1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * CDDL HEADER START
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * The contents of this file are subject to the terms of the
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Common Development and Distribution License (the "License").
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * You may not use this file except in compliance with the License.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * or http://www.opensolaris.org/os/licensing.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * See the License for the specific language governing permissions
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * and limitations under the License.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * When distributing Covered Code, include this CDDL HEADER in each
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * If applicable, add the following below this CDDL HEADER, with the
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * fields enclosed by brackets "[]" replaced with your own identifying
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * information: Portions Copyright [yyyy] [name of copyright owner]
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * CDDL HEADER END
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Use is subject to license terms.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich/*
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich * Copyright (c) 2012, Joyent, Inc. All rights reserved.
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich */
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <sys/types.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <sys/stat.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <sys/socket.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <sys/mman.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <sys/varargs.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <sys/vlan.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <errno.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <ctype.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <fcntl.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <unistd.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <stdio.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <stdlib.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <string.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <netinet/in.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <arpa/inet.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <net/if.h> /* LIFNAMSIZ */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <netinet/vrrp.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <libdladm.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <libdlvnic.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <libdlvlan.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <libdllink.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <libintl.h>
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou#include <libscf.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou#include <libvrrpadm.h>
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou#define VRRP_SERVICE "network/vrrp:default"
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoutypedef vrrp_err_t vrrp_cmd_func_t(int, void *);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhoustatic boolean_t
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhouvrrp_svc_isonline(char *svc_name)
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou{
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou char *s;
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou boolean_t isonline = B_FALSE;
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if ((s = smf_get_state(svc_name)) != NULL) {
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (strcmp(s, SCF_STATE_STRING_ONLINE) == 0)
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou isonline = B_TRUE;
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou free(s);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (isonline);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou}
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou#define MAX_WAIT_TIME 15
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhoustatic vrrp_err_t
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhouvrrp_enable_service()
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou{
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou int i;
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (vrrp_svc_isonline(VRRP_SERVICE))
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_SUCCESS);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (smf_enable_instance(VRRP_SERVICE, 0) == -1) {
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (scf_error() == SCF_ERROR_PERMISSION_DENIED)
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_EPERM);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou else
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ENOSVC);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * Wait up to MAX_WAIT_TIME seconds for the VRRP service being brought
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * up online
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou for (i = 0; i < MAX_WAIT_TIME; i++) {
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (vrrp_svc_isonline(VRRP_SERVICE))
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou break;
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou (void) sleep(1);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (i == MAX_WAIT_TIME)
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ENOSVC);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_SUCCESS);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou}
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou/*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * Disable the VRRP service if there is no VRRP router left.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhoustatic void
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhouvrrp_disable_service_when_no_router()
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou{
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou uint32_t cnt = 0;
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * Get the number of the existing routers. If there is no routers
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * left, disable the service.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (vrrp_list(NULL, VRRP_VRID_NONE, NULL, AF_UNSPEC, &cnt,
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou NULL) == VRRP_SUCCESS && cnt == 0) {
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou (void) smf_disable_instance(VRRP_SERVICE, 0);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou}
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoustatic vrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_cmd_request(void *cmd, size_t csize, vrrp_cmd_func_t func, void *arg)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou struct sockaddr_un to;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou int sock, flags;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou size_t len, cur_size = 0;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_ret_t ret;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_err_t err;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ESYS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Set it to be non-blocking.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou flags = fcntl(sock, F_GETFL, 0);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) fcntl(sock, F_SETFL, (flags | O_NONBLOCK));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) memset(&to, 0, sizeof (to));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou to.sun_family = AF_UNIX;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) strlcpy(to.sun_path, VRRPD_SOCKET, sizeof (to.sun_path));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Connect to vrrpd
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (connect(sock, (const struct sockaddr *)&to, sizeof (to)) < 0) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) close(sock);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ENOSVC);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Send the request
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou while (cur_size < csize) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou len = write(sock, (char *)cmd + cur_size, csize - cur_size);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (len == (size_t)-1 && errno == EAGAIN) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou } else if (len > 0) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cur_size += len;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) close(sock);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ENOSVC);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Expect the ack, first get the error code.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cur_size = 0;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou while (cur_size < sizeof (vrrp_err_t)) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou len = read(sock, (char *)&ret + cur_size,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou sizeof (vrrp_err_t) - cur_size);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (len == (size_t)-1 && errno == EAGAIN) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou } else if (len > 0) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cur_size += len;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) close(sock);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ESYS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if ((err = ret.vr_err) != VRRP_SUCCESS)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou goto done;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * The specific callback gets the rest of the information.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (func != NULL)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou err = func(sock, arg);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoudone:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) close(sock);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (err);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * public APIs
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouconst char *
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err2str(vrrp_err_t err)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou switch (err) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_SUCCESS:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "success"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_ENOMEM:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "not enough memory"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EINVALVRNAME:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "invalid router name"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_ENOPRIM:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "no primary IP"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EEXIST:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "already exists"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_ENOVIRT:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "no virtual IPs"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EIPADM:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "ip configuration failure"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EDLADM:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "data-link configuration "
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou "failure"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EDB:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "configuration update error"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EBADSTATE:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "invalid state"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EVREXIST:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "VRRP router already exists"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_ETOOSMALL:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "not enough space"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EINSTEXIST:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "router name already exists"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_ENOTFOUND:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "VRRP router not found"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EINVALADDR:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "invalid IP address"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EINVALAF:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "invalid IP address family"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EINVALLINK:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "invalid data-link"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EPERM:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "permission denied"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_ESYS:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "system error"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EAGAIN:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "try again"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EALREADY:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "operation already in progress"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_ENOVNIC:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "VRRP VNIC has not been "
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou "created"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_ENOLINK:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "the data-link does not exist"));
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou case VRRP_ENOSVC:
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (dgettext(TEXT_DOMAIN, "the VRRP service cannot "
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou "be enabled"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_EINVAL:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou default:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "invalid argument"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouconst char *
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_state2str(vrrp_state_t state)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou switch (state) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_STATE_NONE:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "NONE"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_STATE_INIT:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "INIT"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_STATE_MASTER:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "MASTER"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VRRP_STATE_BACKUP:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "BACKUP"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou default:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (dgettext(TEXT_DOMAIN, "INVALID"));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_open(vrrp_handle_t *vh)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou dladm_handle_t dh;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (dladm_open(&dh) != DLADM_STATUS_OK)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EDLADM);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if ((*vh = malloc(sizeof (struct vrrp_handle))) == NULL) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou dladm_close(dh);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_ENOMEM);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (*vh)->vh_dh = dh;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_SUCCESS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvoid
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_close(vrrp_handle_t vh)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (vh != NULL) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou dladm_close(vh->vh_dh);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou free(vh);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouboolean_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_valid_name(const char *name)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou const char *c;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * The legal characters in a valid router name are:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * alphanumeric (a-z, A-Z, 0-9), underscore ('_'), and '.'.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou for (c = name; *c != '\0'; c++) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if ((isalnum(*c) == 0) && (*c != '_'))
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (B_FALSE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (B_TRUE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*ARGSUSED*/
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_create(vrrp_handle_t vh, vrrp_vr_conf_t *conf)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_cmd_create_t cmd;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_err_t err;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhouagain:
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * Enable the VRRP service if it is not already enabled.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if ((err = vrrp_enable_service()) != VRRP_SUCCESS)
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (err);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcc_cmd = VRRP_CMD_CREATE;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) memcpy(&cmd.vcc_conf, conf, sizeof (vrrp_vr_conf_t));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou err = vrrp_cmd_request(&cmd, sizeof (cmd), NULL, NULL);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (err == VRRP_ENOSVC) {
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * This may be due to another process is deleting the last
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * router and disabled the VRRP service, try again.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou goto again;
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou } else if (err != VRRP_SUCCESS) {
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * If router cannot be created, check if the VRRP service
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * should be disabled, and disable if needed.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou vrrp_disable_service_when_no_router();
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (err);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*ARGSUSED*/
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_delete(vrrp_handle_t vh, const char *vn)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_cmd_delete_t cmd;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_err_t err;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * If the VRRP service is not enabled, we assume there is no router
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * configured.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (!vrrp_svc_isonline(VRRP_SERVICE))
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ENOTFOUND);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcd_cmd = VRRP_CMD_DELETE;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (strlcpy(cmd.vcd_name, vn, VRRP_NAME_MAX) >= VRRP_NAME_MAX)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou err = vrrp_cmd_request(&cmd, sizeof (cmd), NULL, NULL);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (err == VRRP_SUCCESS)
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou vrrp_disable_service_when_no_router();
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (err);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*ARGSUSED*/
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_enable(vrrp_handle_t vh, const char *vn)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_cmd_enable_t cmd;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_err_t err;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * If the VRRP service is not enabled, we assume there is no router
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * configured.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (!vrrp_svc_isonline(VRRP_SERVICE))
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ENOTFOUND);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcs_cmd = VRRP_CMD_ENABLE;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (strlcpy(cmd.vcs_name, vn, VRRP_NAME_MAX) >= VRRP_NAME_MAX)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou err = vrrp_cmd_request(&cmd, sizeof (cmd), NULL, NULL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (err);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*ARGSUSED*/
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_disable(vrrp_handle_t vh, const char *vn)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_cmd_disable_t cmd;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_err_t err;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * If the VRRP service is not enabled, we assume there is no router
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * configured.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (!vrrp_svc_isonline(VRRP_SERVICE))
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ENOTFOUND);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcx_cmd = VRRP_CMD_DISABLE;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (strlcpy(cmd.vcx_name, vn, VRRP_NAME_MAX) >= VRRP_NAME_MAX)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou err = vrrp_cmd_request(&cmd, sizeof (cmd), NULL, NULL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (err);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*ARGSUSED*/
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_modify(vrrp_handle_t vh, vrrp_vr_conf_t *conf, uint32_t mask)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_cmd_modify_t cmd;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_err_t err;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * If the VRRP service is not enabled, we assume there is no router
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * configured.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (!vrrp_svc_isonline(VRRP_SERVICE))
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ENOTFOUND);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcm_cmd = VRRP_CMD_MODIFY;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcm_mask = mask;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) memcpy(&cmd.vcm_conf, conf, sizeof (vrrp_vr_conf_t));
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou err = vrrp_cmd_request(&cmd, sizeof (cmd), NULL, NULL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (err);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoutypedef struct vrrp_cmd_list_arg {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint32_t *vfl_cnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou char *vfl_names;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou} vrrp_cmd_list_arg_t;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoustatic vrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_list_func(int sock, void *arg)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_cmd_list_arg_t *list_arg = arg;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint32_t in_cnt = *(list_arg->vfl_cnt);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint32_t out_cnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_ret_list_t ret;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou size_t len, cur_size = 0;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Get the rest of vrrp_ret_list_t besides the error code.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cur_size = sizeof (vrrp_err_t);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou while (cur_size < sizeof (vrrp_ret_list_t)) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou len = read(sock, (char *)&ret + cur_size,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou sizeof (vrrp_ret_list_t) - cur_size);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (len == (size_t)-1 && errno == EAGAIN) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou } else if (len > 0) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cur_size += len;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ESYS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *(list_arg->vfl_cnt) = out_cnt = ret.vrl_cnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou out_cnt = (in_cnt <= out_cnt) ? in_cnt : out_cnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cur_size = 0;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou while (cur_size < VRRP_NAME_MAX * out_cnt) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou len = read(sock, (char *)list_arg->vfl_names + cur_size,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou VRRP_NAME_MAX * out_cnt - cur_size);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (len == (size_t)-1 && errno == EAGAIN) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou } else if (len > 0) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cur_size += len;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ESYS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_SUCCESS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Looks up the vrrp instances that matches the given variable.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * If the given cnt is 0, names should be set to NULL. In this case, only
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * the count of the matched instances is returned.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * If the given cnt is non-zero, caller must allocate "names" whose size
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * is (cnt * VRRP_NAME_MAX).
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Return value: the current count of matched instances, and names will be
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * points to the list of the current vrrp instances names. Note that
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * only MIN(in_cnt, out_cnt) number of names will be returned.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*ARGSUSED*/
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_list(vrrp_handle_t vh, vrid_t vrid, const char *intf, int af,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint32_t *cnt, char *names)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_cmd_list_t cmd;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_err_t err;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_cmd_list_arg_t list_arg;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if ((cnt == NULL) || (*cnt != 0 && names == NULL))
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcl_ifname[0] = '\0';
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (intf != NULL && (strlcpy(cmd.vcl_ifname, intf,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou LIFNAMSIZ) >= LIFNAMSIZ)) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * If the service is not online, we assume there is no router
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * configured.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (!vrrp_svc_isonline(VRRP_SERVICE)) {
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou *cnt = 0;
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_SUCCESS);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcl_cmd = VRRP_CMD_LIST;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcl_vrid = vrid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcl_af = af;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou list_arg.vfl_cnt = cnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou list_arg.vfl_names = names;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou err = vrrp_cmd_request(&cmd, sizeof (cmd), vrrp_list_func, &list_arg);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (err);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoustatic vrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_query_func(int sock, void *arg)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_queryinfo_t *qinfo = arg;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou size_t len, cur_size = 0, total;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint32_t in_cnt = qinfo->show_va.va_vipcnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint32_t out_cnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Expect the ack, first get the vrrp_ret_t.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou total = sizeof (vrrp_queryinfo_t);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou while (cur_size < total) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou len = read(sock, (char *)qinfo + cur_size, total - cur_size);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (len == (size_t)-1 && errno == EAGAIN) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou } else if (len > 0) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cur_size += len;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ESYS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou out_cnt = qinfo->show_va.va_vipcnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Even if there is no IP virtual IP address, there is always
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * space in the vrrp_queryinfo_t structure for one virtual
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * IP address.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou out_cnt = (out_cnt == 0) ? 1 : out_cnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou out_cnt = (in_cnt < out_cnt ? in_cnt : out_cnt) - 1;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou total += out_cnt * sizeof (vrrp_addr_t);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou while (cur_size < total) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou len = read(sock, (char *)qinfo + cur_size, total - cur_size);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (len == (size_t)-1 && errno == EAGAIN) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou } else if (len > 0) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cur_size += len;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou continue;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ESYS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_SUCCESS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * *vqp is allocated inside this function and must be freed by the caller.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*ARGSUSED*/
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_query(vrrp_handle_t vh, const char *vn, vrrp_queryinfo_t **vqp)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_cmd_query_t cmd;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_queryinfo_t *qinfo;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_err_t err;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou size_t size;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint32_t vipcnt = 1;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (strlcpy(cmd.vcq_name, vn, VRRP_NAME_MAX) >= VRRP_NAME_MAX)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou /*
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * If the service is not online, we assume there is no router
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou * configured.
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou */
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou if (!vrrp_svc_isonline(VRRP_SERVICE))
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou return (VRRP_ENOTFOUND);
c5e0ece05310eec3c585344bcff875855f3f507aCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou cmd.vcq_cmd = VRRP_CMD_QUERY;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Allocate enough room for virtual IPs.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouagain:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou size = sizeof (vrrp_queryinfo_t);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou size += (vipcnt == 0) ? 0 : (vipcnt - 1) * sizeof (vrrp_addr_t);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if ((qinfo = malloc(size)) == NULL) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou err = VRRP_ENOMEM;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou goto done;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou qinfo->show_va.va_vipcnt = vipcnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou err = vrrp_cmd_request(&cmd, sizeof (cmd), vrrp_query_func, qinfo);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (err != VRRP_SUCCESS) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou free(qinfo);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou goto done;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * If the returned number of virtual IPs is greater than we expected,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * allocate more room and try again.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (qinfo->show_va.va_vipcnt > vipcnt) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vipcnt = qinfo->show_va.va_vipcnt;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou free(qinfo);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou goto again;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *vqp = qinfo;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoudone:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (err);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoustruct lookup_vnic_arg {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrid_t lva_vrid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou datalink_id_t lva_linkid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou int lva_af;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint16_t lva_vid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_handle_t lva_vh;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou char lva_vnic[MAXLINKNAMELEN];
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou};
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Is this a special VNIC interface created for VRRP? If so, return
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * the linkid the VNIC was created on, the VRRP ID and address family.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouboolean_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_is_vrrp_vnic(vrrp_handle_t vh, datalink_id_t vnicid,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou datalink_id_t *linkidp, uint16_t *vidp, vrid_t *vridp, int *afp)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou dladm_vnic_attr_t vattr;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (dladm_vnic_info(vh->vh_dh, vnicid, &vattr, DLADM_OPT_ACTIVE) !=
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou DLADM_STATUS_OK) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (B_FALSE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *vridp = vattr.va_vrid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *vidp = vattr.va_vid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *afp = vattr.va_af;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *linkidp = vattr.va_link_id;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (vattr.va_vrid != VRRP_VRID_NONE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoustatic int
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhoulookup_vnic(dladm_handle_t dh, datalink_id_t vnicid, void *arg)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrid_t vrid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint16_t vid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou datalink_id_t linkid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou int af;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou struct lookup_vnic_arg *lva = arg;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (vrrp_is_vrrp_vnic(lva->lva_vh, vnicid, &linkid, &vid, &vrid,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou &af) && lva->lva_vrid == vrid && lva->lva_linkid == linkid &&
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich (lva->lva_vid == VLAN_ID_NONE || lva->lva_vid == vid) &&
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich lva->lva_af == af) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (dladm_datalink_id2info(dh, vnicid, NULL, NULL, NULL,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou lva->lva_vnic, sizeof (lva->lva_vnic)) == DLADM_STATUS_OK) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (DLADM_WALK_TERMINATE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (DLADM_WALK_CONTINUE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou/*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Given the primary link name, find the assoicated VRRP vnic name, if
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * the vnic does not exist yet, return the linkid, vid of the primary link.
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_err_t
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhouvrrp_get_vnicname(vrrp_handle_t vh, vrid_t vrid, int af, char *link,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou datalink_id_t *linkidp, uint16_t *vidp, char *vnic, size_t len)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou{
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou datalink_id_t linkid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint32_t flags;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint16_t vid = VLAN_ID_NONE;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou datalink_class_t class;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou dladm_vlan_attr_t vlan_attr;
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich dladm_vnic_attr_t vnic_attr;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou struct lookup_vnic_arg lva;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou uint32_t media;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if ((strlen(link) == 0) || dladm_name2info(vh->vh_dh,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou link, &linkid, &flags, &class, &media) !=
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou DLADM_STATUS_OK || !(flags & DLADM_OPT_ACTIVE)) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (class == DATALINK_CLASS_VLAN) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (dladm_vlan_info(vh->vh_dh, linkid, &vlan_attr,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou DLADM_OPT_ACTIVE) != DLADM_STATUS_OK) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou linkid = vlan_attr.dv_linkid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vid = vlan_attr.dv_vid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if ((dladm_datalink_id2info(vh->vh_dh, linkid, NULL,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou &class, &media, NULL, 0)) != DLADM_STATUS_OK) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich if (class == DATALINK_CLASS_VNIC) {
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich if (dladm_vnic_info(vh->vh_dh, linkid, &vnic_attr,
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich DLADM_OPT_ACTIVE) != DLADM_STATUS_OK) {
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich return (VRRP_EINVAL);
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich }
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich linkid = vnic_attr.va_link_id;
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich vid = vnic_attr.va_vid;
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich }
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich * Only VRRP over vnics, aggrs and physical ethernet links is supported
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich if ((class != DATALINK_CLASS_PHYS && class != DATALINK_CLASS_AGGR &&
2954adb080121c02025bb94537c313e6f51c9fd7Rob Gulewich class != DATALINK_CLASS_VNIC) || media != DL_ETHER) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_EINVAL);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (linkidp != NULL)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *linkidp = linkid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (vidp != NULL)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou *vidp = vid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou /*
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou * Find the assoicated vnic with the given vrid/vid/af/linkid
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou */
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou lva.lva_vrid = vrid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou lva.lva_vid = vid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou lva.lva_af = af;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou lva.lva_linkid = linkid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou lva.lva_vh = vh;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou lva.lva_vnic[0] = '\0';
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) dladm_walk_datalink_id(lookup_vnic, vh->vh_dh, &lva,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou DATALINK_CLASS_VNIC, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (strlen(lva.lva_vnic) != 0) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou (void) strlcpy(vnic, lva.lva_vnic, len);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_SUCCESS);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (VRRP_ENOVNIC);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou}