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