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