xref: /illumos-gate/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_arp.c (revision bd670b35a010421b6e1a5536c34453a827007c81)
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