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