rds_ioctl.c revision c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri/*
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * CDDL HEADER START
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri *
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * The contents of this file are subject to the terms of the
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * Common Development and Distribution License (the "License").
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * You may not use this file except in compliance with the License.
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri *
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * or http://www.opensolaris.org/os/licensing.
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * See the License for the specific language governing permissions
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * and limitations under the License.
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri *
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * When distributing Covered Code, include this CDDL HEADER in each
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * If applicable, add the following below this CDDL HEADER, with the
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * fields enclosed by brackets "[]" replaced with your own identifying
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * information: Portions Copyright [yyyy] [name of copyright owner]
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri *
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * CDDL HEADER END
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri */
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri/*
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * Use is subject to license terms.
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri */
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#pragma ident "%Z%%M% %I% %E% SMI"
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#define AF_INET_OFFLOAD 30
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/sockio.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/stream.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/errno.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/cmn_err.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/strsun.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <inet/common.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <net/if.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <inet/mi.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/t_kuser.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/stropts.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/pathname.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/kstr.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/timod.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/ib/clients/rds/rds.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#include <sys/ib/clients/rds/rds_transport.h>
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiristatic sin_t sin_null; /* Zero address for quick clears */
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#define isdigit(ch) ((ch) >= '0' && (ch) <= '9')
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri#define isalpha(ch) (((ch) >= 'a' && (ch) <= 'z') || \
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ((ch) >= 'A' && (ch) <= 'Z'))
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri/*
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * Just pass the ioctl to IP and the result to the caller.
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri */
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiriint
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirirds_do_ip_ioctl(int cmd, int len, caddr_t arg)
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri{
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri vnode_t *kvp, *vp;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri TIUSER *tiptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct strioctl iocb;
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri k_sigset_t smask;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int err = 0;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri &kvp) == 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (t_kopen((file_t *)NULL, kvp->v_rdev, FREAD|FWRITE,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri &tiptr, CRED()) == 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri vp = tiptr->fp->f_vnode;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri } else {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri VN_RELE(kvp);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return (EPROTO);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri } else {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return (EPROTO);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri iocb.ic_cmd = cmd;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri iocb.ic_timout = 0;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri iocb.ic_len = len;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri iocb.ic_dp = arg;
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri sigintr(&smask, 0);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = kstr_ioctl(vp, I_STR, (intptr_t)&iocb);
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri sigunintr(&smask);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (void) t_kclose(tiptr, 0);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri VN_RELE(kvp);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return (err);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri}
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiristatic int
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirirds_dl_info(ldi_handle_t lh, dl_info_ack_t *info)
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri{
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri dl_info_req_t *info_req;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri union DL_primitives *dl_prim;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mblk_t *mp;
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri k_sigset_t smask;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int error;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if ((mp = allocb(sizeof (dl_info_req_t), BPRI_MED)) == NULL) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return (ENOMEM);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mp->b_datap->db_type = M_PROTO;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri info_req = (dl_info_req_t *)(uintptr_t)mp->b_wptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mp->b_wptr += sizeof (dl_info_req_t);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri info_req->dl_primitive = DL_INFO_REQ;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri sigintr(&smask, 0);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if ((error = ldi_putmsg(lh, mp)) != 0) {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri sigunintr(&smask);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return (error);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if ((error = ldi_getmsg(lh, &mp, (timestruc_t *)NULL)) != 0) {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri sigunintr(&smask);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return (error);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri sigunintr(&smask);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri dl_prim = (union DL_primitives *)(uintptr_t)mp->b_rptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri switch (dl_prim->dl_primitive) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case DL_INFO_ACK:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (((uintptr_t)mp->b_wptr - (uintptr_t)mp->b_rptr) <
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sizeof (dl_info_ack_t)) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri error = -1;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri } else {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri *info = *(dl_info_ack_t *)(uintptr_t)mp->b_rptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri error = 0;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri default:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri error = -1;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri freemsg(mp);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return (error);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri}
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri/*
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri * Return 0 if the interface is IB.
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri * Return error (>0) if any error is encountered during processing.
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri * Return -1 if the interface is not IB and no error.
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri */
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiristatic int
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirirds_is_ib_interface(char *name)
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri{
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri char dev_path[MAXPATHLEN];
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ldi_handle_t lh;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri dl_info_ack_t info;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int ret = 0;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int i = 0;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (void) strcpy(dev_path, "/dev/");
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri /*
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * ibd devices are only style 2 devices
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * so we will open only style 2 devices
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * by ignoring the ppa
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri */
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri while (isalpha(name[i])) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri i++;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (i == 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri /*
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * null name.
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri */
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri return (-1);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (strncmp("lo", name, i) == 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri /*
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri * loopback interface is considered RDS capable
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri */
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri return (0);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (void) strncat((dev_path + sizeof ("/dev/") -1), name, i);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ret = ldi_open_by_name(dev_path, FREAD|FWRITE, kcred, &lh, rds_li);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (ret != 0) {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri return (ret);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ret = rds_dl_info(lh, &info);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (void) ldi_close(lh, FREAD|FWRITE, kcred);
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri if (ret != 0) {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri return (ret);
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri if (info.dl_mac_type != DL_IB &&
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri !rds_transport_ops->rds_transport_if_lookup_by_name(name)) {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri return (-1);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri return (0);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri}
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirivoid
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirirds_ioctl_copyin_done(queue_t *q, mblk_t *mp)
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri{
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri char *addr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mblk_t *mp1;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int err = 0;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct iocblk *iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (!(mp1 = mp->b_cont) || !(mp1 = mp1->b_cont)) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = EPROTO;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri goto done;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri addr = (char *)mp1->b_rptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri switch (iocp->ioc_cmd) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFNUM: {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri /* Get number of interfaces. */
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct ifconf kifc;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct ifreq *ifr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int num_ifs;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int n;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = rds_do_ip_ioctl(iocp->ioc_cmd, sizeof (int),
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (char *)&num_ifs);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (err != 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kifc.ifc_len = num_ifs * sizeof (struct ifreq);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kifc.ifc_buf = kmem_zalloc(kifc.ifc_len, KM_SLEEP);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = rds_do_ip_ioctl(SIOCGIFCONF,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sizeof (struct ifconf), (caddr_t)&kifc);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (err != 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kmem_free(kifc.ifc_buf, kifc.ifc_len);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ifr = kifc.ifc_req;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri n = num_ifs;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri for (num_ifs = 0; n > 0; ifr++) {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri err = rds_is_ib_interface(ifr->ifr_name);
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri if (err == 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri num_ifs++;
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri } else if (err > 0) {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri num_ifs = 0;
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri break;
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri } else {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri err = 0;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri n--;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri *((int *)(uintptr_t)addr) = num_ifs;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kmem_free(kifc.ifc_buf, kifc.ifc_len);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case O_SIOCGIFCONF:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFCONF: {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri STRUCT_HANDLE(ifconf, ifc);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri caddr_t ubuf_addr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int ubuf_size;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct ifconf kifc;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct ifreq *ifr, *ptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int num_ifs;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri STRUCT_SET_HANDLE(ifc, iocp->ioc_flag,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (struct ifconf *)(uintptr_t)addr);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ubuf_size = STRUCT_FGET(ifc, ifc_len);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ubuf_addr = STRUCT_FGETP(ifc, ifc_buf);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = rds_do_ip_ioctl(SIOCGIFNUM, sizeof (int),
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (char *)&num_ifs);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (err != 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kifc.ifc_len = num_ifs * sizeof (struct ifreq);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kifc.ifc_buf = kmem_zalloc(kifc.ifc_len, KM_SLEEP);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = rds_do_ip_ioctl(iocp->ioc_cmd,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sizeof (struct ifconf), (caddr_t)&kifc);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (err != 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kmem_free(kifc.ifc_buf, kifc.ifc_len);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mp1 = mi_copyout_alloc(q, mp, ubuf_addr, ubuf_size, B_FALSE);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (mp1 == NULL) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = ENOMEM;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kmem_free(kifc.ifc_buf, ubuf_size);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ifr = kifc.ifc_req;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ptr = (struct ifreq *)(uintptr_t)mp1->b_rptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri for (; num_ifs > 0 &&
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (int)((uintptr_t)mp1->b_wptr - (uintptr_t)mp1->b_rptr) <
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ubuf_size; num_ifs--, ifr++) {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri err = rds_is_ib_interface(ifr->ifr_name);
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri if (err == 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ifr->ifr_addr.sa_family = AF_INET_OFFLOAD;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri bcopy((caddr_t)ifr, ptr, sizeof (struct ifreq));
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ptr++;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mp1->b_wptr = (uchar_t *)ptr;
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri } else if (err > 0) {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri break;
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri } else {
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri err = 0;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri STRUCT_FSET(ifc, ifc_len, (int)((uintptr_t)mp1->b_wptr -
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (uintptr_t)mp1->b_rptr));
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kmem_free(kifc.ifc_buf, kifc.ifc_len);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFMTU:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = rds_do_ip_ioctl(iocp->ioc_cmd,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sizeof (struct ifreq), addr);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFFLAGS:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = rds_do_ip_ioctl(iocp->ioc_cmd,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sizeof (struct ifreq), addr);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case TI_GETMYNAME: {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri rds_t *rds;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri STRUCT_HANDLE(strbuf, sb);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ipaddr_t v4addr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri uint16_t port;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int addrlen;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sin_t *sin;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri STRUCT_SET_HANDLE(sb,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ((struct iocblk *)(uintptr_t)mp->b_rptr)->ioc_flag,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (void *)(uintptr_t)addr);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri rds = (rds_t *)q->q_ptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ASSERT(rds->rds_family == AF_INET_OFFLOAD);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri addrlen = sizeof (sin_t);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri v4addr = rds->rds_src;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri port = rds->rds_port;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mp1 = mi_copyout_alloc(q, mp, STRUCT_FGETP(sb, buf), addrlen,
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri B_TRUE);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (mp1 == NULL)
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri STRUCT_FSET(sb, len, (int)sizeof (sin_t));
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sin = (sin_t *)(uintptr_t)mp1->b_rptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mp1->b_wptr = (uchar_t *)&sin[1];
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri *sin = sin_null;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sin->sin_family = AF_INET_OFFLOAD;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sin->sin_addr.s_addr = v4addr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sin->sin_port = port;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri default:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri err = EOPNOTSUPP;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (err == 0) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mi_copyout(q, mp);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiridone:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mi_copy_done(q, mp, err);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri}
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirivoid
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirirds_ioctl_copyin_setup(queue_t *q, mblk_t *mp)
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri{
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct iocblk *iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int copyin_size;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (mp->b_cont == NULL) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri iocp->ioc_error = EINVAL;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mp->b_datap->db_type = M_IOCNAK;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri iocp->ioc_count = 0;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri qreply(q, mp);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri switch (iocp->ioc_cmd) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case O_SIOCGIFCONF:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFCONF:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (iocp->ioc_count == TRANSPARENT)
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri copyin_size = SIZEOF_STRUCT(ifconf, iocp->ioc_flag);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri else
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri copyin_size = iocp->ioc_count;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFNUM:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri copyin_size = sizeof (int);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFFLAGS:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFMTU:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri copyin_size = sizeof (struct ifreq);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case TI_GETMYNAME:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri copyin_size = SIZEOF_STRUCT(strbuf, iocp->ioc_flag);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri mi_copyin(q, mp, NULL, copyin_size);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri}
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirivoid
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirirds_ioctl(queue_t *q, mblk_t *mp)
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri{
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct iocblk *iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri switch (iocp->ioc_cmd) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case O_SIOCGIFCONF:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFCONF:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFNUM:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFMTU:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case SIOCGIFFLAGS:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri case TI_GETMYNAME:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri rds_ioctl_copyin_setup(q, mp);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri default:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri cmn_err(CE_CONT, "rds_wput unsupported IOCTL \n");
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri miocnak(q, mp, 0, ENOTSUP);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri}
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiriboolean_t
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagirirds_verify_bind_address(ipaddr_t addr)
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri{
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri int numifs;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct ifconf kifc;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct ifreq *ifr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri boolean_t ret = B_FALSE;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (rds_do_ip_ioctl(SIOCGIFNUM, sizeof (int), (caddr_t)&numifs)) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return (ret);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kifc.ifc_len = numifs * sizeof (struct ifreq);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kifc.ifc_buf = kmem_zalloc(kifc.ifc_len, KM_SLEEP);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if (rds_do_ip_ioctl(SIOCGIFCONF, sizeof (struct ifconf),
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri (caddr_t)&kifc)) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri goto done;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ifr = kifc.ifc_req;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri for (numifs = kifc.ifc_len / sizeof (struct ifreq);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri numifs > 0; numifs--, ifr++) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri struct sockaddr_in *sin;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri sin = (struct sockaddr_in *)(uintptr_t)&ifr->ifr_addr;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri if ((sin->sin_addr.s_addr == addr) &&
c1f8b08e52d9b30bd55daeac694e3a7f50d3cd21agiri (rds_is_ib_interface(ifr->ifr_name) == 0)) {
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri ret = B_TRUE;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri break;
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri }
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiridone:
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri kmem_free(kifc.ifc_buf, kifc.ifc_len);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri return (ret);
b86efd96f8acd85ddaa930a2f0c1d664237e4aafagiri}