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  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 #include <sys/types.h>
  26 #include <sys/ddi.h>
  27 #include <sys/sunddi.h>
  28 #include <sys/strsubr.h>
  29 #include <sys/socket.h>
  30 #include <net/if_arp.h>
  31 #include <net/if_types.h>
  32 #include <sys/sockio.h>
  33 #include <sys/pathname.h>
  34 
  35 #include <sys/ib/mgt/ibcm/ibcm_arp.h>
  36 
  37 #include <sys/kstr.h>
  38 #include <sys/t_kuser.h>
  39 
  40 #include <sys/dls.h>
  41 
  42 extern char cmlog[];
  43 
  44 extern int ibcm_resolver_pr_lookup(ibcm_arp_streams_t *ib_s,
  45     ibt_ip_addr_t *dst_addr, ibt_ip_addr_t *src_addr, zoneid_t myzoneid);
  46 extern void ibcm_arp_delete_prwqn(ibcm_arp_prwqn_t *wqnp);
  47 
  48 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibt_ip_addr_s))
  49 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_arp_ip_t))
  50 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_arp_ibd_insts_t))
  51 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_arp_prwqn_t))
  52 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", sockaddr_in))
  53 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", sockaddr_in6))
  54 
  55 int ibcm_printip = 0;
  56 
  57 /*
  58  * Function:
  59  *      ibcm_ip_print
  60  * Input:
  61  *      label           Arbitrary qualifying string
  62  *      ipa             Pointer to IP Address to print
  63  */
  64 void
  65 ibcm_ip_print(char *label, ibt_ip_addr_t *ipaddr)
  66 {
  67         char    buf[INET6_ADDRSTRLEN];
  68 
  69         if (ipaddr->family == AF_INET) {
  70                 IBTF_DPRINTF_L2(cmlog, "%s: %s", label,
  71                     inet_ntop(AF_INET, &ipaddr->un.ip4addr, buf, sizeof (buf)));
  72         } else if (ipaddr->family == AF_INET6) {
  73                 IBTF_DPRINTF_L2(cmlog, "%s: %s", label, inet_ntop(AF_INET6,
  74                     &ipaddr->un.ip6addr, buf, sizeof (buf)));
  75         } else {
  76                 IBTF_DPRINTF_L2(cmlog, "%s: IP ADDR NOT SPECIFIED ", label);
  77         }
  78 }
  79 
  80 
  81 ibt_status_t
  82 ibcm_arp_get_ibaddr(zoneid_t myzoneid, ibt_ip_addr_t srcaddr,
  83     ibt_ip_addr_t destaddr, ib_gid_t *sgid, ib_gid_t *dgid,
  84     ibt_ip_addr_t *saddrp)
  85 {
  86         ibcm_arp_streams_t      *ib_s;
  87         ibcm_arp_prwqn_t        *wqnp;
  88         int                     ret = 0;
  89         int                     len;
  90 
  91         IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibaddr(%d, %p, %p, %p, %p, %p)",
  92             myzoneid, srcaddr, destaddr, sgid, dgid, saddrp);
  93 
  94         ib_s = (ibcm_arp_streams_t *)kmem_zalloc(sizeof (ibcm_arp_streams_t),
  95             KM_SLEEP);
  96 
  97         mutex_init(&ib_s->lock, NULL, MUTEX_DEFAULT, NULL);
  98         cv_init(&ib_s->cv, NULL, CV_DRIVER, NULL);
  99 
 100         mutex_enter(&ib_s->lock);
 101         ib_s->done = B_FALSE;
 102         mutex_exit(&ib_s->lock);
 103 
 104         ret = ibcm_resolver_pr_lookup(ib_s, &destaddr, &srcaddr, myzoneid);
 105 
 106         IBTF_DPRINTF_L3(cmlog, "ibcm_arp_get_ibaddr: ibcm_resolver_pr_lookup "
 107             "returned: %d", ret);
 108         if (ret == 0) {
 109                 mutex_enter(&ib_s->lock);
 110                 while (ib_s->done != B_TRUE)
 111                         cv_wait(&ib_s->cv, &ib_s->lock);
 112                 mutex_exit(&ib_s->lock);
 113         }
 114 
 115         mutex_enter(&ib_s->lock);
 116         wqnp = ib_s->wqnp;
 117         if (ib_s->status == 0) {
 118                 if (sgid)
 119                         *sgid = wqnp->sgid;
 120                 if (dgid)
 121                         *dgid = wqnp->dgid;
 122                 /*
 123                  * If the user supplied a address, then verify we got
 124                  * for the same address.
 125                  */
 126                 if (wqnp->usrc_addr.family && sgid) {
 127                         len = (wqnp->usrc_addr.family == AF_INET) ?
 128                             IP_ADDR_LEN : sizeof (in6_addr_t);
 129                         if (bcmp(&wqnp->usrc_addr.un,
 130                             &wqnp->src_addr.un, len)) {
 131                                 IBTF_DPRINTF_L3(cmlog, "ibcm_arp_get_ibaddr: "
 132                                     "srcaddr mismatch");
 133 
 134                                 /* Clean-up old data, and reset the done flag */
 135                                 ibcm_arp_delete_prwqn(wqnp);
 136                                 ib_s->done = B_FALSE;
 137                                 mutex_exit(&ib_s->lock);
 138 
 139                                 ret = ibcm_resolver_pr_lookup(ib_s, &srcaddr,
 140                                     &srcaddr, myzoneid);
 141                                 if (ret == 0) {
 142                                         mutex_enter(&ib_s->lock);
 143                                         while (ib_s->done != B_TRUE)
 144                                                 cv_wait(&ib_s->cv, &ib_s->lock);
 145                                         mutex_exit(&ib_s->lock);
 146                                 }
 147                                 mutex_enter(&ib_s->lock);
 148                                 wqnp = ib_s->wqnp;
 149                                 if (ib_s->status == 0) {
 150                                         if (sgid)
 151                                                 *sgid = wqnp->dgid;
 152 
 153                                         if (saddrp)
 154                                                 bcopy(&wqnp->src_addr, saddrp,
 155                                                     sizeof (ibt_ip_addr_t));
 156 
 157                                         IBTF_DPRINTF_L4(cmlog,
 158                                             "ibcm_arp_get_ibaddr: "
 159                                             "SGID: %llX:%llX DGID: %llX:%llX",
 160                                             sgid->gid_prefix, sgid->gid_guid,
 161                                             dgid->gid_prefix, dgid->gid_guid);
 162 
 163                                         ibcm_arp_delete_prwqn(wqnp);
 164                                 } else if (ret == 0) {
 165                                         if (wqnp)
 166                                                 kmem_free(wqnp,
 167                                                     sizeof (ibcm_arp_prwqn_t));
 168                                 }
 169                                 goto arp_ibaddr_done;
 170                         }
 171                 }
 172 
 173                 if (saddrp)
 174                         bcopy(&wqnp->src_addr, saddrp, sizeof (ibt_ip_addr_t));
 175 
 176                 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibaddr: SGID: %llX:%llX"
 177                     " DGID: %llX:%llX", sgid->gid_prefix, sgid->gid_guid,
 178                     dgid->gid_prefix, dgid->gid_guid);
 179 
 180                 ibcm_arp_delete_prwqn(wqnp);
 181         } else if (ret == 0) {
 182                 /*
 183                  * We come here only when lookup has returned empty (failed)
 184                  * via callback routine.
 185                  * i.e. ib_s->status is non-zero, while ret is zero.
 186                  */
 187                 if (wqnp)
 188                         kmem_free(wqnp, sizeof (ibcm_arp_prwqn_t));
 189         }
 190 arp_ibaddr_done:
 191         ret = ib_s->status;
 192         mutex_exit(&ib_s->lock);
 193 
 194 arp_ibaddr_error:
 195 
 196         mutex_destroy(&ib_s->lock);
 197         cv_destroy(&ib_s->cv);
 198         kmem_free(ib_s, sizeof (ibcm_arp_streams_t));
 199 
 200         if (ret)
 201                 return (IBT_FAILURE);
 202         else
 203                 return (IBT_SUCCESS);
 204 }
 205 
 206 void
 207 ibcm_arp_free_ibds(ibcm_arp_ibd_insts_t *ibds)
 208 {
 209         if (ibds->ibcm_arp_ip) {
 210                 kmem_free(ibds->ibcm_arp_ip, ibds->ibcm_arp_ibd_alloc *
 211                     sizeof (ibcm_arp_ip_t));
 212                 ibds->ibcm_arp_ibd_alloc = 0;
 213                 ibds->ibcm_arp_ibd_cnt = 0;
 214                 ibds->ibcm_arp_ip = NULL;
 215         }
 216 }
 217 
 218 static void
 219 ibcm_arp_get_ibd_insts(ibcm_arp_ibd_insts_t *ibds)
 220 {
 221         ibcm_arp_ip_t   *ipp;
 222         ib_gid_t        port_gid;
 223         ibt_part_attr_t *attr_list, *attr;
 224         int             nparts;
 225 
 226         if ((ibt_get_all_part_attr(&attr_list, &nparts) != IBT_SUCCESS) ||
 227             (nparts == 0)) {
 228                 IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_ibd_insts: Failed to "
 229                     "IB Part List - %d", nparts);
 230                 ibds->ibcm_arp_ibd_alloc = 0;
 231                 ibds->ibcm_arp_ibd_cnt = 0;
 232                 ibds->ibcm_arp_ip = NULL;
 233                 return;
 234         }
 235         IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibd_insts: Found %d IB Part List",
 236             nparts);
 237 
 238         ibds->ibcm_arp_ibd_alloc = nparts;
 239         ibds->ibcm_arp_ibd_cnt = 0;
 240         ibds->ibcm_arp_ip = (ibcm_arp_ip_t *)kmem_zalloc(
 241             nparts * sizeof (ibcm_arp_ip_t), KM_SLEEP);
 242 
 243         attr = attr_list;
 244         while (nparts--) {
 245                 if (ibt_get_port_state_byguid(attr->pa_hca_guid,
 246                     attr->pa_port, &port_gid, NULL) == IBT_SUCCESS) {
 247 
 248                         ipp = &ibds->ibcm_arp_ip[ibds->ibcm_arp_ibd_cnt];
 249                         ipp->ip_linkid = attr->pa_plinkid;
 250                         ipp->ip_pkey = attr->pa_pkey;
 251                         ipp->ip_hca_guid = attr->pa_hca_guid;
 252                         ipp->ip_port_gid = port_gid;
 253                         ibds->ibcm_arp_ibd_cnt++;
 254 
 255                         IBTF_DPRINTF_L4(cmlog, "PartAttr: p-linkid %lX, "
 256                             "d-linkid %lX, pkey 0x%lX", ipp->ip_linkid,
 257                             attr->pa_dlinkid, ipp->ip_pkey);
 258                         IBTF_DPRINTF_L4(cmlog, "hca_guid 0x%llX, "
 259                             "port_gid %llX \n attr-port_guid %llX",
 260                             ipp->ip_hca_guid, ipp->ip_port_gid.gid_guid,
 261                             attr->pa_port_guid);
 262                 }
 263                 attr++;
 264         }
 265 
 266         (void) ibt_free_part_attr(attr_list, ibds->ibcm_arp_ibd_alloc);
 267 }
 268 
 269 /*
 270  * Issue an ioctl down to IP.  There are several similar versions of this
 271  * function (e.g., rpcib_do_ip_ioctl()); clearly a utility routine is needed.
 272  */
 273 static int
 274 ibcm_do_ip_ioctl(int cmd, int len, void *arg)
 275 {
 276         vnode_t *kkvp;
 277         TIUSER  *tiptr;
 278         struct  strioctl iocb;
 279         int     err = 0;
 280 
 281         if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP, &kkvp) != 0)
 282                 return (EPROTO);
 283 
 284         if (t_kopen(NULL, kkvp->v_rdev, FREAD|FWRITE, &tiptr, CRED()) != 0) {
 285                 VN_RELE(kkvp);
 286                 return (EPROTO);
 287         }
 288 
 289         iocb.ic_cmd = cmd;
 290         iocb.ic_timout = 0;
 291         iocb.ic_len = len;
 292         iocb.ic_dp = (caddr_t)arg;
 293         err = kstr_ioctl(tiptr->fp->f_vnode, I_STR, (intptr_t)&iocb);
 294         (void) t_kclose(tiptr, 0);
 295         VN_RELE(kkvp);
 296         return (err);
 297 }
 298 
 299 /*
 300  * Issue an SIOCGLIFCONF down to IP and return the result in `lifcp'.
 301  * lifcp->lifc_buf is dynamically allocated to be *bufsizep bytes.
 302  */
 303 static int
 304 ibcm_do_lifconf(struct lifconf *lifcp, uint_t *bufsizep, sa_family_t family_loc)
 305 {
 306         int err;
 307         struct lifnum lifn;
 308 
 309         bzero(&lifn, sizeof (struct lifnum));
 310         lifn.lifn_family = family_loc;
 311         lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
 312 
 313         err = ibcm_do_ip_ioctl(SIOCGLIFNUM, sizeof (struct lifnum), &lifn);
 314         if (err != 0)
 315                 return (err);
 316 
 317         IBTF_DPRINTF_L3(cmlog, "ibcm_do_lifconf: Family %d, lifn_count %d",
 318             family_loc, lifn.lifn_count);
 319         /*
 320          * Pad the interface count to account for additional interfaces that
 321          * may have been configured between the SIOCGLIFNUM and SIOCGLIFCONF.
 322          */
 323         lifn.lifn_count += 4;
 324 
 325         bzero(lifcp, sizeof (struct lifconf));
 326         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lifcp))
 327         lifcp->lifc_family = family_loc;
 328         lifcp->lifc_len = *bufsizep = lifn.lifn_count * sizeof (struct lifreq);
 329         lifcp->lifc_buf = kmem_zalloc(*bufsizep, KM_SLEEP);
 330         lifcp->lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
 331 
 332         err = ibcm_do_ip_ioctl(SIOCGLIFCONF, sizeof (struct lifconf), lifcp);
 333         if (err != 0) {
 334                 kmem_free(lifcp->lifc_buf, *bufsizep);
 335                 return (err);
 336         }
 337         return (0);
 338 }
 339 
 340 static ibcm_arp_ip_t *
 341 ibcm_arp_lookup(ibcm_arp_ibd_insts_t *ibds, char *linkname)
 342 {
 343         datalink_id_t   linkid;
 344         int             i;
 345 
 346         IBTF_DPRINTF_L4(cmlog, "ibcm_arp_lookup: linkname =  %s", linkname);
 347 
 348         /*
 349          * If at first we don't succeed, try again, just in case it is in
 350          * hiding. The first call requires the datalink management daemon
 351          * (the authorative source of information about name to id mapping)
 352          * to be present and answering upcalls, the second does not.
 353          */
 354         if (dls_mgmt_get_linkid(linkname, &linkid) != 0) {
 355                 if (dls_devnet_macname2linkid(linkname, &linkid) != 0) {
 356                         IBTF_DPRINTF_L2(cmlog, "ibcm_arp_lookup: could not "
 357                             "get linkid from linkname (%s)", linkname);
 358                         return (NULL);
 359                 }
 360         }
 361 
 362         for (i = 0; i < ibds->ibcm_arp_ibd_cnt; i++) {
 363                 if (ibds->ibcm_arp_ip[i].ip_linkid == linkid)
 364                         return (&ibds->ibcm_arp_ip[i]);
 365         }
 366 
 367         IBTF_DPRINTF_L2(cmlog, "ibcm_arp_lookup: returning NULL for "
 368             "linkname (%s)", linkname);
 369         return (NULL);
 370 }
 371 
 372 /*
 373  * Fill in `ibds' with IP addresses tied to IFT_IB IP interfaces.  Returns
 374  * B_TRUE if at least one address was filled in.
 375  */
 376 static boolean_t
 377 ibcm_arp_get_ibd_ipaddr(ibcm_arp_ibd_insts_t *ibds, sa_family_t family_loc)
 378 {
 379         int i, nifs, naddr = 0;
 380         uint_t bufsize;
 381         struct lifconf lifc;
 382         struct lifreq *lifrp, lifr_copy;
 383         ibcm_arp_ip_t *ipp;
 384         lifgroupinfo_t  lifgr;
 385         int err;
 386         char    ifname[LIFNAMSIZ + 1];
 387         uint64_t        ifflags = 0;
 388         zoneid_t        ifzoneid;
 389 
 390         if (ibcm_do_lifconf(&lifc, &bufsize, family_loc) != 0)
 391                 return (B_FALSE);
 392 
 393         nifs = lifc.lifc_len / sizeof (struct lifreq);
 394 
 395         IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibd_ipaddr: Family %d, nifs %d",
 396             family_loc, nifs);
 397 
 398         for (lifrp = lifc.lifc_req, i = 0; i < nifs; i++, lifrp++) {
 399 
 400                 if (lifrp->lifr_type != IFT_IB)
 401                         continue;
 402 
 403                 IBTF_DPRINTF_L4(cmlog, "\nInterface# : %d", i);
 404                 IBTF_DPRINTF_L4(cmlog, "lifr_name : %s, lifr_family :%X, "
 405                     "lifr_type : 0x%lX", lifrp->lifr_name,
 406                     lifrp->lifr_addr.ss_family, lifrp->lifr_type);
 407 
 408                 (void) strlcpy(ifname, lifrp->lifr_name, LIFNAMSIZ);
 409 
 410                 /* Get ZoneId. */
 411                 lifr_copy = *lifrp;
 412                 ifzoneid = 0;
 413                 err = ibcm_do_ip_ioctl(SIOCGLIFZONE, sizeof (struct lifreq),
 414                     &lifr_copy);
 415                 if (err != 0) {
 416                         IBTF_DPRINTF_L2(cmlog, "IFZONE ioctl Failed: err = %d",
 417                             err);
 418                 } else  {
 419                         IBTF_DPRINTF_L4(cmlog, "lifr_zoneid     : 0x%X",
 420                             lifr_copy.lifr_zoneid);
 421                         ifzoneid = lifr_copy.lifr_zoneid;
 422                 }
 423 
 424                 /* Get IfIndex. */
 425                 lifr_copy = *lifrp;
 426                 err = ibcm_do_ip_ioctl(SIOCGLIFINDEX, sizeof (struct lifreq),
 427                     &lifr_copy);
 428                 if (err != 0) {
 429                         IBTF_DPRINTF_L2(cmlog, "IFINDEX ioctl Failed: err = %d",
 430                             err);
 431                 } else
 432                         IBTF_DPRINTF_L4(cmlog, "lifr_index      : 0x%X",
 433                             lifr_copy.lifr_index);
 434 
 435                 /* Get Interface flags. */
 436                 lifr_copy = *lifrp;
 437                 err = ibcm_do_ip_ioctl(SIOCGLIFFLAGS, sizeof (struct lifreq),
 438                     &lifr_copy);
 439                 if (err != 0) {
 440                         IBTF_DPRINTF_L2(cmlog, "IFFLAGS ioctl Failed: err = %d",
 441                             err);
 442                 } else  {
 443                         ifflags = lifr_copy.lifr_flags;
 444                         IBTF_DPRINTF_L4(cmlog, "lifr_flags      : 0x%llX",
 445                             ifflags);
 446                 }
 447 
 448                 lifr_copy = *lifrp;
 449                 err = ibcm_do_ip_ioctl(SIOCGLIFGROUPNAME,
 450                     sizeof (struct lifreq), &lifr_copy);
 451                 if (err != 0) {
 452                         IBTF_DPRINTF_L3(cmlog, "IFGroupName ioctl Failed: "
 453                             "err = %d", err);
 454                 }
 455 
 456                 if (lifr_copy.lifr_groupname[0] != '\0') {
 457                         IBTF_DPRINTF_L4(cmlog, "lifr_groupname  : %s",
 458                             lifr_copy.lifr_groupname);
 459                         (void) strlcpy(lifgr.gi_grname,
 460                             lifr_copy.lifr_groupname, LIFGRNAMSIZ);
 461                         err = ibcm_do_ip_ioctl(SIOCGLIFGROUPINFO,
 462                             sizeof (struct lifgroupinfo), &lifgr);
 463                         if (err != 0) {
 464                                 IBTF_DPRINTF_L2(cmlog, "IFGroupINFO ioctl "
 465                                     "Failed: err = %d", err);
 466                         } else {
 467                                 IBTF_DPRINTF_L4(cmlog, "lifgroupinfo details");
 468                                 IBTF_DPRINTF_L4(cmlog, "grname : %s, grifname :"
 469                                     " %s, m4ifname : %s, m6ifname : %s",
 470                                     lifgr.gi_grname, lifgr.gi_grifname,
 471                                     lifgr.gi_m4ifname, lifgr.gi_m6ifname);
 472                                 IBTF_DPRINTF_L4(cmlog, "gi_bcifname  : %s",
 473                                     lifgr.gi_bcifname);
 474                                 IBTF_DPRINTF_L4(cmlog, "gi_v4 %d, gi_v6 %d, "
 475                                     "gi_nv4 %d, gi_nv6 %d, gi_mactype %d",
 476                                     lifgr.gi_v4, lifgr.gi_v6, lifgr.gi_nv4,
 477                                     lifgr.gi_nv6, lifgr.gi_mactype);
 478 
 479                                 (void) strlcpy(ifname, lifgr.gi_bcifname,
 480                                     LIFNAMSIZ);
 481                         }
 482                 }
 483 
 484                 if ((ipp = ibcm_arp_lookup(ibds, ifname)) == NULL)
 485                         continue;
 486 
 487                 ipp->ip_zoneid = ifzoneid;   /* Copy back the zoneid info */
 488                 switch (lifrp->lifr_addr.ss_family) {
 489                 case AF_INET:
 490                         ipp->ip_inet_family = AF_INET;
 491                         bcopy(&lifrp->lifr_addr, &ipp->ip_cm_sin,
 492                             sizeof (struct sockaddr_in));
 493                         naddr++;
 494                         break;
 495                 case AF_INET6:
 496                         ipp->ip_inet_family = AF_INET6;
 497                         bcopy(&lifrp->lifr_addr, &ipp->ip_cm_sin6,
 498                             sizeof (struct sockaddr_in6));
 499                         naddr++;
 500                         break;
 501                 }
 502         }
 503 
 504         kmem_free(lifc.lifc_buf, bufsize);
 505         return (naddr > 0);
 506 }
 507 
 508 ibt_status_t
 509 ibcm_arp_get_ibds(ibcm_arp_ibd_insts_t *ibdp, sa_family_t family_loc)
 510 {
 511 #ifdef DEBUG
 512         int i;
 513 #endif
 514 
 515         IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds(%p)", ibdp);
 516 
 517         ibcm_arp_get_ibd_insts(ibdp);
 518 
 519         IBTF_DPRINTF_L3(cmlog, "ibcm_arp_get_ibds: Found %d ibd instances",
 520             ibdp->ibcm_arp_ibd_cnt);
 521 
 522         if (ibdp->ibcm_arp_ibd_cnt == 0)
 523                 return (IBT_SRC_IP_NOT_FOUND);
 524 
 525         /* Get the IP addresses of active ports. */
 526         if (!ibcm_arp_get_ibd_ipaddr(ibdp, family_loc)) {
 527                 IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_ibds: failed to get "
 528                     "ibd instance: IBT_SRC_IP_NOT_FOUND");
 529                 ibcm_arp_free_ibds(ibdp);
 530                 return (IBT_SRC_IP_NOT_FOUND);
 531         }
 532 
 533 #ifdef DEBUG
 534         for (i = 0; i < ibdp->ibcm_arp_ibd_cnt; i++) {
 535                 char    my_buf[INET6_ADDRSTRLEN];
 536                 ibcm_arp_ip_t   *aip = &ibdp->ibcm_arp_ip[i];
 537 
 538                 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds: Linkid %d Family %d "
 539                     "PKey 0x%lX \n HCAGUID 0x%llX SGID %llX:%llX",
 540                     aip->ip_linkid, aip->ip_inet_family, aip->ip_pkey,
 541                     aip->ip_hca_guid, aip->ip_port_gid.gid_prefix,
 542                     aip->ip_port_gid.gid_guid);
 543                 if (aip->ip_inet_family == AF_INET) {
 544                         IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds: IPV4: %s",
 545                             inet_ntop(AF_INET, &aip->ip_cm_sin.sin_addr, my_buf,
 546                             sizeof (my_buf)));
 547                 } else if (aip->ip_inet_family == AF_INET6) {
 548                         IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds: IPV6: %s",
 549                             inet_ntop(AF_INET6, &aip->ip_cm_sin6.sin6_addr,
 550                             my_buf, sizeof (my_buf)));
 551                 } else {
 552                         IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_ibds: Unknown "
 553                             "Family %d", aip->ip_inet_family);
 554                 }
 555         }
 556 #endif
 557 
 558         return (IBT_SUCCESS);
 559 }