xref: /onnv-gate/usr/src/uts/common/io/ib/clients/rdsv3/rdsv3_sc.c (revision 12198:4db936bda957)
1*12198SEiji.Ota@Sun.COM /*
2*12198SEiji.Ota@Sun.COM  * CDDL HEADER START
3*12198SEiji.Ota@Sun.COM  *
4*12198SEiji.Ota@Sun.COM  * The contents of this file are subject to the terms of the
5*12198SEiji.Ota@Sun.COM  * Common Development and Distribution License (the "License").
6*12198SEiji.Ota@Sun.COM  * You may not use this file except in compliance with the License.
7*12198SEiji.Ota@Sun.COM  *
8*12198SEiji.Ota@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12198SEiji.Ota@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*12198SEiji.Ota@Sun.COM  * See the License for the specific language governing permissions
11*12198SEiji.Ota@Sun.COM  * and limitations under the License.
12*12198SEiji.Ota@Sun.COM  *
13*12198SEiji.Ota@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*12198SEiji.Ota@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12198SEiji.Ota@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*12198SEiji.Ota@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*12198SEiji.Ota@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12198SEiji.Ota@Sun.COM  *
19*12198SEiji.Ota@Sun.COM  * CDDL HEADER END
20*12198SEiji.Ota@Sun.COM  */
21*12198SEiji.Ota@Sun.COM /*
22*12198SEiji.Ota@Sun.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23*12198SEiji.Ota@Sun.COM  */
24*12198SEiji.Ota@Sun.COM #include <sys/types.h>
25*12198SEiji.Ota@Sun.COM #include <sys/sunddi.h>
26*12198SEiji.Ota@Sun.COM #include <sys/dlpi.h>
27*12198SEiji.Ota@Sun.COM #include <sys/ib/clients/rdsv3/rdsv3_sc.h>
28*12198SEiji.Ota@Sun.COM #include <sys/ib/clients/rdsv3/rdsv3_debug.h>
29*12198SEiji.Ota@Sun.COM 
30*12198SEiji.Ota@Sun.COM /*
31*12198SEiji.Ota@Sun.COM  * RDS Path MAP
32*12198SEiji.Ota@Sun.COM  *
33*12198SEiji.Ota@Sun.COM  * N - Node record, P - Path record
34*12198SEiji.Ota@Sun.COM  *
35*12198SEiji.Ota@Sun.COM  * rds_path_map -
36*12198SEiji.Ota@Sun.COM  *              |
37*12198SEiji.Ota@Sun.COM  *              v
38*12198SEiji.Ota@Sun.COM  *      	---------	---------	---------
39*12198SEiji.Ota@Sun.COM  *     		|   N   |------>|  N    |------>|   N   |------> NULL
40*12198SEiji.Ota@Sun.COM  * NULL <-------|       |<------|       |<------|       |
41*12198SEiji.Ota@Sun.COM  *     		---------       ---------       ---------
42*12198SEiji.Ota@Sun.COM  *               |               |               |
43*12198SEiji.Ota@Sun.COM  *               |               |               |
44*12198SEiji.Ota@Sun.COM  *               v               v               v
45*12198SEiji.Ota@Sun.COM  *		--------        ---------       ---------
46*12198SEiji.Ota@Sun.COM  *		|  P   |        |  P    |       |  P    |
47*12198SEiji.Ota@Sun.COM  *		--------        ---------       ---------
48*12198SEiji.Ota@Sun.COM  *		|  ^            |   ^           |   ^
49*12198SEiji.Ota@Sun.COM  *		|  |            |   |           |   |
50*12198SEiji.Ota@Sun.COM  *		v  |            v   |           v   |
51*12198SEiji.Ota@Sun.COM  *		--------	--------	---------
52*12198SEiji.Ota@Sun.COM  *		|   P  |	|  P   |	|  P    |
53*12198SEiji.Ota@Sun.COM  *		--------	--------	---------
54*12198SEiji.Ota@Sun.COM  *		  o		   o		   o
55*12198SEiji.Ota@Sun.COM  *		  o		   o		   o
56*12198SEiji.Ota@Sun.COM  *		  o		   o		   o
57*12198SEiji.Ota@Sun.COM  */
58*12198SEiji.Ota@Sun.COM 
59*12198SEiji.Ota@Sun.COM typedef struct rds_path_record_s {
60*12198SEiji.Ota@Sun.COM 	ipaddr_t			libd_ip;
61*12198SEiji.Ota@Sun.COM 	ipaddr_t			ribd_ip;
62*12198SEiji.Ota@Sun.COM 	struct rds_path_record_s	*up;
63*12198SEiji.Ota@Sun.COM 	struct rds_path_record_s	*downp;
64*12198SEiji.Ota@Sun.COM 	char				lifname[MAXNAMELEN];
65*12198SEiji.Ota@Sun.COM 	char				rifname[MAXNAMELEN];
66*12198SEiji.Ota@Sun.COM } rds_path_record_t;
67*12198SEiji.Ota@Sun.COM 
68*12198SEiji.Ota@Sun.COM typedef struct rds_node_record_s {
69*12198SEiji.Ota@Sun.COM 	struct rds_node_record_s	*nextp;
70*12198SEiji.Ota@Sun.COM 	ipaddr_t			lnode_ip;	/* local ip */
71*12198SEiji.Ota@Sun.COM 	ipaddr_t			rnode_ip;	/* remote ip */
72*12198SEiji.Ota@Sun.COM 	struct rds_path_record_s	*downp;
73*12198SEiji.Ota@Sun.COM 	struct rds_node_record_s	*prevp;
74*12198SEiji.Ota@Sun.COM } rds_node_record_t;
75*12198SEiji.Ota@Sun.COM 
76*12198SEiji.Ota@Sun.COM static char			sc_device_name[MAXNAMELEN] = "NotInitialized";
77*12198SEiji.Ota@Sun.COM static kmutex_t			rdsv3_pathmap_lock;
78*12198SEiji.Ota@Sun.COM static rds_node_record_t	*rdsv3_pathmap = NULL;
79*12198SEiji.Ota@Sun.COM 
80*12198SEiji.Ota@Sun.COM #define	RDS_VALIDATE_PATH(p)						\
81*12198SEiji.Ota@Sun.COM 	if ((p->local.iftype != DL_IB) || (p->remote.iftype != DL_IB))	\
82*12198SEiji.Ota@Sun.COM 		return
83*12198SEiji.Ota@Sun.COM 
84*12198SEiji.Ota@Sun.COM #define	isalpha(ch)	(((ch) >= 'a' && (ch) <= 'z') || \
85*12198SEiji.Ota@Sun.COM 			((ch) >= 'A' && (ch) <= 'Z'))
86*12198SEiji.Ota@Sun.COM 
87*12198SEiji.Ota@Sun.COM /*
88*12198SEiji.Ota@Sun.COM  * Called by SC to register the Sun Cluster device name
89*12198SEiji.Ota@Sun.COM  */
90*12198SEiji.Ota@Sun.COM void
rdsv3_clif_name(char * name)91*12198SEiji.Ota@Sun.COM rdsv3_clif_name(char *name)
92*12198SEiji.Ota@Sun.COM {
93*12198SEiji.Ota@Sun.COM 	int	i;
94*12198SEiji.Ota@Sun.COM 
95*12198SEiji.Ota@Sun.COM 	ASSERT(name != NULL);
96*12198SEiji.Ota@Sun.COM 
97*12198SEiji.Ota@Sun.COM 	mutex_enter(&rdsv3_pathmap_lock);
98*12198SEiji.Ota@Sun.COM 
99*12198SEiji.Ota@Sun.COM 	/* extract the device name from the interface name */
100*12198SEiji.Ota@Sun.COM 	i = strlen(name) - 1;
101*12198SEiji.Ota@Sun.COM 	while ((i >= 0) && (!isalpha(name[i]))) i--;
102*12198SEiji.Ota@Sun.COM 	if (i >= 0) {
103*12198SEiji.Ota@Sun.COM 		(void) strncpy(sc_device_name, name, i + 1);
104*12198SEiji.Ota@Sun.COM 		sc_device_name[i + 1] = '\0';
105*12198SEiji.Ota@Sun.COM 	}
106*12198SEiji.Ota@Sun.COM 
107*12198SEiji.Ota@Sun.COM 	mutex_exit(&rdsv3_pathmap_lock);
108*12198SEiji.Ota@Sun.COM }
109*12198SEiji.Ota@Sun.COM 
110*12198SEiji.Ota@Sun.COM /*
111*12198SEiji.Ota@Sun.COM  * Called by SC on discovering a new path
112*12198SEiji.Ota@Sun.COM  */
113*12198SEiji.Ota@Sun.COM void
rdsv3_path_up(rds_path_t * path)114*12198SEiji.Ota@Sun.COM rdsv3_path_up(rds_path_t *path)
115*12198SEiji.Ota@Sun.COM {
116*12198SEiji.Ota@Sun.COM 	rds_node_record_t	*p;
117*12198SEiji.Ota@Sun.COM 	rds_path_record_t	*p1;
118*12198SEiji.Ota@Sun.COM 
119*12198SEiji.Ota@Sun.COM 	ASSERT(path != NULL);
120*12198SEiji.Ota@Sun.COM 
121*12198SEiji.Ota@Sun.COM 	/* ignore if the end points are not of type DL_IB */
122*12198SEiji.Ota@Sun.COM 	RDS_VALIDATE_PATH(path);
123*12198SEiji.Ota@Sun.COM 
124*12198SEiji.Ota@Sun.COM 	mutex_enter(&rdsv3_pathmap_lock);
125*12198SEiji.Ota@Sun.COM 
126*12198SEiji.Ota@Sun.COM 	p = rdsv3_pathmap;
127*12198SEiji.Ota@Sun.COM 	while ((p) && ((p->lnode_ip != path->local.node_ipaddr) ||
128*12198SEiji.Ota@Sun.COM 	    (p->rnode_ip != path->remote.node_ipaddr))) {
129*12198SEiji.Ota@Sun.COM 		p = p->nextp;
130*12198SEiji.Ota@Sun.COM 	}
131*12198SEiji.Ota@Sun.COM 
132*12198SEiji.Ota@Sun.COM 	if (p == NULL) {
133*12198SEiji.Ota@Sun.COM 		p = (rds_node_record_t *)kmem_alloc(sizeof (rds_node_record_t),
134*12198SEiji.Ota@Sun.COM 		    KM_SLEEP);
135*12198SEiji.Ota@Sun.COM 		p1 = (rds_path_record_t *)kmem_alloc(
136*12198SEiji.Ota@Sun.COM 		    sizeof (rds_path_record_t), KM_SLEEP);
137*12198SEiji.Ota@Sun.COM 
138*12198SEiji.Ota@Sun.COM 		p->nextp = NULL;
139*12198SEiji.Ota@Sun.COM 		p->lnode_ip = path->local.node_ipaddr;
140*12198SEiji.Ota@Sun.COM 		p->rnode_ip = path->remote.node_ipaddr;
141*12198SEiji.Ota@Sun.COM 		p->downp = p1;
142*12198SEiji.Ota@Sun.COM 		p->prevp = NULL;
143*12198SEiji.Ota@Sun.COM 
144*12198SEiji.Ota@Sun.COM 		p1->libd_ip = path->local.ipaddr;
145*12198SEiji.Ota@Sun.COM 		p1->ribd_ip = path->remote.ipaddr;
146*12198SEiji.Ota@Sun.COM 		p1->up = NULL;
147*12198SEiji.Ota@Sun.COM 		p1->downp = NULL;
148*12198SEiji.Ota@Sun.COM 		(void) strcpy(p1->lifname, path->local.ifname);
149*12198SEiji.Ota@Sun.COM 		(void) strcpy(p1->rifname, path->remote.ifname);
150*12198SEiji.Ota@Sun.COM 
151*12198SEiji.Ota@Sun.COM 		if (rdsv3_pathmap == NULL) {
152*12198SEiji.Ota@Sun.COM 			rdsv3_pathmap = p;
153*12198SEiji.Ota@Sun.COM 		} else {
154*12198SEiji.Ota@Sun.COM 			/* insert this node at the head */
155*12198SEiji.Ota@Sun.COM 			rdsv3_pathmap->prevp = p;
156*12198SEiji.Ota@Sun.COM 			p->nextp = rdsv3_pathmap;
157*12198SEiji.Ota@Sun.COM 			rdsv3_pathmap = p;
158*12198SEiji.Ota@Sun.COM 		}
159*12198SEiji.Ota@Sun.COM 	} else {
160*12198SEiji.Ota@Sun.COM 		/* we found a match */
161*12198SEiji.Ota@Sun.COM 		p1 = (rds_path_record_t *)kmem_alloc(
162*12198SEiji.Ota@Sun.COM 		    sizeof (rds_path_record_t), KM_SLEEP);
163*12198SEiji.Ota@Sun.COM 
164*12198SEiji.Ota@Sun.COM 		p1->libd_ip = path->local.ipaddr;
165*12198SEiji.Ota@Sun.COM 		p1->ribd_ip = path->remote.ipaddr;
166*12198SEiji.Ota@Sun.COM 		p1->downp = p->downp;
167*12198SEiji.Ota@Sun.COM 		p->downp->up = p1;
168*12198SEiji.Ota@Sun.COM 		p1->up = NULL;
169*12198SEiji.Ota@Sun.COM 		p->downp = p1;
170*12198SEiji.Ota@Sun.COM 		(void) strcpy(p1->lifname, path->local.ifname);
171*12198SEiji.Ota@Sun.COM 		(void) strcpy(p1->rifname, path->remote.ifname);
172*12198SEiji.Ota@Sun.COM 	}
173*12198SEiji.Ota@Sun.COM 
174*12198SEiji.Ota@Sun.COM 	mutex_exit(&rdsv3_pathmap_lock);
175*12198SEiji.Ota@Sun.COM }
176*12198SEiji.Ota@Sun.COM 
177*12198SEiji.Ota@Sun.COM /*
178*12198SEiji.Ota@Sun.COM  * Called by SC to delete a path
179*12198SEiji.Ota@Sun.COM  */
180*12198SEiji.Ota@Sun.COM void
rdsv3_path_down(rds_path_t * path)181*12198SEiji.Ota@Sun.COM rdsv3_path_down(rds_path_t *path)
182*12198SEiji.Ota@Sun.COM {
183*12198SEiji.Ota@Sun.COM 	rds_node_record_t	*p;
184*12198SEiji.Ota@Sun.COM 	rds_path_record_t	*p1, *p1up, *p1downp;
185*12198SEiji.Ota@Sun.COM 
186*12198SEiji.Ota@Sun.COM 	ASSERT(path != NULL);
187*12198SEiji.Ota@Sun.COM 
188*12198SEiji.Ota@Sun.COM 	/* ignore if the end points are not of type DL_IB */
189*12198SEiji.Ota@Sun.COM 	RDS_VALIDATE_PATH(path);
190*12198SEiji.Ota@Sun.COM 
191*12198SEiji.Ota@Sun.COM 	mutex_enter(&rdsv3_pathmap_lock);
192*12198SEiji.Ota@Sun.COM 
193*12198SEiji.Ota@Sun.COM 	p = rdsv3_pathmap;
194*12198SEiji.Ota@Sun.COM 	while ((p) && ((p->lnode_ip != path->local.node_ipaddr) ||
195*12198SEiji.Ota@Sun.COM 	    (p->rnode_ip != path->remote.node_ipaddr))) {
196*12198SEiji.Ota@Sun.COM 		p = p->nextp;
197*12198SEiji.Ota@Sun.COM 	}
198*12198SEiji.Ota@Sun.COM 
199*12198SEiji.Ota@Sun.COM 	if (p == NULL) {
200*12198SEiji.Ota@Sun.COM 		/* no match */
201*12198SEiji.Ota@Sun.COM 		RDSV3_DPRINTF2("rdsv3_path_down", "Node record not found "
202*12198SEiji.Ota@Sun.COM 		    "(0x%x <-> 0x%x)", path->local.node_ipaddr,
203*12198SEiji.Ota@Sun.COM 		    path->remote.node_ipaddr);
204*12198SEiji.Ota@Sun.COM 		mutex_exit(&rdsv3_pathmap_lock);
205*12198SEiji.Ota@Sun.COM 		return;
206*12198SEiji.Ota@Sun.COM 	}
207*12198SEiji.Ota@Sun.COM 
208*12198SEiji.Ota@Sun.COM 	p1 = p->downp;
209*12198SEiji.Ota@Sun.COM 	while ((p1) && ((p1->libd_ip != path->local.ipaddr) ||
210*12198SEiji.Ota@Sun.COM 	    (p1->ribd_ip != path->remote.ipaddr))) {
211*12198SEiji.Ota@Sun.COM 		p1 = p1->downp;
212*12198SEiji.Ota@Sun.COM 	}
213*12198SEiji.Ota@Sun.COM 
214*12198SEiji.Ota@Sun.COM 	if (p1 == NULL) {
215*12198SEiji.Ota@Sun.COM 		/* no match */
216*12198SEiji.Ota@Sun.COM 		RDSV3_DPRINTF2("rdsv3_path_down", "Path record not found "
217*12198SEiji.Ota@Sun.COM 		    "(0x%x <-> 0x%x)", path->local.ipaddr, path->remote.ipaddr);
218*12198SEiji.Ota@Sun.COM 		mutex_exit(&rdsv3_pathmap_lock);
219*12198SEiji.Ota@Sun.COM 		return;
220*12198SEiji.Ota@Sun.COM 	}
221*12198SEiji.Ota@Sun.COM 
222*12198SEiji.Ota@Sun.COM 	/* we found the record, remove it */
223*12198SEiji.Ota@Sun.COM 	p1up = p1->up;
224*12198SEiji.Ota@Sun.COM 	p1downp = p1->downp;
225*12198SEiji.Ota@Sun.COM 
226*12198SEiji.Ota@Sun.COM 	if (p1up) {
227*12198SEiji.Ota@Sun.COM 		p1up->downp = p1downp;
228*12198SEiji.Ota@Sun.COM 	} else {
229*12198SEiji.Ota@Sun.COM 		/* this is the first path record */
230*12198SEiji.Ota@Sun.COM 		p->downp = p1downp;
231*12198SEiji.Ota@Sun.COM 	}
232*12198SEiji.Ota@Sun.COM 
233*12198SEiji.Ota@Sun.COM 	if (p1downp) {
234*12198SEiji.Ota@Sun.COM 		p1downp->up = p1up;
235*12198SEiji.Ota@Sun.COM 	}
236*12198SEiji.Ota@Sun.COM 
237*12198SEiji.Ota@Sun.COM 	kmem_free(p1, sizeof (rds_path_record_t));
238*12198SEiji.Ota@Sun.COM 
239*12198SEiji.Ota@Sun.COM 	/* remove the node record if there are no path records */
240*12198SEiji.Ota@Sun.COM 	if (p->downp == NULL) {
241*12198SEiji.Ota@Sun.COM 		if (p->prevp) {
242*12198SEiji.Ota@Sun.COM 			p->prevp->nextp = p->nextp;
243*12198SEiji.Ota@Sun.COM 		} else {
244*12198SEiji.Ota@Sun.COM 			/* this is the first node record */
245*12198SEiji.Ota@Sun.COM 			ASSERT(p == rdsv3_pathmap);
246*12198SEiji.Ota@Sun.COM 			rdsv3_pathmap = p->nextp;
247*12198SEiji.Ota@Sun.COM 		}
248*12198SEiji.Ota@Sun.COM 
249*12198SEiji.Ota@Sun.COM 		if (p->nextp) {
250*12198SEiji.Ota@Sun.COM 			p->nextp->prevp = p->prevp;
251*12198SEiji.Ota@Sun.COM 		}
252*12198SEiji.Ota@Sun.COM 
253*12198SEiji.Ota@Sun.COM 		kmem_free(p, sizeof (rds_node_record_t));
254*12198SEiji.Ota@Sun.COM 	}
255*12198SEiji.Ota@Sun.COM 
256*12198SEiji.Ota@Sun.COM 	mutex_exit(&rdsv3_pathmap_lock);
257*12198SEiji.Ota@Sun.COM }
258*12198SEiji.Ota@Sun.COM 
259*12198SEiji.Ota@Sun.COM int
rdsv3_sc_path_lookup(ipaddr_t * localip,ipaddr_t * remip)260*12198SEiji.Ota@Sun.COM rdsv3_sc_path_lookup(ipaddr_t *localip, ipaddr_t *remip)
261*12198SEiji.Ota@Sun.COM {
262*12198SEiji.Ota@Sun.COM 	rds_node_record_t	*p;
263*12198SEiji.Ota@Sun.COM 	rds_path_record_t	*p1, *p1downp;
264*12198SEiji.Ota@Sun.COM 
265*12198SEiji.Ota@Sun.COM 	mutex_enter(&rdsv3_pathmap_lock);
266*12198SEiji.Ota@Sun.COM 
267*12198SEiji.Ota@Sun.COM 	p = rdsv3_pathmap;
268*12198SEiji.Ota@Sun.COM 	while ((p) && ((p->lnode_ip != *localip) || (p->rnode_ip != *remip))) {
269*12198SEiji.Ota@Sun.COM 		p = p->nextp;
270*12198SEiji.Ota@Sun.COM 	}
271*12198SEiji.Ota@Sun.COM 
272*12198SEiji.Ota@Sun.COM 	if (p == NULL) {
273*12198SEiji.Ota@Sun.COM 		/* no match */
274*12198SEiji.Ota@Sun.COM 		RDSV3_DPRINTF2("rdsv3_sc_path_lookup", "Node record not found "
275*12198SEiji.Ota@Sun.COM 		    "(0x%x <-> 0x%x)", *localip, *remip);
276*12198SEiji.Ota@Sun.COM 		mutex_exit(&rdsv3_pathmap_lock);
277*12198SEiji.Ota@Sun.COM 		return (0);
278*12198SEiji.Ota@Sun.COM 	}
279*12198SEiji.Ota@Sun.COM 
280*12198SEiji.Ota@Sun.COM 	/* found a path */
281*12198SEiji.Ota@Sun.COM 	p1 = p->downp;
282*12198SEiji.Ota@Sun.COM 	*localip = p1->libd_ip;
283*12198SEiji.Ota@Sun.COM 	*remip = p1->ribd_ip;
284*12198SEiji.Ota@Sun.COM 
285*12198SEiji.Ota@Sun.COM 	/*
286*12198SEiji.Ota@Sun.COM 	 * But next time, we want to use a different path record so move this
287*12198SEiji.Ota@Sun.COM 	 * path record to the end.
288*12198SEiji.Ota@Sun.COM 	 */
289*12198SEiji.Ota@Sun.COM 	p1downp = p1->downp;
290*12198SEiji.Ota@Sun.COM 	if (p1downp != NULL) {
291*12198SEiji.Ota@Sun.COM 		p->downp = p1downp;
292*12198SEiji.Ota@Sun.COM 		p1downp->up = NULL;
293*12198SEiji.Ota@Sun.COM 
294*12198SEiji.Ota@Sun.COM 		/* walk down to the last path record */
295*12198SEiji.Ota@Sun.COM 		while (p1downp->downp != NULL) {
296*12198SEiji.Ota@Sun.COM 			p1downp = p1downp->downp;
297*12198SEiji.Ota@Sun.COM 		}
298*12198SEiji.Ota@Sun.COM 
299*12198SEiji.Ota@Sun.COM 		/* Attach the first path record to the end */
300*12198SEiji.Ota@Sun.COM 		p1downp->downp = p1;
301*12198SEiji.Ota@Sun.COM 		p1->up = p1downp;
302*12198SEiji.Ota@Sun.COM 		p1->downp = NULL;
303*12198SEiji.Ota@Sun.COM 	}
304*12198SEiji.Ota@Sun.COM 
305*12198SEiji.Ota@Sun.COM 	mutex_exit(&rdsv3_pathmap_lock);
306*12198SEiji.Ota@Sun.COM 
307*12198SEiji.Ota@Sun.COM 	return (1);
308*12198SEiji.Ota@Sun.COM }
309*12198SEiji.Ota@Sun.COM 
310*12198SEiji.Ota@Sun.COM boolean_t
rdsv3_if_lookup_by_name(char * devname)311*12198SEiji.Ota@Sun.COM rdsv3_if_lookup_by_name(char *devname)
312*12198SEiji.Ota@Sun.COM {
313*12198SEiji.Ota@Sun.COM 	mutex_enter(&rdsv3_pathmap_lock);
314*12198SEiji.Ota@Sun.COM 
315*12198SEiji.Ota@Sun.COM 	/*
316*12198SEiji.Ota@Sun.COM 	 * Sun Cluster always names its interconnect virtual network interface
317*12198SEiji.Ota@Sun.COM 	 * as clprivnetx, so  return TRUE if there is atleast one node record
318*12198SEiji.Ota@Sun.COM 	 * and the interface name is clprivnet something.
319*12198SEiji.Ota@Sun.COM 	 */
320*12198SEiji.Ota@Sun.COM 	if (strcmp(devname, sc_device_name) == 0) {
321*12198SEiji.Ota@Sun.COM 		/* clprivnet address */
322*12198SEiji.Ota@Sun.COM 		mutex_exit(&rdsv3_pathmap_lock);
323*12198SEiji.Ota@Sun.COM 		return (B_TRUE);
324*12198SEiji.Ota@Sun.COM 	}
325*12198SEiji.Ota@Sun.COM 
326*12198SEiji.Ota@Sun.COM 	mutex_exit(&rdsv3_pathmap_lock);
327*12198SEiji.Ota@Sun.COM 	return (B_FALSE);
328*12198SEiji.Ota@Sun.COM }
329*12198SEiji.Ota@Sun.COM 
330*12198SEiji.Ota@Sun.COM boolean_t
rdsv3_if_lookup_by_addr(ipaddr_t addr)331*12198SEiji.Ota@Sun.COM rdsv3_if_lookup_by_addr(ipaddr_t addr)
332*12198SEiji.Ota@Sun.COM {
333*12198SEiji.Ota@Sun.COM 	rds_node_record_t	*p;
334*12198SEiji.Ota@Sun.COM 	rds_path_record_t	*p1;
335*12198SEiji.Ota@Sun.COM 
336*12198SEiji.Ota@Sun.COM 	mutex_enter(&rdsv3_pathmap_lock);
337*12198SEiji.Ota@Sun.COM 
338*12198SEiji.Ota@Sun.COM 	p = rdsv3_pathmap;
339*12198SEiji.Ota@Sun.COM 	while ((p) && (p->lnode_ip != addr)) {
340*12198SEiji.Ota@Sun.COM 		p1 = p->downp;
341*12198SEiji.Ota@Sun.COM 		while ((p1) && (p1->libd_ip != addr)) {
342*12198SEiji.Ota@Sun.COM 			p1 = p1->downp;
343*12198SEiji.Ota@Sun.COM 		}
344*12198SEiji.Ota@Sun.COM 
345*12198SEiji.Ota@Sun.COM 		/* we found a match */
346*12198SEiji.Ota@Sun.COM 		if (p1 != NULL)
347*12198SEiji.Ota@Sun.COM 			break;
348*12198SEiji.Ota@Sun.COM 
349*12198SEiji.Ota@Sun.COM 		/* go to the next node record */
350*12198SEiji.Ota@Sun.COM 		p = p->nextp;
351*12198SEiji.Ota@Sun.COM 	}
352*12198SEiji.Ota@Sun.COM 
353*12198SEiji.Ota@Sun.COM 	mutex_exit(&rdsv3_pathmap_lock);
354*12198SEiji.Ota@Sun.COM 	if (p == NULL) {
355*12198SEiji.Ota@Sun.COM 		/* no match */
356*12198SEiji.Ota@Sun.COM 		RDSV3_DPRINTF2("rds_if_lookup_by_addr",
357*12198SEiji.Ota@Sun.COM 		    "Addr: 0x%x not found", addr);
358*12198SEiji.Ota@Sun.COM 		return (B_FALSE);
359*12198SEiji.Ota@Sun.COM 	}
360*12198SEiji.Ota@Sun.COM 
361*12198SEiji.Ota@Sun.COM 	/* Found a matching node record */
362*12198SEiji.Ota@Sun.COM 	return (B_TRUE);
363*12198SEiji.Ota@Sun.COM }
364*12198SEiji.Ota@Sun.COM 
365*12198SEiji.Ota@Sun.COM /*
366*12198SEiji.Ota@Sun.COM  * If SC is configured then addr would be a clprivnet address. Find the
367*12198SEiji.Ota@Sun.COM  * node record and return the first IB address. If the node record is not
368*12198SEiji.Ota@Sun.COM  * found, then return addr as-is.
369*12198SEiji.Ota@Sun.COM  */
370*12198SEiji.Ota@Sun.COM ipaddr_t
rdsv3_scaddr_to_ibaddr(ipaddr_t addr)371*12198SEiji.Ota@Sun.COM rdsv3_scaddr_to_ibaddr(ipaddr_t addr)
372*12198SEiji.Ota@Sun.COM {
373*12198SEiji.Ota@Sun.COM 	rds_node_record_t	*p;
374*12198SEiji.Ota@Sun.COM 	rds_path_record_t	*p1;
375*12198SEiji.Ota@Sun.COM 	ipaddr_t		ret = addr;
376*12198SEiji.Ota@Sun.COM 
377*12198SEiji.Ota@Sun.COM 	mutex_enter(&rdsv3_pathmap_lock);
378*12198SEiji.Ota@Sun.COM 
379*12198SEiji.Ota@Sun.COM 	p = rdsv3_pathmap;
380*12198SEiji.Ota@Sun.COM 	while ((p) && (p->lnode_ip != addr)) {
381*12198SEiji.Ota@Sun.COM 		/* go to the next node record */
382*12198SEiji.Ota@Sun.COM 		p = p->nextp;
383*12198SEiji.Ota@Sun.COM 	}
384*12198SEiji.Ota@Sun.COM 
385*12198SEiji.Ota@Sun.COM 	if (p != NULL) {
386*12198SEiji.Ota@Sun.COM 		p1 = p->downp;
387*12198SEiji.Ota@Sun.COM 		ret = p1->libd_ip;
388*12198SEiji.Ota@Sun.COM 		RDSV3_DPRINTF3("rds_scaddr_to_ibaddr",
389*12198SEiji.Ota@Sun.COM 		    "Addr: 0x%x found: 0x%x", addr, p1->libd_ip);
390*12198SEiji.Ota@Sun.COM 	}
391*12198SEiji.Ota@Sun.COM 	mutex_exit(&rdsv3_pathmap_lock);
392*12198SEiji.Ota@Sun.COM 
393*12198SEiji.Ota@Sun.COM 	/* Found a matching node record */
394*12198SEiji.Ota@Sun.COM 	return (ret);
395*12198SEiji.Ota@Sun.COM }
396