xref: /illumos-gate/usr/src/cmd/isns/isnsd/qry.c (revision fcf3ce44)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte 
22*fcf3ce44SJohn Forte /*
23*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*fcf3ce44SJohn Forte  * Use is subject to license terms.
25*fcf3ce44SJohn Forte  */
26*fcf3ce44SJohn Forte 
27*fcf3ce44SJohn Forte #include <stdio.h>
28*fcf3ce44SJohn Forte #include <stdlib.h>
29*fcf3ce44SJohn Forte #include <string.h>
30*fcf3ce44SJohn Forte 
31*fcf3ce44SJohn Forte #include "isns_server.h"
32*fcf3ce44SJohn Forte #include "isns_func.h"
33*fcf3ce44SJohn Forte #include "isns_msgq.h"
34*fcf3ce44SJohn Forte #include "isns_htab.h"
35*fcf3ce44SJohn Forte #include "isns_cache.h"
36*fcf3ce44SJohn Forte #include "isns_obj.h"
37*fcf3ce44SJohn Forte #include "isns_dd.h"
38*fcf3ce44SJohn Forte #include "isns_pdu.h"
39*fcf3ce44SJohn Forte #include "isns_qry.h"
40*fcf3ce44SJohn Forte 
41*fcf3ce44SJohn Forte /*
42*fcf3ce44SJohn Forte  * external variables
43*fcf3ce44SJohn Forte  */
44*fcf3ce44SJohn Forte extern const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE];
45*fcf3ce44SJohn Forte extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
46*fcf3ce44SJohn Forte extern const int NUM_OF_CHILD[MAX_OBJ_TYPE];
47*fcf3ce44SJohn Forte extern const int TYPE_OF_CHILD[MAX_OBJ_TYPE][MAX_CHILD_TYPE];
48*fcf3ce44SJohn Forte 
49*fcf3ce44SJohn Forte /*
50*fcf3ce44SJohn Forte  * global variables
51*fcf3ce44SJohn Forte  */
52*fcf3ce44SJohn Forte const int TAG_RANGE[MAX_OBJ_TYPE][3] = {
53*fcf3ce44SJohn Forte 	{ 0, 0 },
54*fcf3ce44SJohn Forte 	{ ENTITY_KEY, LAST_TAG_ENTITY, ENTITY_END },
55*fcf3ce44SJohn Forte 	{ ISCSI_KEY, LAST_TAG_ISCSI, ISCSI_END },
56*fcf3ce44SJohn Forte 	{ PORTAL_KEY1, LAST_TAG_PORTAL, PORTAL_END },
57*fcf3ce44SJohn Forte 	{ PG_KEY1, LAST_TAG_PG, PG_END },
58*fcf3ce44SJohn Forte 	{ DD_KEY, LAST_TAG_DD, DD_END },
59*fcf3ce44SJohn Forte 	{ DDS_KEY, LAST_TAG_DDS, DDS_END }
60*fcf3ce44SJohn Forte };
61*fcf3ce44SJohn Forte 
62*fcf3ce44SJohn Forte /*
63*fcf3ce44SJohn Forte  * local variables
64*fcf3ce44SJohn Forte  */
65*fcf3ce44SJohn Forte typedef int (*qry_func_t)(lookup_ctrl_t *);
66*fcf3ce44SJohn Forte 
67*fcf3ce44SJohn Forte /* Edge functions of each adjacent object */
68*fcf3ce44SJohn Forte static int qry_c2e(lookup_ctrl_t *);
69*fcf3ce44SJohn Forte static int qry_ds2m(lookup_ctrl_t *);
70*fcf3ce44SJohn Forte static int qry_slf(lookup_ctrl_t *);
71*fcf3ce44SJohn Forte static int qry_e2i(lookup_ctrl_t *);
72*fcf3ce44SJohn Forte static int qry_e2p(lookup_ctrl_t *);
73*fcf3ce44SJohn Forte static int qry_e2g(lookup_ctrl_t *);
74*fcf3ce44SJohn Forte static int qry_i2g(lookup_ctrl_t *);
75*fcf3ce44SJohn Forte static int qry_i2d(lookup_ctrl_t *);
76*fcf3ce44SJohn Forte static int qry_p2g(lookup_ctrl_t *);
77*fcf3ce44SJohn Forte static int qry_g2i(lookup_ctrl_t *);
78*fcf3ce44SJohn Forte static int qry_g2p(lookup_ctrl_t *);
79*fcf3ce44SJohn Forte static int qry_d2s(lookup_ctrl_t *);
80*fcf3ce44SJohn Forte 
81*fcf3ce44SJohn Forte /* The directed cyclic graph of query procedure. */
82*fcf3ce44SJohn Forte /* __|____e_________i_________p_________g_________d_________s____ */
83*fcf3ce44SJohn Forte /* e | qry_slf...qry_e2i...qry_e2p...qry_e2g...NULL......NULL.... */
84*fcf3ce44SJohn Forte /* i | qry_c2e...qry_slf...NULL......qry_i2g...qry_i2d...NULL.... */
85*fcf3ce44SJohn Forte /* p | qry_c2e...NULL......qry_slf...qry_p2g...NULL......NULL.... */
86*fcf3ce44SJohn Forte /* g | qry_c2e...qry_g2i...qry_g2p...qry_slf...NULL......NULL.... */
87*fcf3ce44SJohn Forte /* d | NULL......qry_ds2m..NULL......NULL......qry_slf...qry_d2s. */
88*fcf3ce44SJohn Forte /* s | NULL......NULL......NULL......NULL......qry_ds2m..qry_slf. */
89*fcf3ce44SJohn Forte 
90*fcf3ce44SJohn Forte /* The type of spanning tree of query graph. */
91*fcf3ce44SJohn Forte typedef struct adjvex {
92*fcf3ce44SJohn Forte 	qry_func_t f;
93*fcf3ce44SJohn Forte 	isns_type_t t;
94*fcf3ce44SJohn Forte 	struct adjvex const *v;
95*fcf3ce44SJohn Forte } adjvex_t;
96*fcf3ce44SJohn Forte 
97*fcf3ce44SJohn Forte /* The solid edges in the spanning tree. */
98*fcf3ce44SJohn Forte static const adjvex_t v_slf = { &qry_slf,  0,		NULL };
99*fcf3ce44SJohn Forte static const adjvex_t v_c2e = { &qry_c2e,  OBJ_ENTITY,	NULL };
100*fcf3ce44SJohn Forte static const adjvex_t v_e2i = { &qry_e2i,  OBJ_ISCSI,	NULL };
101*fcf3ce44SJohn Forte static const adjvex_t v_e2p = { &qry_e2p,  OBJ_PORTAL,	NULL };
102*fcf3ce44SJohn Forte static const adjvex_t v_e2g = { &qry_e2g,  OBJ_PG,	NULL };
103*fcf3ce44SJohn Forte static const adjvex_t v_i2g = { &qry_i2g,  OBJ_PG,	NULL };
104*fcf3ce44SJohn Forte static const adjvex_t v_i2d = { &qry_i2d,  OBJ_DD,	NULL };
105*fcf3ce44SJohn Forte static const adjvex_t v_p2g = { &qry_p2g,  OBJ_PG,	NULL };
106*fcf3ce44SJohn Forte static const adjvex_t v_g2i = { &qry_g2i,  OBJ_ISCSI,	NULL };
107*fcf3ce44SJohn Forte static const adjvex_t v_g2p = { &qry_g2p,  OBJ_PORTAL,	NULL };
108*fcf3ce44SJohn Forte static const adjvex_t v_d2s = { &qry_d2s,  OBJ_DDS,	NULL };
109*fcf3ce44SJohn Forte static const adjvex_t v_d2i = { &qry_ds2m, OBJ_ISCSI,	NULL };
110*fcf3ce44SJohn Forte static const adjvex_t v_s2d = { &qry_ds2m, OBJ_DD,	NULL };
111*fcf3ce44SJohn Forte 
112*fcf3ce44SJohn Forte /* The virtual edges in the spanning tree. */
113*fcf3ce44SJohn Forte static const adjvex_t v_i2p = { &qry_i2g,  OBJ_PG,    &v_g2p };
114*fcf3ce44SJohn Forte static const adjvex_t v_i2s = { &qry_i2d,  OBJ_DD,    &v_d2s };
115*fcf3ce44SJohn Forte 
116*fcf3ce44SJohn Forte static const adjvex_t v_g2d = { &qry_g2i,  OBJ_ISCSI, &v_i2d };
117*fcf3ce44SJohn Forte static const adjvex_t v_g2s = { &qry_g2i,  OBJ_ISCSI, &v_i2s };
118*fcf3ce44SJohn Forte 
119*fcf3ce44SJohn Forte static const adjvex_t v_p2i = { &qry_p2g,  OBJ_PG,    &v_g2i };
120*fcf3ce44SJohn Forte static const adjvex_t v_p2d = { &qry_p2g,  OBJ_PG,    &v_g2d };
121*fcf3ce44SJohn Forte static const adjvex_t v_p2s = { &qry_p2g,  OBJ_PG,    &v_g2s };
122*fcf3ce44SJohn Forte 
123*fcf3ce44SJohn Forte static const adjvex_t v_e2d = { &qry_e2i,  OBJ_ISCSI, &v_i2d };
124*fcf3ce44SJohn Forte static const adjvex_t v_e2s = { &qry_e2i,  OBJ_ISCSI, &v_i2s };
125*fcf3ce44SJohn Forte 
126*fcf3ce44SJohn Forte static const adjvex_t v_d2e = { &qry_ds2m, OBJ_ISCSI, &v_c2e };
127*fcf3ce44SJohn Forte static const adjvex_t v_d2p = { &qry_ds2m, OBJ_ISCSI, &v_i2p };
128*fcf3ce44SJohn Forte static const adjvex_t v_d2g = { &qry_ds2m, OBJ_ISCSI, &v_i2g };
129*fcf3ce44SJohn Forte 
130*fcf3ce44SJohn Forte static const adjvex_t v_s2e = { &qry_ds2m, OBJ_DD,    &v_d2e };
131*fcf3ce44SJohn Forte static const adjvex_t v_s2i = { &qry_ds2m, OBJ_DD,    &v_d2i };
132*fcf3ce44SJohn Forte static const adjvex_t v_s2p = { &qry_ds2m, OBJ_DD,    &v_d2p };
133*fcf3ce44SJohn Forte static const adjvex_t v_s2g = { &qry_ds2m, OBJ_DD,    &v_d2g };
134*fcf3ce44SJohn Forte 
135*fcf3ce44SJohn Forte /* the vector of query graph */
136*fcf3ce44SJohn Forte static const adjvex_t *qry_puzzle[MAX_OBJ_TYPE][MAX_OBJ_TYPE] = {
137*fcf3ce44SJohn Forte { NULL },
138*fcf3ce44SJohn Forte { NULL, &v_slf, &v_e2i, &v_e2p, &v_e2g, &v_e2d, &v_e2s },
139*fcf3ce44SJohn Forte { NULL, &v_c2e, &v_slf, &v_i2p, &v_i2g, &v_i2d, &v_i2s },
140*fcf3ce44SJohn Forte { NULL, &v_c2e, &v_p2i, &v_slf, &v_p2g, &v_p2d, &v_p2s },
141*fcf3ce44SJohn Forte { NULL, &v_c2e, &v_g2i, &v_g2p, &v_slf, &v_g2d, &v_g2s },
142*fcf3ce44SJohn Forte { NULL, &v_d2e, &v_d2i, &v_d2p, &v_d2g, &v_slf, &v_d2s },
143*fcf3ce44SJohn Forte { NULL, &v_s2e, &v_s2i, &v_s2p, &v_s2g, &v_s2d, &v_slf }
144*fcf3ce44SJohn Forte };
145*fcf3ce44SJohn Forte 
146*fcf3ce44SJohn Forte static int
cb_qry_parent_uid(void * p1,void * p2)147*fcf3ce44SJohn Forte cb_qry_parent_uid(
148*fcf3ce44SJohn Forte 	void *p1,
149*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_ARG_UNUSED */
150*fcf3ce44SJohn Forte 	void *p2
151*fcf3ce44SJohn Forte )
152*fcf3ce44SJohn Forte {
153*fcf3ce44SJohn Forte 	uint32_t puid = get_parent_uid((isns_obj_t *)p1);
154*fcf3ce44SJohn Forte 	return ((int)puid);
155*fcf3ce44SJohn Forte }
156*fcf3ce44SJohn Forte 
157*fcf3ce44SJohn Forte static int
cb_qry_child_uids(void * p1,void * p2)158*fcf3ce44SJohn Forte cb_qry_child_uids(
159*fcf3ce44SJohn Forte 	void *p1,
160*fcf3ce44SJohn Forte 	void *p2
161*fcf3ce44SJohn Forte )
162*fcf3ce44SJohn Forte {
163*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
164*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
165*fcf3ce44SJohn Forte 	isns_type_t type = lcp->data[1].ui;
166*fcf3ce44SJohn Forte 	uint32_t *uidp = get_child_t(obj, type);
167*fcf3ce44SJohn Forte 	uint32_t num = 0;
168*fcf3ce44SJohn Forte 	uint32_t *p;
169*fcf3ce44SJohn Forte 
170*fcf3ce44SJohn Forte 	if (uidp != NULL && *uidp > 0) {
171*fcf3ce44SJohn Forte 		num = *uidp;
172*fcf3ce44SJohn Forte 		p = malloc(num * sizeof (*p));
173*fcf3ce44SJohn Forte 		if (p != NULL) {
174*fcf3ce44SJohn Forte 			uidp ++;
175*fcf3ce44SJohn Forte 			(void) memcpy(p, uidp, num * sizeof (*p));
176*fcf3ce44SJohn Forte 			lcp->id[2] = num;
177*fcf3ce44SJohn Forte 			lcp->data[2].ptr = (uchar_t *)p;
178*fcf3ce44SJohn Forte 		} else {
179*fcf3ce44SJohn Forte 			return (ISNS_RSP_INTERNAL_ERROR);
180*fcf3ce44SJohn Forte 		}
181*fcf3ce44SJohn Forte 	}
182*fcf3ce44SJohn Forte 
183*fcf3ce44SJohn Forte 	return (0);
184*fcf3ce44SJohn Forte }
185*fcf3ce44SJohn Forte 
186*fcf3ce44SJohn Forte static int
e2c(lookup_ctrl_t * lcp,isns_type_t type)187*fcf3ce44SJohn Forte e2c(
188*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
189*fcf3ce44SJohn Forte 	isns_type_t type
190*fcf3ce44SJohn Forte )
191*fcf3ce44SJohn Forte {
192*fcf3ce44SJohn Forte 	int ec = 0;
193*fcf3ce44SJohn Forte 
194*fcf3ce44SJohn Forte 	uint32_t uid = lcp->curr_uid; /* last child */
195*fcf3ce44SJohn Forte 	uint32_t num_of_child;
196*fcf3ce44SJohn Forte 	uint32_t *uids;
197*fcf3ce44SJohn Forte 
198*fcf3ce44SJohn Forte 	uint32_t tmp_uid = 0;
199*fcf3ce44SJohn Forte 
200*fcf3ce44SJohn Forte 	/* the first times of query */
201*fcf3ce44SJohn Forte 	if (uid == 0) {
202*fcf3ce44SJohn Forte 		lcp->data[1].ui = type;
203*fcf3ce44SJohn Forte 		ec = cache_lookup(lcp, NULL, cb_qry_child_uids);
204*fcf3ce44SJohn Forte 	}
205*fcf3ce44SJohn Forte 
206*fcf3ce44SJohn Forte 	num_of_child = lcp->id[2];
207*fcf3ce44SJohn Forte 	uids = (uint32_t *)lcp->data[2].ptr;
208*fcf3ce44SJohn Forte 
209*fcf3ce44SJohn Forte 	while (num_of_child > 0) {
210*fcf3ce44SJohn Forte 		if (*uids > uid) {
211*fcf3ce44SJohn Forte 			tmp_uid = *uids;
212*fcf3ce44SJohn Forte 			break;
213*fcf3ce44SJohn Forte 		}
214*fcf3ce44SJohn Forte 		uids ++;
215*fcf3ce44SJohn Forte 		num_of_child --;
216*fcf3ce44SJohn Forte 	}
217*fcf3ce44SJohn Forte 
218*fcf3ce44SJohn Forte 	uid = tmp_uid;
219*fcf3ce44SJohn Forte 
220*fcf3ce44SJohn Forte 	/* no more child, clean up memory */
221*fcf3ce44SJohn Forte 	if (uid == 0) {
222*fcf3ce44SJohn Forte 		lcp->data[1].ui = 0;
223*fcf3ce44SJohn Forte 		lcp->id[2] = 0;
224*fcf3ce44SJohn Forte 		lcp->data[2].ptr = NULL;
225*fcf3ce44SJohn Forte 
226*fcf3ce44SJohn Forte 		/* free up the memory */
227*fcf3ce44SJohn Forte 		free(uids);
228*fcf3ce44SJohn Forte 	}
229*fcf3ce44SJohn Forte 
230*fcf3ce44SJohn Forte 	/* save it for returning and querying next uid */
231*fcf3ce44SJohn Forte 	lcp->curr_uid = uid;
232*fcf3ce44SJohn Forte 
233*fcf3ce44SJohn Forte 	return (ec);
234*fcf3ce44SJohn Forte }
235*fcf3ce44SJohn Forte 
236*fcf3ce44SJohn Forte static int
qry_c2e(lookup_ctrl_t * lcp)237*fcf3ce44SJohn Forte qry_c2e(
238*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
239*fcf3ce44SJohn Forte )
240*fcf3ce44SJohn Forte {
241*fcf3ce44SJohn Forte 	uint32_t uid;
242*fcf3ce44SJohn Forte 
243*fcf3ce44SJohn Forte 	/* child object has only one parent */
244*fcf3ce44SJohn Forte 	if (lcp->curr_uid == 0) {
245*fcf3ce44SJohn Forte 		uid = (uint32_t)cache_lookup(lcp, NULL,
246*fcf3ce44SJohn Forte 		    cb_qry_parent_uid);
247*fcf3ce44SJohn Forte 	} else {
248*fcf3ce44SJohn Forte 		uid = 0;
249*fcf3ce44SJohn Forte 	}
250*fcf3ce44SJohn Forte 
251*fcf3ce44SJohn Forte 	/* save the result for returnning */
252*fcf3ce44SJohn Forte 	lcp->curr_uid = uid;
253*fcf3ce44SJohn Forte 
254*fcf3ce44SJohn Forte 	return (0);
255*fcf3ce44SJohn Forte }
256*fcf3ce44SJohn Forte 
257*fcf3ce44SJohn Forte static int
qry_ds2m(lookup_ctrl_t * lcp)258*fcf3ce44SJohn Forte qry_ds2m(
259*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
260*fcf3ce44SJohn Forte )
261*fcf3ce44SJohn Forte {
262*fcf3ce44SJohn Forte 	int ec = 0;
263*fcf3ce44SJohn Forte 
264*fcf3ce44SJohn Forte 	uint32_t uid = lcp->curr_uid; /* last member */
265*fcf3ce44SJohn Forte 	isns_type_t type = lcp->type;
266*fcf3ce44SJohn Forte 	uint32_t ds_id = lcp->data[0].ui;
267*fcf3ce44SJohn Forte 
268*fcf3ce44SJohn Forte 	uint32_t tmp_uid;
269*fcf3ce44SJohn Forte 
270*fcf3ce44SJohn Forte 	uint32_t n;
271*fcf3ce44SJohn Forte 	bmp_t *p;
272*fcf3ce44SJohn Forte 
273*fcf3ce44SJohn Forte 	/* the first times of query */
274*fcf3ce44SJohn Forte 	if (uid == 0) {
275*fcf3ce44SJohn Forte 		ec = (type == OBJ_DD) ?
276*fcf3ce44SJohn Forte 		    get_dd_matrix(ds_id, &p, &n) :
277*fcf3ce44SJohn Forte 		    get_dds_matrix(ds_id, &p, &n);
278*fcf3ce44SJohn Forte 		lcp->id[1] = n;
279*fcf3ce44SJohn Forte 		lcp->data[1].ptr = (uchar_t *)p;
280*fcf3ce44SJohn Forte 	} else {
281*fcf3ce44SJohn Forte 		n = lcp->id[1];
282*fcf3ce44SJohn Forte 		p = (bmp_t *)lcp->data[1].ptr;
283*fcf3ce44SJohn Forte 	}
284*fcf3ce44SJohn Forte 
285*fcf3ce44SJohn Forte 	FOR_EACH_MEMBER(p, n, tmp_uid, {
286*fcf3ce44SJohn Forte 		if (tmp_uid > uid) {
287*fcf3ce44SJohn Forte 			lcp->curr_uid = tmp_uid;
288*fcf3ce44SJohn Forte 			return (ec);
289*fcf3ce44SJohn Forte 		}
290*fcf3ce44SJohn Forte 	});
291*fcf3ce44SJohn Forte 
292*fcf3ce44SJohn Forte 	/* no more member, clean up memory */
293*fcf3ce44SJohn Forte 	lcp->id[1] = 0;
294*fcf3ce44SJohn Forte 	lcp->data[1].ptr = NULL;
295*fcf3ce44SJohn Forte 
296*fcf3ce44SJohn Forte 	/* free up the matrix */
297*fcf3ce44SJohn Forte 	free(p);
298*fcf3ce44SJohn Forte 
299*fcf3ce44SJohn Forte 	lcp->curr_uid = 0;
300*fcf3ce44SJohn Forte 
301*fcf3ce44SJohn Forte 	return (ec);
302*fcf3ce44SJohn Forte }
303*fcf3ce44SJohn Forte 
304*fcf3ce44SJohn Forte static int
qry_slf(lookup_ctrl_t * lcp)305*fcf3ce44SJohn Forte qry_slf(
306*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
307*fcf3ce44SJohn Forte )
308*fcf3ce44SJohn Forte {
309*fcf3ce44SJohn Forte 	uint32_t uid;
310*fcf3ce44SJohn Forte 
311*fcf3ce44SJohn Forte 	if (lcp->curr_uid == 0) {
312*fcf3ce44SJohn Forte 		uid = lcp->data[0].ui;
313*fcf3ce44SJohn Forte 	} else {
314*fcf3ce44SJohn Forte 		uid = 0;
315*fcf3ce44SJohn Forte 	}
316*fcf3ce44SJohn Forte 
317*fcf3ce44SJohn Forte 	lcp->curr_uid = uid;
318*fcf3ce44SJohn Forte 
319*fcf3ce44SJohn Forte 	return (0);
320*fcf3ce44SJohn Forte }
321*fcf3ce44SJohn Forte 
322*fcf3ce44SJohn Forte static int
qry_e2i(lookup_ctrl_t * lcp)323*fcf3ce44SJohn Forte qry_e2i(
324*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
325*fcf3ce44SJohn Forte )
326*fcf3ce44SJohn Forte {
327*fcf3ce44SJohn Forte 	return (e2c(lcp, OBJ_ISCSI));
328*fcf3ce44SJohn Forte }
329*fcf3ce44SJohn Forte 
330*fcf3ce44SJohn Forte static int
qry_e2p(lookup_ctrl_t * lcp)331*fcf3ce44SJohn Forte qry_e2p(
332*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
333*fcf3ce44SJohn Forte )
334*fcf3ce44SJohn Forte {
335*fcf3ce44SJohn Forte 	return (e2c(lcp, OBJ_PORTAL));
336*fcf3ce44SJohn Forte }
337*fcf3ce44SJohn Forte 
338*fcf3ce44SJohn Forte static int
qry_e2g(lookup_ctrl_t * lcp)339*fcf3ce44SJohn Forte qry_e2g(
340*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
341*fcf3ce44SJohn Forte )
342*fcf3ce44SJohn Forte {
343*fcf3ce44SJohn Forte 	uint32_t uid = lcp->curr_uid; /* last pg */
344*fcf3ce44SJohn Forte 
345*fcf3ce44SJohn Forte 	htab_t *htab = cache_get_htab(OBJ_PG);
346*fcf3ce44SJohn Forte 
347*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
348*fcf3ce44SJohn Forte 	uint32_t puid;
349*fcf3ce44SJohn Forte 
350*fcf3ce44SJohn Forte 	SET_UID_LCP(&lc, OBJ_PG, 0);
351*fcf3ce44SJohn Forte 
352*fcf3ce44SJohn Forte 	/* this is a shortcut */
353*fcf3ce44SJohn Forte 	FOR_EACH_ITEM(htab, uid, {
354*fcf3ce44SJohn Forte 		lc.data[0].ui = uid;
355*fcf3ce44SJohn Forte 		puid = (uint32_t)cache_lookup(&lc, NULL,
356*fcf3ce44SJohn Forte 		    cb_qry_parent_uid);
357*fcf3ce44SJohn Forte 		if (puid == lcp->data[0].ui) {
358*fcf3ce44SJohn Forte 			/* keep the current uid */
359*fcf3ce44SJohn Forte 			lcp->curr_uid = uid;
360*fcf3ce44SJohn Forte 			return (0);
361*fcf3ce44SJohn Forte 		}
362*fcf3ce44SJohn Forte 	});
363*fcf3ce44SJohn Forte 
364*fcf3ce44SJohn Forte 	lcp->curr_uid = 0;
365*fcf3ce44SJohn Forte 
366*fcf3ce44SJohn Forte 	return (0);
367*fcf3ce44SJohn Forte }
368*fcf3ce44SJohn Forte 
369*fcf3ce44SJohn Forte static int
qry_i2g(lookup_ctrl_t * lcp)370*fcf3ce44SJohn Forte qry_i2g(
371*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
372*fcf3ce44SJohn Forte )
373*fcf3ce44SJohn Forte {
374*fcf3ce44SJohn Forte 	int ec = 0;
375*fcf3ce44SJohn Forte 
376*fcf3ce44SJohn Forte 	uint32_t uid = lcp->curr_uid; /* last pg */
377*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
378*fcf3ce44SJohn Forte 
379*fcf3ce44SJohn Forte 	/* the first times of query */
380*fcf3ce44SJohn Forte 	if (uid == 0) {
381*fcf3ce44SJohn Forte 		lcp->id[1] = ISNS_ISCSI_NAME_ATTR_ID;
382*fcf3ce44SJohn Forte 		ec = cache_lookup(lcp, NULL, cb_clone_attrs);
383*fcf3ce44SJohn Forte 	}
384*fcf3ce44SJohn Forte 
385*fcf3ce44SJohn Forte 	if (lcp->data[1].ptr != NULL) {
386*fcf3ce44SJohn Forte 		/* pg lookup */
387*fcf3ce44SJohn Forte 		lc.curr_uid = uid;
388*fcf3ce44SJohn Forte 		lc.type = OBJ_PG;
389*fcf3ce44SJohn Forte 		lc.id[0] = ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID);
390*fcf3ce44SJohn Forte 		lc.op[0] = OP_STRING;
391*fcf3ce44SJohn Forte 		lc.data[0].ptr = lcp->data[1].ptr;
392*fcf3ce44SJohn Forte 		lc.op[1] = 0;
393*fcf3ce44SJohn Forte 
394*fcf3ce44SJohn Forte 		uid = is_obj_there(&lc);
395*fcf3ce44SJohn Forte 	} else {
396*fcf3ce44SJohn Forte 		uid = 0;
397*fcf3ce44SJohn Forte 	}
398*fcf3ce44SJohn Forte 
399*fcf3ce44SJohn Forte 	/* no more pg, update lcp with pg object */
400*fcf3ce44SJohn Forte 	if (uid == 0) {
401*fcf3ce44SJohn Forte 		lcp->id[1] = 0;
402*fcf3ce44SJohn Forte 
403*fcf3ce44SJohn Forte 		/* clean up the memory */
404*fcf3ce44SJohn Forte 		if (lcp->data[1].ptr != NULL) {
405*fcf3ce44SJohn Forte 			free(lcp->data[1].ptr);
406*fcf3ce44SJohn Forte 			/* reset it */
407*fcf3ce44SJohn Forte 			lcp->data[1].ptr = NULL;
408*fcf3ce44SJohn Forte 		}
409*fcf3ce44SJohn Forte 	}
410*fcf3ce44SJohn Forte 
411*fcf3ce44SJohn Forte 	/* save it for returning and querying next pg */
412*fcf3ce44SJohn Forte 	lcp->curr_uid = uid;
413*fcf3ce44SJohn Forte 
414*fcf3ce44SJohn Forte 	return (ec);
415*fcf3ce44SJohn Forte }
416*fcf3ce44SJohn Forte 
417*fcf3ce44SJohn Forte static int
qry_i2d(lookup_ctrl_t * lcp)418*fcf3ce44SJohn Forte qry_i2d(
419*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
420*fcf3ce44SJohn Forte )
421*fcf3ce44SJohn Forte {
422*fcf3ce44SJohn Forte 	uint32_t dd_id = lcp->curr_uid; /* last dd_id */
423*fcf3ce44SJohn Forte 	uint32_t uid = lcp->data[0].ui;
424*fcf3ce44SJohn Forte 
425*fcf3ce44SJohn Forte 	dd_id = get_dd_id(uid, dd_id);
426*fcf3ce44SJohn Forte 
427*fcf3ce44SJohn Forte 	/* save it for returning and getting next dd */
428*fcf3ce44SJohn Forte 	lcp->curr_uid = dd_id;
429*fcf3ce44SJohn Forte 
430*fcf3ce44SJohn Forte 	return (0);
431*fcf3ce44SJohn Forte }
432*fcf3ce44SJohn Forte 
433*fcf3ce44SJohn Forte static int
qry_p2g(lookup_ctrl_t * lcp)434*fcf3ce44SJohn Forte qry_p2g(
435*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
436*fcf3ce44SJohn Forte )
437*fcf3ce44SJohn Forte {
438*fcf3ce44SJohn Forte 	int ec = 0;
439*fcf3ce44SJohn Forte 
440*fcf3ce44SJohn Forte 	uint32_t uid = lcp->curr_uid; /* last pg */
441*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
442*fcf3ce44SJohn Forte 
443*fcf3ce44SJohn Forte 	/* the first time of query */
444*fcf3ce44SJohn Forte 	if (uid == 0) {
445*fcf3ce44SJohn Forte 		/* use 1&2 for the portal ip address & port */
446*fcf3ce44SJohn Forte 		lcp->id[1] = ISNS_PORTAL_IP_ADDR_ATTR_ID;
447*fcf3ce44SJohn Forte 		lcp->id[2] = ISNS_PORTAL_PORT_ATTR_ID;
448*fcf3ce44SJohn Forte 		ec = cache_lookup(lcp, NULL, cb_clone_attrs);
449*fcf3ce44SJohn Forte 	}
450*fcf3ce44SJohn Forte 
451*fcf3ce44SJohn Forte 	if (lcp->data[1].ip != NULL) {
452*fcf3ce44SJohn Forte 		/* pg lookup */
453*fcf3ce44SJohn Forte 		lc.curr_uid = uid;
454*fcf3ce44SJohn Forte 		lc.type = OBJ_PG;
455*fcf3ce44SJohn Forte 		lc.id[0] = ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID);
456*fcf3ce44SJohn Forte 		lc.op[0] = OP_MEMORY_IP6;
457*fcf3ce44SJohn Forte 		lc.data[0].ip = lcp->data[1].ip;
458*fcf3ce44SJohn Forte 		lc.id[1] = ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID);
459*fcf3ce44SJohn Forte 		lc.op[1] = OP_INTEGER;
460*fcf3ce44SJohn Forte 		lc.data[1].ui = lcp->data[2].ui;
461*fcf3ce44SJohn Forte 		lc.op[2] = 0;
462*fcf3ce44SJohn Forte 
463*fcf3ce44SJohn Forte 		uid = is_obj_there(&lc);
464*fcf3ce44SJohn Forte 	} else {
465*fcf3ce44SJohn Forte 		uid = 0;
466*fcf3ce44SJohn Forte 	}
467*fcf3ce44SJohn Forte 
468*fcf3ce44SJohn Forte 	/* no more pg, clean up memory */
469*fcf3ce44SJohn Forte 	if (uid == 0) {
470*fcf3ce44SJohn Forte 		lcp->id[1] = 0;
471*fcf3ce44SJohn Forte 		lcp->id[2] = 0;
472*fcf3ce44SJohn Forte 
473*fcf3ce44SJohn Forte 		/* clean up the memory */
474*fcf3ce44SJohn Forte 		if (lcp->data[1].ip != NULL) {
475*fcf3ce44SJohn Forte 			free(lcp->data[1].ip);
476*fcf3ce44SJohn Forte 			/* reset it */
477*fcf3ce44SJohn Forte 			lcp->data[1].ip = NULL;
478*fcf3ce44SJohn Forte 		}
479*fcf3ce44SJohn Forte 		lcp->data[2].ui = 0;
480*fcf3ce44SJohn Forte 	}
481*fcf3ce44SJohn Forte 
482*fcf3ce44SJohn Forte 	/* save it for returning and next query */
483*fcf3ce44SJohn Forte 	lcp->curr_uid = uid;
484*fcf3ce44SJohn Forte 
485*fcf3ce44SJohn Forte 	return (ec);
486*fcf3ce44SJohn Forte }
487*fcf3ce44SJohn Forte 
488*fcf3ce44SJohn Forte static int
qry_g2i(lookup_ctrl_t * lcp)489*fcf3ce44SJohn Forte qry_g2i(
490*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
491*fcf3ce44SJohn Forte )
492*fcf3ce44SJohn Forte {
493*fcf3ce44SJohn Forte 	int ec = 0;
494*fcf3ce44SJohn Forte 
495*fcf3ce44SJohn Forte 	uint32_t uid = lcp->curr_uid; /* last node */
496*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
497*fcf3ce44SJohn Forte 
498*fcf3ce44SJohn Forte 	/* the first time of query */
499*fcf3ce44SJohn Forte 	if (uid == 0) {
500*fcf3ce44SJohn Forte 		/* use slot 1 for the storage node name */
501*fcf3ce44SJohn Forte 		lcp->id[1] = ISNS_PG_ISCSI_NAME_ATTR_ID;
502*fcf3ce44SJohn Forte 		ec = cache_lookup(lcp, NULL, cb_clone_attrs);
503*fcf3ce44SJohn Forte 
504*fcf3ce44SJohn Forte 		if (lcp->data[1].ptr != NULL) {
505*fcf3ce44SJohn Forte 			/* iscsi node lookup */
506*fcf3ce44SJohn Forte 			lc.curr_uid = uid;
507*fcf3ce44SJohn Forte 			lc.type = OBJ_ISCSI;
508*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
509*fcf3ce44SJohn Forte 			lc.op[0] = OP_STRING;
510*fcf3ce44SJohn Forte 			lc.data[0].ptr = lcp->data[1].ptr;
511*fcf3ce44SJohn Forte 			lc.op[1] = 0;
512*fcf3ce44SJohn Forte 
513*fcf3ce44SJohn Forte 			uid = is_obj_there(&lc);
514*fcf3ce44SJohn Forte 
515*fcf3ce44SJohn Forte 			/* no longer need it, clean it up */
516*fcf3ce44SJohn Forte 			free(lcp->data[1].ptr);
517*fcf3ce44SJohn Forte 			lcp->data[1].ptr = NULL;
518*fcf3ce44SJohn Forte 		}
519*fcf3ce44SJohn Forte 		/* no longer need it, reset it */
520*fcf3ce44SJohn Forte 		lcp->id[1] = 0;
521*fcf3ce44SJohn Forte 	} else {
522*fcf3ce44SJohn Forte 		/* one pg has maximum number of one storage node */
523*fcf3ce44SJohn Forte 		uid = 0;
524*fcf3ce44SJohn Forte 	}
525*fcf3ce44SJohn Forte 
526*fcf3ce44SJohn Forte 	/* save it for returning and next query */
527*fcf3ce44SJohn Forte 	lcp->curr_uid = uid;
528*fcf3ce44SJohn Forte 
529*fcf3ce44SJohn Forte 	return (ec);
530*fcf3ce44SJohn Forte }
531*fcf3ce44SJohn Forte 
532*fcf3ce44SJohn Forte static int
qry_g2p(lookup_ctrl_t * lcp)533*fcf3ce44SJohn Forte qry_g2p(
534*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
535*fcf3ce44SJohn Forte )
536*fcf3ce44SJohn Forte {
537*fcf3ce44SJohn Forte 	int ec = 0;
538*fcf3ce44SJohn Forte 
539*fcf3ce44SJohn Forte 	uint32_t uid = lcp->curr_uid; /* last portal */
540*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
541*fcf3ce44SJohn Forte 
542*fcf3ce44SJohn Forte 	/* the first times of query */
543*fcf3ce44SJohn Forte 	if (uid == 0) {
544*fcf3ce44SJohn Forte 		/* use 1&2 for the portal ip addr and port */
545*fcf3ce44SJohn Forte 		lcp->id[1] = ISNS_PG_PORTAL_IP_ADDR_ATTR_ID;
546*fcf3ce44SJohn Forte 		lcp->id[2] = ISNS_PG_PORTAL_PORT_ATTR_ID;
547*fcf3ce44SJohn Forte 		ec = cache_lookup(lcp, NULL, cb_clone_attrs);
548*fcf3ce44SJohn Forte 
549*fcf3ce44SJohn Forte 		if (lcp->data[1].ip != NULL) {
550*fcf3ce44SJohn Forte 			/* portal lookup */
551*fcf3ce44SJohn Forte 			lc.curr_uid = uid;
552*fcf3ce44SJohn Forte 			lc.type = OBJ_PORTAL;
553*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_PORTAL(
554*fcf3ce44SJohn Forte 			    ISNS_PORTAL_IP_ADDR_ATTR_ID);
555*fcf3ce44SJohn Forte 			lc.op[0] = OP_MEMORY_IP6;
556*fcf3ce44SJohn Forte 			lc.data[0].ip = lcp->data[1].ip;
557*fcf3ce44SJohn Forte 			lc.id[1] = ATTR_INDEX_PORTAL(
558*fcf3ce44SJohn Forte 			    ISNS_PORTAL_PORT_ATTR_ID);
559*fcf3ce44SJohn Forte 			lc.op[1] = OP_INTEGER;
560*fcf3ce44SJohn Forte 			lc.data[1].ui = lcp->data[2].ui;
561*fcf3ce44SJohn Forte 			lc.op[2] = 0;
562*fcf3ce44SJohn Forte 
563*fcf3ce44SJohn Forte 			uid = is_obj_there(&lc);
564*fcf3ce44SJohn Forte 
565*fcf3ce44SJohn Forte 			/* no longer need it, reset it */
566*fcf3ce44SJohn Forte 			free(lcp->data[1].ip);
567*fcf3ce44SJohn Forte 			lcp->data[1].ip = NULL;
568*fcf3ce44SJohn Forte 		}
569*fcf3ce44SJohn Forte 		/* no longer need it, reset it */
570*fcf3ce44SJohn Forte 		lcp->id[1] = 0;
571*fcf3ce44SJohn Forte 		lcp->id[2] = 0;
572*fcf3ce44SJohn Forte 		lcp->data[2].ui = 0;
573*fcf3ce44SJohn Forte 	} else {
574*fcf3ce44SJohn Forte 		/* one pg has maximum number of one portal */
575*fcf3ce44SJohn Forte 		uid = 0;
576*fcf3ce44SJohn Forte 	}
577*fcf3ce44SJohn Forte 
578*fcf3ce44SJohn Forte 	/* save it for returning and next query */
579*fcf3ce44SJohn Forte 	lcp->curr_uid = uid;
580*fcf3ce44SJohn Forte 
581*fcf3ce44SJohn Forte 	return (ec);
582*fcf3ce44SJohn Forte }
583*fcf3ce44SJohn Forte 
584*fcf3ce44SJohn Forte static int
qry_d2s(lookup_ctrl_t * lcp)585*fcf3ce44SJohn Forte qry_d2s(
586*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
587*fcf3ce44SJohn Forte )
588*fcf3ce44SJohn Forte {
589*fcf3ce44SJohn Forte 	uint32_t dds_id = lcp->curr_uid; /* last dds */
590*fcf3ce44SJohn Forte 	uint32_t dd_id = lcp->data[0].ui;
591*fcf3ce44SJohn Forte 
592*fcf3ce44SJohn Forte 	dds_id = get_dds_id(dd_id, dds_id);
593*fcf3ce44SJohn Forte 
594*fcf3ce44SJohn Forte 	/* save it for returning and for getting next dds */
595*fcf3ce44SJohn Forte 	lcp->curr_uid = dds_id;
596*fcf3ce44SJohn Forte 
597*fcf3ce44SJohn Forte 	return (0);
598*fcf3ce44SJohn Forte }
599*fcf3ce44SJohn Forte 
600*fcf3ce44SJohn Forte int
validate_qry_key(isns_type_t type,isns_tlv_t * key,uint16_t key_len,isns_attr_t * attrs)601*fcf3ce44SJohn Forte validate_qry_key(
602*fcf3ce44SJohn Forte 	isns_type_t type,
603*fcf3ce44SJohn Forte 	isns_tlv_t *key,
604*fcf3ce44SJohn Forte 	uint16_t key_len,
605*fcf3ce44SJohn Forte 	isns_attr_t *attrs
606*fcf3ce44SJohn Forte )
607*fcf3ce44SJohn Forte {
608*fcf3ce44SJohn Forte 	int ec = 0;
609*fcf3ce44SJohn Forte 
610*fcf3ce44SJohn Forte 	uint32_t tag;
611*fcf3ce44SJohn Forte 	uint32_t min_tag, max_tag;
612*fcf3ce44SJohn Forte 
613*fcf3ce44SJohn Forte 	isns_attr_t *attr;
614*fcf3ce44SJohn Forte 
615*fcf3ce44SJohn Forte 	min_tag = TAG_RANGE[type][0];
616*fcf3ce44SJohn Forte 	max_tag = TAG_RANGE[type][2];
617*fcf3ce44SJohn Forte 
618*fcf3ce44SJohn Forte 	while (key_len != 0 && ec == 0) {
619*fcf3ce44SJohn Forte 		tag = key->attr_id;
620*fcf3ce44SJohn Forte 		if (tag < min_tag || tag > max_tag) {
621*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
622*fcf3ce44SJohn Forte 		} else if (key->attr_len > 0 && attrs != NULL) {
623*fcf3ce44SJohn Forte 			attr = &attrs[tag - min_tag]; /* ATTR_INDEX_xxx */
624*fcf3ce44SJohn Forte 			ec = extract_attr(attr, key, 0);
625*fcf3ce44SJohn Forte 			if (ec == ISNS_RSP_INVALID_REGIS) {
626*fcf3ce44SJohn Forte 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
627*fcf3ce44SJohn Forte 			}
628*fcf3ce44SJohn Forte 		}
629*fcf3ce44SJohn Forte 		NEXT_TLV(key, key_len);
630*fcf3ce44SJohn Forte 	}
631*fcf3ce44SJohn Forte 
632*fcf3ce44SJohn Forte 	return (ec);
633*fcf3ce44SJohn Forte }
634*fcf3ce44SJohn Forte 
635*fcf3ce44SJohn Forte static lookup_method_t
get_op_method(uint32_t tag)636*fcf3ce44SJohn Forte get_op_method(
637*fcf3ce44SJohn Forte 	uint32_t tag
638*fcf3ce44SJohn Forte )
639*fcf3ce44SJohn Forte {
640*fcf3ce44SJohn Forte 	lookup_method_t method = 0;
641*fcf3ce44SJohn Forte 
642*fcf3ce44SJohn Forte 	switch (tag) {
643*fcf3ce44SJohn Forte 	/* OP_STRING */
644*fcf3ce44SJohn Forte 	case ISNS_EID_ATTR_ID:
645*fcf3ce44SJohn Forte 	case ISNS_PORTAL_NAME_ATTR_ID:
646*fcf3ce44SJohn Forte 	case ISNS_ISCSI_ALIAS_ATTR_ID:
647*fcf3ce44SJohn Forte 	case ISNS_DD_SET_NAME_ATTR_ID:
648*fcf3ce44SJohn Forte 	case ISNS_DD_NAME_ATTR_ID:
649*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NAME_ATTR_ID:
650*fcf3ce44SJohn Forte 	case ISNS_PG_ISCSI_NAME_ATTR_ID:
651*fcf3ce44SJohn Forte 	case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
652*fcf3ce44SJohn Forte 		method = OP_STRING;
653*fcf3ce44SJohn Forte 		break;
654*fcf3ce44SJohn Forte 	/* OP_MEMORY_IP6 */
655*fcf3ce44SJohn Forte 	case ISNS_MGMT_IP_ADDR_ATTR_ID:
656*fcf3ce44SJohn Forte 	case ISNS_PORTAL_IP_ADDR_ATTR_ID:
657*fcf3ce44SJohn Forte 	case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
658*fcf3ce44SJohn Forte 		method = OP_MEMORY_IP6;
659*fcf3ce44SJohn Forte 		break;
660*fcf3ce44SJohn Forte 	/* OP_INTEGER */
661*fcf3ce44SJohn Forte 	case ISNS_ENTITY_PROTOCOL_ATTR_ID:
662*fcf3ce44SJohn Forte 	case ISNS_VERSION_RANGE_ATTR_ID:
663*fcf3ce44SJohn Forte 	case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
664*fcf3ce44SJohn Forte 	case ISNS_ENTITY_INDEX_ATTR_ID:
665*fcf3ce44SJohn Forte 	case ISNS_PORTAL_PORT_ATTR_ID:
666*fcf3ce44SJohn Forte 	case ISNS_ESI_INTERVAL_ATTR_ID:
667*fcf3ce44SJohn Forte 	case ISNS_ESI_PORT_ATTR_ID:
668*fcf3ce44SJohn Forte 	case ISNS_PORTAL_INDEX_ATTR_ID:
669*fcf3ce44SJohn Forte 	case ISNS_SCN_PORT_ATTR_ID:
670*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
671*fcf3ce44SJohn Forte 	case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
672*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
673*fcf3ce44SJohn Forte 	case ISNS_PG_PORTAL_PORT_ATTR_ID:
674*fcf3ce44SJohn Forte 	case ISNS_PG_TAG_ATTR_ID:
675*fcf3ce44SJohn Forte 	case ISNS_PG_INDEX_ATTR_ID:
676*fcf3ce44SJohn Forte 	case ISNS_DD_SET_ID_ATTR_ID:
677*fcf3ce44SJohn Forte 	case ISNS_DD_SET_STATUS_ATTR_ID:
678*fcf3ce44SJohn Forte 	case ISNS_DD_ID_ATTR_ID:
679*fcf3ce44SJohn Forte 	/* all other attrs */
680*fcf3ce44SJohn Forte 	default:
681*fcf3ce44SJohn Forte 		method = OP_INTEGER;
682*fcf3ce44SJohn Forte 		break;
683*fcf3ce44SJohn Forte 	}
684*fcf3ce44SJohn Forte 
685*fcf3ce44SJohn Forte 	return (method);
686*fcf3ce44SJohn Forte }
687*fcf3ce44SJohn Forte 
688*fcf3ce44SJohn Forte static int
cb_attrs_match(void * p1,void * p2)689*fcf3ce44SJohn Forte cb_attrs_match(
690*fcf3ce44SJohn Forte 	void *p1,
691*fcf3ce44SJohn Forte 	void *p2
692*fcf3ce44SJohn Forte )
693*fcf3ce44SJohn Forte {
694*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
695*fcf3ce44SJohn Forte 	isns_attr_t *attrs = (isns_attr_t *)
696*fcf3ce44SJohn Forte 	    ((lookup_ctrl_t *)p2)->data[1].ptr;
697*fcf3ce44SJohn Forte 
698*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
699*fcf3ce44SJohn Forte 	int match = 1; /* 0: not match, otherwise: match */
700*fcf3ce44SJohn Forte 
701*fcf3ce44SJohn Forte 	int i;
702*fcf3ce44SJohn Forte 
703*fcf3ce44SJohn Forte 	lc.op[1] = 0;
704*fcf3ce44SJohn Forte 
705*fcf3ce44SJohn Forte 	for (i = 0; match != 0 && i < NUM_OF_ATTRS[obj->type]; i++) {
706*fcf3ce44SJohn Forte 		if (attrs->tag != 0 && attrs->len > 0) {
707*fcf3ce44SJohn Forte 			lc.id[0] = i;
708*fcf3ce44SJohn Forte 			lc.op[0] = get_op_method(attrs->tag);
709*fcf3ce44SJohn Forte 			lc.data[0].ptr = attrs->value.ptr;
710*fcf3ce44SJohn Forte 			match = key_cmp(&lc, obj) == 0 ? 1 : 0;
711*fcf3ce44SJohn Forte 		}
712*fcf3ce44SJohn Forte 		attrs ++;
713*fcf3ce44SJohn Forte 	}
714*fcf3ce44SJohn Forte 
715*fcf3ce44SJohn Forte 	return (match);
716*fcf3ce44SJohn Forte }
717*fcf3ce44SJohn Forte 
718*fcf3ce44SJohn Forte static int
attrs_match(isns_type_t type,uint32_t uid,isns_attr_t * attrs)719*fcf3ce44SJohn Forte attrs_match(
720*fcf3ce44SJohn Forte 	isns_type_t type,
721*fcf3ce44SJohn Forte 	uint32_t uid,
722*fcf3ce44SJohn Forte 	isns_attr_t *attrs
723*fcf3ce44SJohn Forte )
724*fcf3ce44SJohn Forte {
725*fcf3ce44SJohn Forte 	int match; /* 0: not match, otherwise: match */
726*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
727*fcf3ce44SJohn Forte 
728*fcf3ce44SJohn Forte 	SET_UID_LCP(&lc, type, uid);
729*fcf3ce44SJohn Forte 
730*fcf3ce44SJohn Forte 	lc.data[1].ptr = (uchar_t *)attrs;
731*fcf3ce44SJohn Forte 
732*fcf3ce44SJohn Forte 	match = cache_lookup(&lc, NULL, cb_attrs_match);
733*fcf3ce44SJohn Forte 
734*fcf3ce44SJohn Forte 	return (match);
735*fcf3ce44SJohn Forte }
736*fcf3ce44SJohn Forte 
737*fcf3ce44SJohn Forte static int
insert_uid(uint32_t ** pp,uint32_t * np,uint32_t * sp,uint32_t uid)738*fcf3ce44SJohn Forte insert_uid(
739*fcf3ce44SJohn Forte 	uint32_t **pp,
740*fcf3ce44SJohn Forte 	uint32_t *np,
741*fcf3ce44SJohn Forte 	uint32_t *sp,
742*fcf3ce44SJohn Forte 	uint32_t uid
743*fcf3ce44SJohn Forte )
744*fcf3ce44SJohn Forte {
745*fcf3ce44SJohn Forte 	int ec = 0;
746*fcf3ce44SJohn Forte 
747*fcf3ce44SJohn Forte 	uint32_t *p = *pp;
748*fcf3ce44SJohn Forte 	uint32_t n = *np;
749*fcf3ce44SJohn Forte 	uint32_t s = *sp;
750*fcf3ce44SJohn Forte 
751*fcf3ce44SJohn Forte 	uint32_t u;
752*fcf3ce44SJohn Forte 	uint32_t *t;
753*fcf3ce44SJohn Forte 
754*fcf3ce44SJohn Forte 	/* check for duplication */
755*fcf3ce44SJohn Forte 	if (n > 0 && uid <= p[n - 1]) {
756*fcf3ce44SJohn Forte 		while (n-- > 0) {
757*fcf3ce44SJohn Forte 			if (p[n] == uid) {
758*fcf3ce44SJohn Forte 				return (0);
759*fcf3ce44SJohn Forte 			}
760*fcf3ce44SJohn Forte 		}
761*fcf3ce44SJohn Forte 		n = *np;
762*fcf3ce44SJohn Forte 		u = p[n - 1];
763*fcf3ce44SJohn Forte 		p[n - 1] = uid;
764*fcf3ce44SJohn Forte 		uid = u;
765*fcf3ce44SJohn Forte 	}
766*fcf3ce44SJohn Forte 
767*fcf3ce44SJohn Forte 
768*fcf3ce44SJohn Forte 	if (s == n) {
769*fcf3ce44SJohn Forte 		s = (s == 0) ? 8 : s * 2;
770*fcf3ce44SJohn Forte 		t = (uint32_t *)realloc(p, s * sizeof (uint32_t));
771*fcf3ce44SJohn Forte 		if (t != NULL) {
772*fcf3ce44SJohn Forte 			p = t;
773*fcf3ce44SJohn Forte 			*pp = p;
774*fcf3ce44SJohn Forte 			*sp = s;
775*fcf3ce44SJohn Forte 		} else {
776*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
777*fcf3ce44SJohn Forte 		}
778*fcf3ce44SJohn Forte 	}
779*fcf3ce44SJohn Forte 
780*fcf3ce44SJohn Forte 	if (ec == 0) {
781*fcf3ce44SJohn Forte 		p[n ++] = uid;
782*fcf3ce44SJohn Forte 		*np = n;
783*fcf3ce44SJohn Forte 	}
784*fcf3ce44SJohn Forte 
785*fcf3ce44SJohn Forte 	return (ec);
786*fcf3ce44SJohn Forte }
787*fcf3ce44SJohn Forte 
788*fcf3ce44SJohn Forte static int
qry_and_match(uint32_t ** obj_uids,uint32_t * num_of_objs,uint32_t * size,isns_type_t type,uint32_t src_uid,isns_type_t src_type,isns_attr_t * attrs)789*fcf3ce44SJohn Forte qry_and_match(
790*fcf3ce44SJohn Forte 	uint32_t **obj_uids,
791*fcf3ce44SJohn Forte 	uint32_t *num_of_objs,
792*fcf3ce44SJohn Forte 	uint32_t *size,
793*fcf3ce44SJohn Forte 	isns_type_t type,
794*fcf3ce44SJohn Forte 	uint32_t src_uid,
795*fcf3ce44SJohn Forte 	isns_type_t src_type,
796*fcf3ce44SJohn Forte 	isns_attr_t *attrs
797*fcf3ce44SJohn Forte )
798*fcf3ce44SJohn Forte {
799*fcf3ce44SJohn Forte 	int ec = 0;
800*fcf3ce44SJohn Forte 
801*fcf3ce44SJohn Forte 	lookup_ctrl_t lc = { 0 }; /* !!! need to be empty */
802*fcf3ce44SJohn Forte 	uint32_t uid;
803*fcf3ce44SJohn Forte 
804*fcf3ce44SJohn Forte 	const adjvex_t *vex;
805*fcf3ce44SJohn Forte 
806*fcf3ce44SJohn Forte 	/* circular list */
807*fcf3ce44SJohn Forte 	uint32_t *p[2], n[2], s[2];
808*fcf3ce44SJohn Forte 	int i, j;
809*fcf3ce44SJohn Forte 
810*fcf3ce44SJohn Forte 	uint32_t *p1, n1;
811*fcf3ce44SJohn Forte 	uint32_t *p2, n2, s2;
812*fcf3ce44SJohn Forte 	isns_type_t t;
813*fcf3ce44SJohn Forte 
814*fcf3ce44SJohn Forte 	/* initialize the circular list */
815*fcf3ce44SJohn Forte 	i = 0;
816*fcf3ce44SJohn Forte 	j = 1;
817*fcf3ce44SJohn Forte 
818*fcf3ce44SJohn Forte 	p[i] = *obj_uids;
819*fcf3ce44SJohn Forte 	n[i] = *num_of_objs;
820*fcf3ce44SJohn Forte 	s[i] = *size;
821*fcf3ce44SJohn Forte 
822*fcf3ce44SJohn Forte 	p[j] = malloc(8 * sizeof (uint32_t));
823*fcf3ce44SJohn Forte 	p[j][0] = src_uid;
824*fcf3ce44SJohn Forte 	n[j] = 1;
825*fcf3ce44SJohn Forte 	s[j] = 8;
826*fcf3ce44SJohn Forte 
827*fcf3ce44SJohn Forte 	/* initial object type of being queried */
828*fcf3ce44SJohn Forte 	t = src_type;
829*fcf3ce44SJohn Forte 
830*fcf3ce44SJohn Forte 	vex = qry_puzzle[src_type][type];
831*fcf3ce44SJohn Forte 
832*fcf3ce44SJohn Forte 	do {
833*fcf3ce44SJohn Forte 		/* shift one on the circular list */
834*fcf3ce44SJohn Forte 		i = (i + 1) & 1;
835*fcf3ce44SJohn Forte 		j = (j + 1) & 1;
836*fcf3ce44SJohn Forte 
837*fcf3ce44SJohn Forte 		p1 = p[i]; n1 = n[i];
838*fcf3ce44SJohn Forte 		p2 = p[j]; n2 = n[j]; s2 = s[j];
839*fcf3ce44SJohn Forte 
840*fcf3ce44SJohn Forte 		/* prepare lookup control */
841*fcf3ce44SJohn Forte 		lc.type = t;
842*fcf3ce44SJohn Forte 		lc.id[0] = UID_ATTR_INDEX[t];
843*fcf3ce44SJohn Forte 		lc.op[0] = OP_INTEGER;
844*fcf3ce44SJohn Forte 
845*fcf3ce44SJohn Forte 		/* result object type */
846*fcf3ce44SJohn Forte 		t = vex->t;
847*fcf3ce44SJohn Forte 
848*fcf3ce44SJohn Forte 		FOR_EACH_OBJS(p1, n1, uid, {
849*fcf3ce44SJohn Forte 			/* start query */
850*fcf3ce44SJohn Forte 			lc.data[0].ui = uid;
851*fcf3ce44SJohn Forte 			ec = vex->f(&lc);
852*fcf3ce44SJohn Forte 			uid = lc.curr_uid;
853*fcf3ce44SJohn Forte 			while (ec == 0 && uid != 0) {
854*fcf3ce44SJohn Forte 				if (attrs == NULL ||
855*fcf3ce44SJohn Forte 				    attrs_match(type, uid, attrs) != 0) {
856*fcf3ce44SJohn Forte 					ec = insert_uid(&p2, &n2, &s2, uid);
857*fcf3ce44SJohn Forte 				}
858*fcf3ce44SJohn Forte 				if (ec == 0) {
859*fcf3ce44SJohn Forte 					ec = vex->f(&lc);
860*fcf3ce44SJohn Forte 					uid = lc.curr_uid;
861*fcf3ce44SJohn Forte 				} else {
862*fcf3ce44SJohn Forte 					n1 = n2 = 0; /* force break */
863*fcf3ce44SJohn Forte 				}
864*fcf3ce44SJohn Forte 			}
865*fcf3ce44SJohn Forte 		});
866*fcf3ce44SJohn Forte 		if (ec == 0) {
867*fcf3ce44SJohn Forte 			vex = vex->v;
868*fcf3ce44SJohn Forte 		} else {
869*fcf3ce44SJohn Forte 			vex = NULL; /* force break */
870*fcf3ce44SJohn Forte 		}
871*fcf3ce44SJohn Forte 		/* push back */
872*fcf3ce44SJohn Forte 		p[j] = p2; n[j] = n2; s[j] = s2;
873*fcf3ce44SJohn Forte 		/* reset the number of objects */
874*fcf3ce44SJohn Forte 		n[i] = 0;
875*fcf3ce44SJohn Forte 	} while (vex != NULL);
876*fcf3ce44SJohn Forte 
877*fcf3ce44SJohn Forte 	/* clean up the memory */
878*fcf3ce44SJohn Forte 	free(p1);
879*fcf3ce44SJohn Forte 	if (ec != 0) {
880*fcf3ce44SJohn Forte 		free(p2);
881*fcf3ce44SJohn Forte 		p2 = NULL;
882*fcf3ce44SJohn Forte 		n2 = 0;
883*fcf3ce44SJohn Forte 		s2 = 0;
884*fcf3ce44SJohn Forte 	}
885*fcf3ce44SJohn Forte 
886*fcf3ce44SJohn Forte 	*obj_uids = p2;
887*fcf3ce44SJohn Forte 	*num_of_objs = n2;
888*fcf3ce44SJohn Forte 	*size = s2;
889*fcf3ce44SJohn Forte 
890*fcf3ce44SJohn Forte 	return (ec);
891*fcf3ce44SJohn Forte }
892*fcf3ce44SJohn Forte 
893*fcf3ce44SJohn Forte int
get_qry_keys(bmp_t * nodes_bmp,uint32_t num_of_nodes,isns_type_t * type,isns_tlv_t * key,uint16_t key_len,uint32_t ** obj_uids,uint32_t * num_of_objs)894*fcf3ce44SJohn Forte get_qry_keys(
895*fcf3ce44SJohn Forte 	bmp_t *nodes_bmp,
896*fcf3ce44SJohn Forte 	uint32_t num_of_nodes,
897*fcf3ce44SJohn Forte 	isns_type_t *type,
898*fcf3ce44SJohn Forte 	isns_tlv_t *key,
899*fcf3ce44SJohn Forte 	uint16_t key_len,
900*fcf3ce44SJohn Forte 	uint32_t **obj_uids,
901*fcf3ce44SJohn Forte 	uint32_t *num_of_objs
902*fcf3ce44SJohn Forte )
903*fcf3ce44SJohn Forte {
904*fcf3ce44SJohn Forte 	int ec = 0;
905*fcf3ce44SJohn Forte 	union {
906*fcf3ce44SJohn Forte 		isns_obj_t o;
907*fcf3ce44SJohn Forte 		isns_entity_t e;
908*fcf3ce44SJohn Forte 		isns_iscsi_t i;
909*fcf3ce44SJohn Forte 		isns_portal_t p;
910*fcf3ce44SJohn Forte 		isns_pg_t g;
911*fcf3ce44SJohn Forte 		isns_dd_t d;
912*fcf3ce44SJohn Forte 		isns_dds_t s;
913*fcf3ce44SJohn Forte 	} an_obj = { 0 };
914*fcf3ce44SJohn Forte 	isns_attr_t *attrs;
915*fcf3ce44SJohn Forte 
916*fcf3ce44SJohn Forte 	htab_t *htab;
917*fcf3ce44SJohn Forte 	uint32_t node_uid;
918*fcf3ce44SJohn Forte 
919*fcf3ce44SJohn Forte 	uint32_t size;
920*fcf3ce44SJohn Forte 
921*fcf3ce44SJohn Forte 	*obj_uids = NULL;
922*fcf3ce44SJohn Forte 	*num_of_objs = 0;
923*fcf3ce44SJohn Forte 	size = 0;
924*fcf3ce44SJohn Forte 
925*fcf3ce44SJohn Forte 	/* get the object type identified by the key */
926*fcf3ce44SJohn Forte 	*type = TLV2TYPE(key);
927*fcf3ce44SJohn Forte 	if (*type == 0) {
928*fcf3ce44SJohn Forte 		return (ISNS_RSP_INVALID_QRY);
929*fcf3ce44SJohn Forte 	}
930*fcf3ce44SJohn Forte 
931*fcf3ce44SJohn Forte 	attrs = &an_obj.o.attrs[0];
932*fcf3ce44SJohn Forte 	/* validate the Message Key */
933*fcf3ce44SJohn Forte 	ec = validate_qry_key(*type, key, key_len, attrs);
934*fcf3ce44SJohn Forte 	if (ec != 0) {
935*fcf3ce44SJohn Forte 		return (ec);
936*fcf3ce44SJohn Forte 	}
937*fcf3ce44SJohn Forte 
938*fcf3ce44SJohn Forte 	if (nodes_bmp != NULL) {
939*fcf3ce44SJohn Forte 		FOR_EACH_MEMBER(nodes_bmp, num_of_nodes, node_uid, {
940*fcf3ce44SJohn Forte 			ec = qry_and_match(
941*fcf3ce44SJohn Forte 			    obj_uids, num_of_objs, &size, *type,
942*fcf3ce44SJohn Forte 			    node_uid, OBJ_ISCSI, attrs);
943*fcf3ce44SJohn Forte 			if (ec != 0) {
944*fcf3ce44SJohn Forte 				return (ec);
945*fcf3ce44SJohn Forte 			}
946*fcf3ce44SJohn Forte 		});
947*fcf3ce44SJohn Forte 	} else {
948*fcf3ce44SJohn Forte 		node_uid = 0;
949*fcf3ce44SJohn Forte 		htab = cache_get_htab(OBJ_ISCSI);
950*fcf3ce44SJohn Forte 		FOR_EACH_ITEM(htab, node_uid, {
951*fcf3ce44SJohn Forte 			ec = qry_and_match(
952*fcf3ce44SJohn Forte 			    obj_uids, num_of_objs, &size, *type,
953*fcf3ce44SJohn Forte 			    node_uid, OBJ_ISCSI, attrs);
954*fcf3ce44SJohn Forte 			if (ec != 0) {
955*fcf3ce44SJohn Forte 				return (ec);
956*fcf3ce44SJohn Forte 			}
957*fcf3ce44SJohn Forte 		});
958*fcf3ce44SJohn Forte 	}
959*fcf3ce44SJohn Forte 
960*fcf3ce44SJohn Forte 	return (ec);
961*fcf3ce44SJohn Forte }
962*fcf3ce44SJohn Forte 
963*fcf3ce44SJohn Forte int
get_qry_ops(uint32_t uid,isns_type_t src_type,isns_type_t op_type,uint32_t ** op_uids,uint32_t * num_of_ops,uint32_t * size)964*fcf3ce44SJohn Forte get_qry_ops(
965*fcf3ce44SJohn Forte 	uint32_t uid,
966*fcf3ce44SJohn Forte 	isns_type_t src_type,
967*fcf3ce44SJohn Forte 	isns_type_t op_type,
968*fcf3ce44SJohn Forte 	uint32_t **op_uids,
969*fcf3ce44SJohn Forte 	uint32_t *num_of_ops,
970*fcf3ce44SJohn Forte 	uint32_t *size
971*fcf3ce44SJohn Forte )
972*fcf3ce44SJohn Forte {
973*fcf3ce44SJohn Forte 	int ec = 0;
974*fcf3ce44SJohn Forte 
975*fcf3ce44SJohn Forte 	*num_of_ops = 0;
976*fcf3ce44SJohn Forte 
977*fcf3ce44SJohn Forte 	ec = qry_and_match(
978*fcf3ce44SJohn Forte 	    op_uids, num_of_ops, size, op_type,
979*fcf3ce44SJohn Forte 	    uid, src_type, NULL);
980*fcf3ce44SJohn Forte 
981*fcf3ce44SJohn Forte 	return (ec);
982*fcf3ce44SJohn Forte }
983*fcf3ce44SJohn Forte 
984*fcf3ce44SJohn Forte int
get_qry_ops2(uint32_t * nodes_bmp,uint32_t num_of_nodes,isns_type_t op_type,uint32_t ** op_uids,uint32_t * num_of_ops,uint32_t * size)985*fcf3ce44SJohn Forte get_qry_ops2(
986*fcf3ce44SJohn Forte 	uint32_t *nodes_bmp,
987*fcf3ce44SJohn Forte 	uint32_t num_of_nodes,
988*fcf3ce44SJohn Forte 	isns_type_t op_type,
989*fcf3ce44SJohn Forte 	uint32_t **op_uids,
990*fcf3ce44SJohn Forte 	uint32_t *num_of_ops,
991*fcf3ce44SJohn Forte 	uint32_t *size
992*fcf3ce44SJohn Forte )
993*fcf3ce44SJohn Forte {
994*fcf3ce44SJohn Forte 	int ec = 0;
995*fcf3ce44SJohn Forte 
996*fcf3ce44SJohn Forte 	uint32_t node_uid;
997*fcf3ce44SJohn Forte 
998*fcf3ce44SJohn Forte 	htab_t *htab;
999*fcf3ce44SJohn Forte 
1000*fcf3ce44SJohn Forte 	*num_of_ops = 0;
1001*fcf3ce44SJohn Forte 
1002*fcf3ce44SJohn Forte 	if (nodes_bmp != NULL) {
1003*fcf3ce44SJohn Forte 		FOR_EACH_MEMBER(nodes_bmp, num_of_nodes, node_uid, {
1004*fcf3ce44SJohn Forte 			ec = qry_and_match(
1005*fcf3ce44SJohn Forte 			    op_uids, num_of_ops, size, op_type,
1006*fcf3ce44SJohn Forte 			    node_uid, OBJ_ISCSI, NULL);
1007*fcf3ce44SJohn Forte 			if (ec != 0) {
1008*fcf3ce44SJohn Forte 				return (ec);
1009*fcf3ce44SJohn Forte 			}
1010*fcf3ce44SJohn Forte 		});
1011*fcf3ce44SJohn Forte 	} else {
1012*fcf3ce44SJohn Forte 		node_uid = 0;
1013*fcf3ce44SJohn Forte 		htab = cache_get_htab(OBJ_ISCSI);
1014*fcf3ce44SJohn Forte 		FOR_EACH_ITEM(htab, node_uid, {
1015*fcf3ce44SJohn Forte 			ec = qry_and_match(
1016*fcf3ce44SJohn Forte 			    op_uids, num_of_ops, size, op_type,
1017*fcf3ce44SJohn Forte 			    node_uid, OBJ_ISCSI, NULL);
1018*fcf3ce44SJohn Forte 			if (ec != 0) {
1019*fcf3ce44SJohn Forte 				return (ec);
1020*fcf3ce44SJohn Forte 			}
1021*fcf3ce44SJohn Forte 		});
1022*fcf3ce44SJohn Forte 	}
1023*fcf3ce44SJohn Forte 
1024*fcf3ce44SJohn Forte 	return (ec);
1025*fcf3ce44SJohn Forte }
1026*fcf3ce44SJohn Forte 
1027*fcf3ce44SJohn Forte uint32_t
get_next_obj(isns_tlv_t * tlv,uint32_t tlv_len,isns_type_t type,uint32_t * uids,uint32_t num)1028*fcf3ce44SJohn Forte get_next_obj(
1029*fcf3ce44SJohn Forte 	isns_tlv_t *tlv,
1030*fcf3ce44SJohn Forte 	uint32_t tlv_len,
1031*fcf3ce44SJohn Forte 	isns_type_t type,
1032*fcf3ce44SJohn Forte 	uint32_t *uids,
1033*fcf3ce44SJohn Forte 	uint32_t num
1034*fcf3ce44SJohn Forte )
1035*fcf3ce44SJohn Forte {
1036*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
1037*fcf3ce44SJohn Forte 
1038*fcf3ce44SJohn Forte 	uint32_t tag;
1039*fcf3ce44SJohn Forte 	uint8_t *value;
1040*fcf3ce44SJohn Forte 
1041*fcf3ce44SJohn Forte 	uint32_t old = 0;
1042*fcf3ce44SJohn Forte 	uint32_t min = 0;
1043*fcf3ce44SJohn Forte 	uint32_t uid, diff;
1044*fcf3ce44SJohn Forte 	uint32_t pre_diff = 0xFFFFFFFF;
1045*fcf3ce44SJohn Forte 
1046*fcf3ce44SJohn Forte 	lc.curr_uid = 0;
1047*fcf3ce44SJohn Forte 	lc.type = type;
1048*fcf3ce44SJohn Forte 	lc.op[1] = 0;
1049*fcf3ce44SJohn Forte 	lc.op[2] = 0;
1050*fcf3ce44SJohn Forte 
1051*fcf3ce44SJohn Forte 	if (tlv_len > 8) {
1052*fcf3ce44SJohn Forte 		tag = tlv->attr_id;
1053*fcf3ce44SJohn Forte 		value = tlv->attr_value;
1054*fcf3ce44SJohn Forte 		switch (tag) {
1055*fcf3ce44SJohn Forte 		case ISNS_EID_ATTR_ID:
1056*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID);
1057*fcf3ce44SJohn Forte 			lc.op[0] = OP_STRING;
1058*fcf3ce44SJohn Forte 			lc.data[0].ptr = (uchar_t *)value;
1059*fcf3ce44SJohn Forte 			break;
1060*fcf3ce44SJohn Forte 		case ISNS_ISCSI_NAME_ATTR_ID:
1061*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
1062*fcf3ce44SJohn Forte 			lc.op[0] = OP_STRING;
1063*fcf3ce44SJohn Forte 			lc.data[0].ptr = (uchar_t *)value;
1064*fcf3ce44SJohn Forte 			break;
1065*fcf3ce44SJohn Forte 		case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
1066*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_ISCSI(
1067*fcf3ce44SJohn Forte 			    ISNS_ISCSI_NODE_INDEX_ATTR_ID);
1068*fcf3ce44SJohn Forte 			lc.op[0] = OP_INTEGER;
1069*fcf3ce44SJohn Forte 			lc.data[0].ui = ntohl(*(uint32_t *)value);
1070*fcf3ce44SJohn Forte 			break;
1071*fcf3ce44SJohn Forte 		case ISNS_PORTAL_IP_ADDR_ATTR_ID:
1072*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_PORTAL(
1073*fcf3ce44SJohn Forte 			    ISNS_PORTAL_IP_ADDR_ATTR_ID);
1074*fcf3ce44SJohn Forte 			lc.op[0] = OP_MEMORY_IP6;
1075*fcf3ce44SJohn Forte 			lc.data[0].ip = (in6_addr_t *)value;
1076*fcf3ce44SJohn Forte 			NEXT_TLV(tlv, tlv_len);
1077*fcf3ce44SJohn Forte 			if (tlv_len > 8 &&
1078*fcf3ce44SJohn Forte 			    ((tag = tlv->attr_id) ==
1079*fcf3ce44SJohn Forte 			    ISNS_PORTAL_PORT_ATTR_ID)) {
1080*fcf3ce44SJohn Forte 				value = tlv->attr_value;
1081*fcf3ce44SJohn Forte 				lc.id[1] = ATTR_INDEX_PORTAL(
1082*fcf3ce44SJohn Forte 				    ISNS_PORTAL_PORT_ATTR_ID);
1083*fcf3ce44SJohn Forte 				lc.op[1] = OP_INTEGER;
1084*fcf3ce44SJohn Forte 				lc.data[1].ui = ntohl(*(uint32_t *)value);
1085*fcf3ce44SJohn Forte 			} else {
1086*fcf3ce44SJohn Forte 				return (0);
1087*fcf3ce44SJohn Forte 			}
1088*fcf3ce44SJohn Forte 			break;
1089*fcf3ce44SJohn Forte 		case ISNS_PORTAL_INDEX_ATTR_ID:
1090*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_PORTAL(ISNS_PORTAL_INDEX_ATTR_ID);
1091*fcf3ce44SJohn Forte 			lc.op[0] = OP_INTEGER;
1092*fcf3ce44SJohn Forte 			lc.data[0].ui = ntohl(*(uint32_t *)value);
1093*fcf3ce44SJohn Forte 			break;
1094*fcf3ce44SJohn Forte 		case ISNS_PG_INDEX_ATTR_ID:
1095*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_PG(ISNS_PG_INDEX_ATTR_ID);
1096*fcf3ce44SJohn Forte 			lc.op[0] = OP_INTEGER;
1097*fcf3ce44SJohn Forte 			lc.data[0].ui = ntohl(*(uint32_t *)value);
1098*fcf3ce44SJohn Forte 			break;
1099*fcf3ce44SJohn Forte 		default:
1100*fcf3ce44SJohn Forte 			return (0);
1101*fcf3ce44SJohn Forte 		}
1102*fcf3ce44SJohn Forte 
1103*fcf3ce44SJohn Forte 		old = is_obj_there(&lc);
1104*fcf3ce44SJohn Forte 		if (old == 0) {
1105*fcf3ce44SJohn Forte 			return (0);
1106*fcf3ce44SJohn Forte 		}
1107*fcf3ce44SJohn Forte 	}
1108*fcf3ce44SJohn Forte 
1109*fcf3ce44SJohn Forte 	while (num > 0) {
1110*fcf3ce44SJohn Forte 		uid = uids[-- num];
1111*fcf3ce44SJohn Forte 		if (uid > old) {
1112*fcf3ce44SJohn Forte 			diff = uid - old;
1113*fcf3ce44SJohn Forte 			if (diff < pre_diff) {
1114*fcf3ce44SJohn Forte 				min = uid;
1115*fcf3ce44SJohn Forte 				pre_diff = diff;
1116*fcf3ce44SJohn Forte 			}
1117*fcf3ce44SJohn Forte 		}
1118*fcf3ce44SJohn Forte 	}
1119*fcf3ce44SJohn Forte 
1120*fcf3ce44SJohn Forte 	return (min);
1121*fcf3ce44SJohn Forte }
1122*fcf3ce44SJohn Forte 
1123*fcf3ce44SJohn Forte static int
cb_qry_rsp(void * p1,void * p2)1124*fcf3ce44SJohn Forte cb_qry_rsp(
1125*fcf3ce44SJohn Forte 	void *p1,
1126*fcf3ce44SJohn Forte 	void *p2
1127*fcf3ce44SJohn Forte )
1128*fcf3ce44SJohn Forte {
1129*fcf3ce44SJohn Forte 	int ec = 0;
1130*fcf3ce44SJohn Forte 
1131*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
1132*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
1133*fcf3ce44SJohn Forte 
1134*fcf3ce44SJohn Forte 	uint16_t tlv_len = lcp->id[1];
1135*fcf3ce44SJohn Forte 	isns_tlv_t *tlv = (isns_tlv_t *)lcp->data[1].ptr;
1136*fcf3ce44SJohn Forte 	conn_arg_t *conn = (conn_arg_t *)lcp->data[2].ptr;
1137*fcf3ce44SJohn Forte 
1138*fcf3ce44SJohn Forte 	isns_type_t type = obj->type;
1139*fcf3ce44SJohn Forte 	uint32_t min_tag = TAG_RANGE[type][0];
1140*fcf3ce44SJohn Forte 	uint32_t mid_tag = TAG_RANGE[type][1];
1141*fcf3ce44SJohn Forte 	uint32_t max_tag = TAG_RANGE[type][2];
1142*fcf3ce44SJohn Forte 
1143*fcf3ce44SJohn Forte 	isns_attr_t *attr;
1144*fcf3ce44SJohn Forte 	uint32_t tag;
1145*fcf3ce44SJohn Forte 	uint32_t id;
1146*fcf3ce44SJohn Forte 	uint32_t len;
1147*fcf3ce44SJohn Forte 	void *value;
1148*fcf3ce44SJohn Forte 
1149*fcf3ce44SJohn Forte 	isns_pdu_t *rsp = conn->out_packet.pdu;
1150*fcf3ce44SJohn Forte 	size_t pl = conn->out_packet.pl;
1151*fcf3ce44SJohn Forte 	size_t sz = conn->out_packet.sz;
1152*fcf3ce44SJohn Forte 
1153*fcf3ce44SJohn Forte 	do {
1154*fcf3ce44SJohn Forte 		if (tlv->attr_len == 0) {
1155*fcf3ce44SJohn Forte 			tag = tlv->attr_id;
1156*fcf3ce44SJohn Forte 			if (tag <= mid_tag) {
1157*fcf3ce44SJohn Forte 				id = ATTR_INDEX(tag, type);
1158*fcf3ce44SJohn Forte 				attr = &obj->attrs[id];
1159*fcf3ce44SJohn Forte 				len = attr->len;
1160*fcf3ce44SJohn Forte 				value = (void *)attr->value.ptr;
1161*fcf3ce44SJohn Forte 				ec = pdu_add_tlv(&rsp, &pl, &sz,
1162*fcf3ce44SJohn Forte 				    tag, len, value, 0);
1163*fcf3ce44SJohn Forte 			}
1164*fcf3ce44SJohn Forte 		}
1165*fcf3ce44SJohn Forte 		NEXT_TLV(tlv, tlv_len);
1166*fcf3ce44SJohn Forte 	} while (ec == 0 &&
1167*fcf3ce44SJohn Forte 	    tlv_len >= 8 &&
1168*fcf3ce44SJohn Forte 	    tlv->attr_id >= min_tag &&
1169*fcf3ce44SJohn Forte 	    tlv->attr_id <= max_tag);
1170*fcf3ce44SJohn Forte 
1171*fcf3ce44SJohn Forte 	conn->out_packet.pdu = rsp;
1172*fcf3ce44SJohn Forte 	conn->out_packet.pl = pl;
1173*fcf3ce44SJohn Forte 	conn->out_packet.sz = sz;
1174*fcf3ce44SJohn Forte 
1175*fcf3ce44SJohn Forte 	return (ec);
1176*fcf3ce44SJohn Forte }
1177*fcf3ce44SJohn Forte 
1178*fcf3ce44SJohn Forte int
get_qry_attrs(uint32_t uid,isns_type_t type,isns_tlv_t * tlv,uint16_t tlv_len,conn_arg_t * conn)1179*fcf3ce44SJohn Forte get_qry_attrs(
1180*fcf3ce44SJohn Forte 	uint32_t uid,
1181*fcf3ce44SJohn Forte 	isns_type_t type,
1182*fcf3ce44SJohn Forte 	isns_tlv_t *tlv,
1183*fcf3ce44SJohn Forte 	uint16_t tlv_len,
1184*fcf3ce44SJohn Forte 	conn_arg_t *conn
1185*fcf3ce44SJohn Forte )
1186*fcf3ce44SJohn Forte {
1187*fcf3ce44SJohn Forte 	int ec = 0;
1188*fcf3ce44SJohn Forte 
1189*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
1190*fcf3ce44SJohn Forte 
1191*fcf3ce44SJohn Forte 	SET_UID_LCP(&lc, type, uid);
1192*fcf3ce44SJohn Forte 
1193*fcf3ce44SJohn Forte 	lc.id[1] = tlv_len;
1194*fcf3ce44SJohn Forte 	lc.data[1].ptr = (uchar_t *)tlv;
1195*fcf3ce44SJohn Forte 	lc.data[2].ptr = (uchar_t *)conn;
1196*fcf3ce44SJohn Forte 
1197*fcf3ce44SJohn Forte 	ec = cache_lookup(&lc, NULL, cb_qry_rsp);
1198*fcf3ce44SJohn Forte 
1199*fcf3ce44SJohn Forte 	return (ec);
1200*fcf3ce44SJohn Forte }
1201*fcf3ce44SJohn Forte 
1202*fcf3ce44SJohn Forte int
get_qry_attrs1(uint32_t uid,isns_type_t type,isns_tlv_t * tlv,uint16_t tlv_len,conn_arg_t * conn)1203*fcf3ce44SJohn Forte get_qry_attrs1(
1204*fcf3ce44SJohn Forte 	uint32_t uid,
1205*fcf3ce44SJohn Forte 	isns_type_t type,
1206*fcf3ce44SJohn Forte 	isns_tlv_t *tlv,
1207*fcf3ce44SJohn Forte 	uint16_t tlv_len,
1208*fcf3ce44SJohn Forte 	conn_arg_t *conn
1209*fcf3ce44SJohn Forte )
1210*fcf3ce44SJohn Forte {
1211*fcf3ce44SJohn Forte 	isns_tlv_t *tmp = tlv;
1212*fcf3ce44SJohn Forte 	uint32_t tmp_len = tlv_len;
1213*fcf3ce44SJohn Forte 
1214*fcf3ce44SJohn Forte 	/* clear the length of all of tlv */
1215*fcf3ce44SJohn Forte 	while (tmp_len > 8) {
1216*fcf3ce44SJohn Forte 		tmp->attr_len = 0;
1217*fcf3ce44SJohn Forte 		NEXT_TLV(tmp, tmp_len);
1218*fcf3ce44SJohn Forte 	}
1219*fcf3ce44SJohn Forte 
1220*fcf3ce44SJohn Forte 	return (get_qry_attrs(uid, type, tlv, tlv_len, conn));
1221*fcf3ce44SJohn Forte }
1222