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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/ddi.h> 28 #include <sys/sunddi.h> 29 #include <sys/strsubr.h> 30 #include <sys/socket.h> 31 #include <net/if_arp.h> 32 #include <net/if_types.h> 33 #include <sys/sockio.h> 34 #include <sys/pathname.h> 35 36 #include <sys/ib/mgt/ibcm/ibcm_arp.h> 37 38 #include <sys/kstr.h> 39 #include <sys/t_kuser.h> 40 41 extern char cmlog[]; 42 43 extern int ibcm_resolver_pr_lookup(ibcm_arp_streams_t *ib_s, 44 ibt_ip_addr_t *dst_addr, ibt_ip_addr_t *src_addr); 45 extern void ibcm_arp_delete_prwqn(ibcm_arp_prwqn_t *wqnp); 46 47 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibt_ip_addr_s)) 48 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_arp_ip_t)) 49 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_arp_ibd_insts_t)) 50 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_arp_prwqn_t)) 51 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", sockaddr_in)) 52 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", sockaddr_in6)) 53 54 int ibcm_printip = 0; 55 56 /* 57 * Function: 58 * ibcm_ip_print 59 * Input: 60 * label Arbitrary qualifying string 61 * ipa Pointer to IP Address to print 62 */ 63 void 64 ibcm_ip_print(char *label, ibt_ip_addr_t *ipaddr) 65 { 66 char buf[INET6_ADDRSTRLEN]; 67 68 if (ipaddr->family == AF_INET) { 69 IBTF_DPRINTF_L2(cmlog, "%s: %s", label, 70 inet_ntop(AF_INET, &ipaddr->un.ip4addr, buf, sizeof (buf))); 71 } else if (ipaddr->family == AF_INET6) { 72 IBTF_DPRINTF_L2(cmlog, "%s: %s", label, inet_ntop(AF_INET6, 73 &ipaddr->un.ip6addr, buf, sizeof (buf))); 74 } else { 75 IBTF_DPRINTF_L2(cmlog, "%s: IP ADDR NOT SPECIFIED ", label); 76 } 77 } 78 79 80 ibt_status_t 81 ibcm_arp_get_ibaddr(ibt_ip_addr_t srcaddr, ibt_ip_addr_t destaddr, 82 ib_gid_t *sgid, ib_gid_t *dgid) 83 { 84 ibcm_arp_streams_t *ib_s; 85 ibcm_arp_prwqn_t *wqnp; 86 int ret = 0; 87 88 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibaddr(%p, %p, %p, %p)", 89 srcaddr, destaddr, sgid, dgid); 90 91 ib_s = (ibcm_arp_streams_t *)kmem_zalloc(sizeof (ibcm_arp_streams_t), 92 KM_SLEEP); 93 94 mutex_init(&ib_s->lock, NULL, MUTEX_DEFAULT, NULL); 95 cv_init(&ib_s->cv, NULL, CV_DRIVER, NULL); 96 97 mutex_enter(&ib_s->lock); 98 ib_s->done = B_FALSE; 99 mutex_exit(&ib_s->lock); 100 101 ret = ibcm_resolver_pr_lookup(ib_s, &destaddr, &srcaddr); 102 103 IBTF_DPRINTF_L3(cmlog, "ibcm_arp_get_ibaddr: ibcm_resolver_pr_lookup " 104 "returned: %d", ret); 105 if (ret == 0) { 106 mutex_enter(&ib_s->lock); 107 while (ib_s->done != B_TRUE) 108 cv_wait(&ib_s->cv, &ib_s->lock); 109 mutex_exit(&ib_s->lock); 110 } 111 112 mutex_enter(&ib_s->lock); 113 wqnp = ib_s->wqnp; 114 if (ib_s->status == 0) { 115 if (sgid) 116 *sgid = ib_s->wqnp->sgid; 117 if (dgid) 118 *dgid = ib_s->wqnp->dgid; 119 120 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibaddr: SGID: %llX:%llX" 121 " DGID: %llX:%llX", 122 ib_s->wqnp->sgid.gid_prefix, ib_s->wqnp->sgid.gid_guid, 123 ib_s->wqnp->dgid.gid_prefix, ib_s->wqnp->dgid.gid_guid); 124 125 ibcm_arp_delete_prwqn(wqnp); 126 } else if (ret == 0) { 127 /* 128 * We come here only when lookup has returned empty (failed) 129 * via callback routine. 130 * i.e. ib_s->status is non-zero, while ret is zero. 131 */ 132 if (wqnp) 133 kmem_free(wqnp, sizeof (ibcm_arp_prwqn_t)); 134 } 135 ret = ib_s->status; 136 mutex_exit(&ib_s->lock); 137 138 arp_ibaddr_error: 139 140 mutex_destroy(&ib_s->lock); 141 cv_destroy(&ib_s->cv); 142 kmem_free(ib_s, sizeof (ibcm_arp_streams_t)); 143 144 if (ret) 145 return (IBT_FAILURE); 146 else 147 return (IBT_SUCCESS); 148 } 149 150 151 /* 152 * Routine to get list of "local" IP-ADDR to GID/P_KEY mapping information. 153 * Optionally, if "gid" and/or "p_key" info are specified, then retrieve the 154 * IP-ADDR info for that attribute only. 155 */ 156 157 static ibcm_arp_ip_t * 158 ibcm_arp_ibd_gid2mac(ib_gid_t *gid, ib_pkey_t pkey, ibcm_arp_ibd_insts_t *ibdp) 159 { 160 ibcm_arp_ip_t *ipp; 161 int i; 162 163 for (i = 0, ipp = ibdp->ibcm_arp_ip; i < ibdp->ibcm_arp_ibd_cnt; 164 i++, ipp++) { 165 if ((ipp->ip_port_gid.gid_prefix == gid->gid_prefix) && 166 (ipp->ip_port_gid.gid_guid == gid->gid_guid)) { 167 if (pkey) { 168 if (ipp->ip_pkey == pkey) 169 return (ipp); 170 else 171 continue; 172 } 173 return (ipp); 174 } 175 } 176 return (NULL); 177 } 178 179 static ibt_status_t 180 ibcm_arp_ibd_mac2gid(ibcm_arp_ibd_insts_t *ibdp, ibt_ip_addr_t *srcip, 181 ib_gid_t *sgid) 182 { 183 ibcm_arp_ip_t *ipp; 184 int i; 185 boolean_t found = B_FALSE; 186 187 for (i = 0, ipp = ibdp->ibcm_arp_ip; i < ibdp->ibcm_arp_ibd_cnt; 188 i++, ipp++) { 189 190 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_ibd_mac2gid: GID %llX:%llX", 191 ipp->ip_port_gid.gid_prefix, ipp->ip_port_gid.gid_guid); 192 193 if (srcip->family == ipp->ip_inet_family) { 194 if ((srcip->family == AF_INET) && 195 (bcmp(&srcip->un.ip4addr, &ipp->ip_cm_sin.sin_addr, 196 sizeof (in_addr_t)) == 0)) { 197 found = B_TRUE; 198 } else if ((srcip->family == AF_INET6) && 199 IN6_ARE_ADDR_EQUAL(&srcip->un.ip6addr, 200 &ipp->ip_cm_sin6.sin6_addr)) { 201 found = B_TRUE; 202 } 203 if (found) { 204 *sgid = ipp->ip_port_gid; 205 206 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_ibd_mac2gid: " 207 "Found GID %llX:%llX", sgid->gid_prefix, 208 sgid->gid_guid); 209 return (IBT_SUCCESS); 210 } 211 } else { 212 IBTF_DPRINTF_L3(cmlog, "ibcm_arp_ibd_mac2gid: Different" 213 " family keep searching..."); 214 } 215 } 216 IBTF_DPRINTF_L3(cmlog, "ibcm_arp_ibd_mac2gid: Matching SRC info " 217 "NOT Found"); 218 return (IBT_SRC_IP_NOT_FOUND); 219 } 220 221 static int 222 ibcm_arp_get_ibd_insts_cb(dev_info_t *dip, void *arg) 223 { 224 ibcm_arp_ibd_insts_t *ibds = (ibcm_arp_ibd_insts_t *)arg; 225 ibcm_arp_ip_t *ipp; 226 ib_pkey_t pkey; 227 uint8_t port; 228 ib_guid_t hca_guid; 229 ib_gid_t port_gid; 230 231 if (i_ddi_devi_attached(dip) && 232 (strcmp(ddi_node_name(dip), "ibport") == 0) && 233 (strstr(ddi_get_name_addr(dip), "ipib") != NULL)) { 234 235 if (ibds->ibcm_arp_ibd_cnt >= ibds->ibcm_arp_ibd_alloc) { 236 ibcm_arp_ip_t *tmp = NULL; 237 uint8_t new_count; 238 239 new_count = ibds->ibcm_arp_ibd_alloc + 240 IBCM_ARP_IBD_INSTANCES; 241 242 tmp = (ibcm_arp_ip_t *)kmem_zalloc( 243 new_count * sizeof (ibcm_arp_ip_t), KM_SLEEP); 244 bcopy(ibds->ibcm_arp_ip, tmp, 245 ibds->ibcm_arp_ibd_alloc * sizeof (ibcm_arp_ip_t)); 246 kmem_free(ibds->ibcm_arp_ip, 247 ibds->ibcm_arp_ibd_alloc * sizeof (ibcm_arp_ip_t)); 248 ibds->ibcm_arp_ibd_alloc = new_count; 249 ibds->ibcm_arp_ip = tmp; 250 } 251 252 if (((hca_guid = ddi_prop_get_int64(DDI_DEV_T_ANY, dip, 0, 253 "hca-guid", 0)) == 0) || 254 ((port = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 255 "port-number", 0)) == 0) || 256 (ibt_get_port_state_byguid(hca_guid, port, &port_gid, 257 NULL) != IBT_SUCCESS) || 258 ((pkey = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 259 "port-pkey", IB_PKEY_INVALID_LIMITED)) <= 260 IB_PKEY_INVALID_FULL)) { 261 return (DDI_WALK_CONTINUE); 262 } 263 264 ipp = &ibds->ibcm_arp_ip[ibds->ibcm_arp_ibd_cnt]; 265 ipp->ip_inst = ddi_get_instance(dip); 266 ipp->ip_pkey = pkey; 267 ipp->ip_hca_guid = hca_guid; 268 ipp->ip_port_gid = port_gid; 269 ibds->ibcm_arp_ibd_cnt++; 270 } 271 return (DDI_WALK_CONTINUE); 272 } 273 274 static void 275 ibcm_arp_get_ibd_insts(ibcm_arp_ibd_insts_t *ibds) 276 { 277 ddi_walk_devs(ddi_root_node(), ibcm_arp_get_ibd_insts_cb, ibds); 278 } 279 280 /* 281 * Issue an ioctl down to IP. There are several similar versions of this 282 * function (e.g., rpcib_do_ip_ioctl()); clearly a utility routine is needed. 283 */ 284 static int 285 ibcm_do_ip_ioctl(int cmd, int len, void *arg) 286 { 287 vnode_t *kvp; 288 TIUSER *tiptr; 289 struct strioctl iocb; 290 int err = 0; 291 292 if (lookupname("/dev/udp", UIO_SYSSPACE, FOLLOW, NULLVPP, &kvp) != 0) 293 return (EPROTO); 294 295 if (t_kopen(NULL, kvp->v_rdev, FREAD|FWRITE, &tiptr, CRED()) != 0) { 296 VN_RELE(kvp); 297 return (EPROTO); 298 } 299 300 iocb.ic_cmd = cmd; 301 iocb.ic_timout = 0; 302 iocb.ic_len = len; 303 iocb.ic_dp = (caddr_t)arg; 304 err = kstr_ioctl(tiptr->fp->f_vnode, I_STR, (intptr_t)&iocb); 305 (void) t_kclose(tiptr, 0); 306 VN_RELE(kvp); 307 return (err); 308 } 309 310 /* 311 * Issue an SIOCGLIFCONF down to IP and return the result in `lifcp'. 312 * lifcp->lifc_buf is dynamically allocated to be *bufsizep bytes. 313 */ 314 static int 315 ibcm_do_lifconf(struct lifconf *lifcp, uint_t *bufsizep, sa_family_t family_loc) 316 { 317 int err; 318 struct lifnum lifn; 319 320 bzero(&lifn, sizeof (struct lifnum)); 321 lifn.lifn_family = family_loc; 322 323 err = ibcm_do_ip_ioctl(SIOCGLIFNUM, sizeof (struct lifnum), &lifn); 324 if (err != 0) 325 return (err); 326 327 IBTF_DPRINTF_L4(cmlog, "ibcm_do_lifconf: Family %d, lifn_count %d", 328 family_loc, lifn.lifn_count); 329 /* 330 * Pad the interface count to account for additional interfaces that 331 * may have been configured between the SIOCGLIFNUM and SIOCGLIFCONF. 332 */ 333 lifn.lifn_count += 4; 334 335 bzero(lifcp, sizeof (struct lifconf)); 336 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lifcp)) 337 lifcp->lifc_family = family_loc; 338 lifcp->lifc_len = *bufsizep = lifn.lifn_count * sizeof (struct lifreq); 339 lifcp->lifc_buf = kmem_zalloc(*bufsizep, KM_SLEEP); 340 341 err = ibcm_do_ip_ioctl(SIOCGLIFCONF, sizeof (struct lifconf), lifcp); 342 if (err != 0) { 343 kmem_free(lifcp->lifc_buf, *bufsizep); 344 return (err); 345 } 346 return (0); 347 } 348 349 /* 350 * Fill in `ibds' with IP addresses tied to IFT_IB IP interfaces. Returns 351 * B_TRUE if at least one address was filled in. 352 */ 353 static boolean_t 354 ibcm_arp_get_ibd_ipaddr(ibcm_arp_ibd_insts_t *ibds, sa_family_t family_loc) 355 { 356 int i, nifs, naddr = 0; 357 uint_t bufsize; 358 struct lifconf lifc; 359 struct lifreq *lifrp; 360 ibcm_arp_ip_t *ipp; 361 362 if (ibcm_do_lifconf(&lifc, &bufsize, family_loc) != 0) 363 return (B_FALSE); 364 365 nifs = lifc.lifc_len / sizeof (struct lifreq); 366 367 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibd_ipaddr: Family %d, nifs %d", 368 family_loc, nifs); 369 370 for (lifrp = lifc.lifc_req, i = 0; 371 i < nifs && naddr < ibds->ibcm_arp_ibd_cnt; i++, lifrp++) { 372 if (lifrp->lifr_type != IFT_IB) 373 continue; 374 375 ipp = &ibds->ibcm_arp_ip[naddr]; 376 switch (lifrp->lifr_addr.ss_family) { 377 case AF_INET: 378 ipp->ip_inet_family = AF_INET; 379 bcopy(&lifrp->lifr_addr, &ipp->ip_cm_sin, 380 sizeof (struct sockaddr_in)); 381 naddr++; 382 break; 383 case AF_INET6: 384 ipp->ip_inet_family = AF_INET6; 385 bcopy(&lifrp->lifr_addr, &ipp->ip_cm_sin6, 386 sizeof (struct sockaddr_in6)); 387 naddr++; 388 break; 389 } 390 } 391 392 kmem_free(lifc.lifc_buf, bufsize); 393 return (naddr > 0); 394 } 395 396 ibt_status_t 397 ibcm_arp_get_ibds(ibcm_arp_ibd_insts_t *ibdp, sa_family_t family_loc) 398 { 399 #ifdef DEBUG 400 int i; 401 #endif 402 403 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds(%p)", ibdp); 404 405 ibcm_arp_get_ibd_insts(ibdp); 406 407 IBTF_DPRINTF_L3(cmlog, "ibcm_arp_get_ibds: Found %d ibd instances", 408 ibdp->ibcm_arp_ibd_cnt); 409 410 if (ibdp->ibcm_arp_ibd_cnt == 0) 411 return (IBT_SRC_IP_NOT_FOUND); 412 413 /* Get the IP addresses of active ports. */ 414 if (!ibcm_arp_get_ibd_ipaddr(ibdp, family_loc)) { 415 IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_ibds: failed to get " 416 "ibd instance: IBT_SRC_IP_NOT_FOUND"); 417 return (IBT_SRC_IP_NOT_FOUND); 418 } 419 420 #ifdef DEBUG 421 for (i = 0; i < ibdp->ibcm_arp_ibd_cnt; i++) { 422 char my_buf[INET6_ADDRSTRLEN]; 423 ibcm_arp_ip_t *aip = &ibdp->ibcm_arp_ip[i]; 424 425 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds: ibd[%d]: Family %d " 426 "Instance %d PKey 0x%lX \n HCAGUID 0x%llX SGID %llX:%llX", 427 i, aip->ip_inet_family, aip->ip_inst, aip->ip_pkey, 428 aip->ip_hca_guid, aip->ip_port_gid.gid_prefix, 429 aip->ip_port_gid.gid_guid); 430 if (aip->ip_inet_family == AF_INET) { 431 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds: IPV4: %s", 432 inet_ntop(AF_INET, &aip->ip_cm_sin.sin_addr, my_buf, 433 sizeof (my_buf))); 434 } else if (aip->ip_inet_family == AF_INET6) { 435 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_ibds: IPV6: %s", 436 inet_ntop(AF_INET6, &aip->ip_cm_sin6.sin6_addr, 437 my_buf, sizeof (my_buf))); 438 } else { 439 IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_ibds: Unknown " 440 "Family %d", aip->ip_inet_family); 441 } 442 } 443 #endif 444 445 return (IBT_SUCCESS); 446 } 447 448 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibtl_cm_port_list_t)) 449 450 ibt_status_t 451 ibcm_arp_get_srcip_plist(ibt_ip_path_attr_t *ipattr, ibt_path_flags_t flags, 452 ibtl_cm_port_list_t **port_list_p) 453 { 454 ibt_path_attr_t attr; 455 ibt_status_t ret; 456 ibcm_arp_ibd_insts_t ibds; 457 ibcm_arp_ip_t *ipp; 458 ibtl_cm_port_list_t *plistp; 459 ib_gid_t sgid; 460 sa_family_t family_interested = AF_UNSPEC; 461 462 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_srcip_plist(%p, %llX)", 463 ipattr, flags); 464 465 if (ipattr->ipa_src_ip.family != AF_UNSPEC) 466 family_interested = ipattr->ipa_src_ip.family; 467 else 468 family_interested = ipattr->ipa_dst_ip[0].family; 469 470 sgid.gid_prefix = sgid.gid_guid = 0; 471 bzero(&ibds, sizeof (ibcm_arp_ibd_insts_t)); 472 ibds.ibcm_arp_ibd_alloc = IBCM_ARP_IBD_INSTANCES; 473 ibds.ibcm_arp_ibd_cnt = 0; 474 ibds.ibcm_arp_ip = (ibcm_arp_ip_t *)kmem_zalloc( 475 ibds.ibcm_arp_ibd_alloc * sizeof (ibcm_arp_ip_t), KM_SLEEP); 476 477 ret = ibcm_arp_get_ibds(&ibds, family_interested); 478 if (ret != IBT_SUCCESS) { 479 IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_srcip_plist: " 480 "ibcm_arp_get_ibds failed : 0x%x", ret); 481 goto srcip_plist_end; 482 } 483 484 if (ipattr->ipa_src_ip.family != AF_UNSPEC) { 485 ret = ibcm_arp_ibd_mac2gid(&ibds, &ipattr->ipa_src_ip, &sgid); 486 if (ret != IBT_SUCCESS) { 487 IBTF_DPRINTF_L2(cmlog, "ibcm_arp_get_srcip_plist: " 488 "SGID for the specified SRCIP Not found %X", ret); 489 goto srcip_plist_end; 490 } 491 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_srcip_plist: SGID " 492 "%llX:%llX", sgid.gid_prefix, sgid.gid_guid); 493 } 494 495 bzero(&attr, sizeof (ibt_path_attr_t)); 496 attr.pa_hca_guid = ipattr->ipa_hca_guid; 497 attr.pa_hca_port_num = ipattr->ipa_hca_port_num; 498 attr.pa_sgid = sgid; 499 bcopy(&ipattr->ipa_mtu, &attr.pa_mtu, sizeof (ibt_mtu_req_t)); 500 bcopy(&ipattr->ipa_srate, &attr.pa_srate, sizeof (ibt_srate_req_t)); 501 bcopy(&ipattr->ipa_pkt_lt, &attr.pa_pkt_lt, sizeof (ibt_pkt_lt_req_t)); 502 503 ret = ibtl_cm_get_active_plist(&attr, flags, port_list_p); 504 if (ret == IBT_SUCCESS) { 505 int i; 506 uint8_t cnt; 507 boolean_t no_srcip_configured = B_FALSE; 508 uint8_t no_srcip_cnt = 0; 509 510 plistp = port_list_p[0]; 511 cnt = plistp->p_count; 512 for (i = 0; i < cnt; i++, plistp++) { 513 ipp = ibcm_arp_ibd_gid2mac(&plistp->p_sgid, 0, &ibds); 514 if ((ipp == NULL) || 515 (ipp->ip_inet_family == AF_UNSPEC)) { 516 plistp->p_src_ip.family = AF_UNSPEC; 517 no_srcip_configured = B_TRUE; 518 no_srcip_cnt++; 519 IBTF_DPRINTF_L3(cmlog, 520 "ibcm_arp_get_srcip_plist: SrcIP NOT " 521 "Configured for GID %llX:%llX", 522 plistp->p_sgid.gid_prefix, 523 plistp->p_sgid.gid_guid); 524 } else { 525 IBTF_DPRINTF_L4(cmlog, 526 "ibcm_arp_get_srcip_plist: GID %llX:%llX", 527 plistp->p_sgid.gid_prefix, 528 plistp->p_sgid.gid_guid); 529 if (ipp->ip_inet_family == AF_INET) { 530 plistp->p_src_ip.family = AF_INET; 531 bcopy(&ipp->ip_cm_sin.sin_addr, 532 &plistp->p_src_ip.un.ip4addr, 533 sizeof (in_addr_t)); 534 535 } else if (ipp->ip_inet_family == AF_INET6) { 536 plistp->p_src_ip.family = AF_INET6; 537 bcopy(&ipp->ip_cm_sin6.sin6_addr, 538 &plistp->p_src_ip.un.ip6addr, 539 sizeof (in6_addr_t)); 540 } 541 IBCM_PRINT_IP("ibcm_arp_get_srcip_plist: " 542 "IP Addr is:", &plistp->p_src_ip); 543 } 544 } 545 if (no_srcip_configured) { 546 ibtl_cm_port_list_t *n_plistp, *tmp_n_plistp; 547 uint8_t new_cnt; 548 549 new_cnt = cnt - no_srcip_cnt; 550 551 /* 552 * Looks like some of the SRC GID we found have no 553 * IP ADDR configured, so remove these entries from 554 * our list. 555 */ 556 plistp = port_list_p[0]; 557 IBTF_DPRINTF_L4(cmlog, "ibcm_arp_get_srcip_plist: " 558 "Only %d SGID (%d/%d) have SrcIP Configured", 559 new_cnt, no_srcip_cnt, cnt); 560 if (new_cnt) { 561 /* Allocate Memory to hold Src Point info. */ 562 n_plistp = kmem_zalloc(new_cnt * 563 sizeof (ibtl_cm_port_list_t), KM_SLEEP); 564 565 tmp_n_plistp = n_plistp; 566 for (i = 0; i < cnt; i++, plistp++) { 567 if (plistp->p_src_ip.family == 568 AF_UNSPEC) 569 continue; 570 571 bcopy(plistp, n_plistp, 572 sizeof (ibtl_cm_port_list_t)); 573 n_plistp->p_count = new_cnt; 574 n_plistp++; 575 } 576 plistp = port_list_p[0]; 577 *port_list_p = tmp_n_plistp; 578 } else { 579 /* 580 * All entries we have, do not have IP-Addr 581 * configured so return empty hand. 582 */ 583 IBTF_DPRINTF_L2(cmlog, 584 "ibcm_arp_get_srcip_plist: None of SGID " 585 "found have SrcIP Configured"); 586 *port_list_p = NULL; 587 ret = IBT_SRC_IP_NOT_FOUND; 588 } 589 IBTF_DPRINTF_L4(cmlog, "FREE OLD list %p, NEW list is " 590 "%p - %p", plistp, port_list_p, *port_list_p); 591 kmem_free(plistp, cnt * sizeof (ibtl_cm_port_list_t)); 592 } 593 } 594 595 srcip_plist_end: 596 if (ibds.ibcm_arp_ip) 597 kmem_free(ibds.ibcm_arp_ip, ibds.ibcm_arp_ibd_alloc * 598 sizeof (ibcm_arp_ip_t)); 599 600 return (ret); 601 } 602