xref: /titanic_51/usr/src/cmd/isns/isnsd/obj.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
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 #include <pthread.h>
31*fcf3ce44SJohn Forte #include <sys/types.h>
32*fcf3ce44SJohn Forte #include <sys/socket.h>
33*fcf3ce44SJohn Forte #include <netinet/in.h>
34*fcf3ce44SJohn Forte #include <arpa/inet.h>
35*fcf3ce44SJohn Forte 
36*fcf3ce44SJohn Forte #include "isns_server.h"
37*fcf3ce44SJohn Forte #include "isns_msgq.h"
38*fcf3ce44SJohn Forte #include "isns_htab.h"
39*fcf3ce44SJohn Forte #include "isns_cache.h"
40*fcf3ce44SJohn Forte #include "isns_pdu.h"
41*fcf3ce44SJohn Forte #include "isns_obj.h"
42*fcf3ce44SJohn Forte #include "isns_dd.h"
43*fcf3ce44SJohn Forte #include "isns_func.h"
44*fcf3ce44SJohn Forte #include "isns_dseng.h"
45*fcf3ce44SJohn Forte #include "isns_log.h"
46*fcf3ce44SJohn Forte #include "isns_scn.h"
47*fcf3ce44SJohn Forte #include "isns_utils.h"
48*fcf3ce44SJohn Forte #include "isns_esi.h"
49*fcf3ce44SJohn Forte 
50*fcf3ce44SJohn Forte /*
51*fcf3ce44SJohn Forte  * external variables
52*fcf3ce44SJohn Forte  */
53*fcf3ce44SJohn Forte #ifdef DEBUG
54*fcf3ce44SJohn Forte extern int verbose_mc;
55*fcf3ce44SJohn Forte extern void print_object(char *, isns_obj_t *);
56*fcf3ce44SJohn Forte #endif
57*fcf3ce44SJohn Forte 
58*fcf3ce44SJohn Forte extern msg_queue_t *sys_q;
59*fcf3ce44SJohn Forte extern msg_queue_t *scn_q;
60*fcf3ce44SJohn Forte 
61*fcf3ce44SJohn Forte extern pthread_mutex_t el_mtx;
62*fcf3ce44SJohn Forte 
63*fcf3ce44SJohn Forte extern int cache_flag;
64*fcf3ce44SJohn Forte 
65*fcf3ce44SJohn Forte /*
66*fcf3ce44SJohn Forte  * global data
67*fcf3ce44SJohn Forte  */
68*fcf3ce44SJohn Forte 
69*fcf3ce44SJohn Forte /*
70*fcf3ce44SJohn Forte  * local variables
71*fcf3ce44SJohn Forte  */
72*fcf3ce44SJohn Forte /* type of parent object */
73*fcf3ce44SJohn Forte const int TYPE_OF_PARENT[MAX_OBJ_TYPE_FOR_SIZE] = {
74*fcf3ce44SJohn Forte 	0,
75*fcf3ce44SJohn Forte 	0,
76*fcf3ce44SJohn Forte 	ISCSI_PARENT_TYPE,
77*fcf3ce44SJohn Forte 	PORTAL_PARENT_TYPE,
78*fcf3ce44SJohn Forte 	PG_PARENT_TYPE,
79*fcf3ce44SJohn Forte 	0,	/* OBJ_DD */
80*fcf3ce44SJohn Forte 	0,	/* OBJ_DDS */
81*fcf3ce44SJohn Forte 	0,	/* MAX_OBJ_TYPE */
82*fcf3ce44SJohn Forte 	0,	/* OBJ_DUMMY1 */
83*fcf3ce44SJohn Forte 	0,	/* OBJ_DUMMY2 */
84*fcf3ce44SJohn Forte 	0,	/* OBJ_DUMMY3 */
85*fcf3ce44SJohn Forte 	0,	/* OBJ_DUMMY4 */
86*fcf3ce44SJohn Forte 	ASSOC_ISCSI_PARENT_TYPE,
87*fcf3ce44SJohn Forte 	ASSOC_DD_PARENT_TYPE
88*fcf3ce44SJohn Forte };
89*fcf3ce44SJohn Forte 
90*fcf3ce44SJohn Forte /* number of children object type */
91*fcf3ce44SJohn Forte const int NUM_OF_CHILD[MAX_OBJ_TYPE] = {
92*fcf3ce44SJohn Forte 	0,
93*fcf3ce44SJohn Forte 	MAX_ENTITY_CHILD,
94*fcf3ce44SJohn Forte 	MAX_ISCSI_CHILD,
95*fcf3ce44SJohn Forte 	MAX_PORTAL_CHILD,
96*fcf3ce44SJohn Forte 	MAX_PG_CHILD,
97*fcf3ce44SJohn Forte 	0,
98*fcf3ce44SJohn Forte 	0
99*fcf3ce44SJohn Forte };
100*fcf3ce44SJohn Forte 
101*fcf3ce44SJohn Forte /* type of a child object */
102*fcf3ce44SJohn Forte const int TYPE_OF_CHILD[MAX_OBJ_TYPE][MAX_CHILD_TYPE] = {
103*fcf3ce44SJohn Forte 	{ 0, 0 },
104*fcf3ce44SJohn Forte 	{ OBJ_ISCSI, OBJ_PORTAL },
105*fcf3ce44SJohn Forte 	{ 0, 0 },
106*fcf3ce44SJohn Forte 	{ 0, 0 },
107*fcf3ce44SJohn Forte 	{ 0, 0 },
108*fcf3ce44SJohn Forte 	{ 0, 0 },
109*fcf3ce44SJohn Forte 	{ 0, 0 }
110*fcf3ce44SJohn Forte };
111*fcf3ce44SJohn Forte 
112*fcf3ce44SJohn Forte /* number of attributes of certain type of object */
113*fcf3ce44SJohn Forte const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE] = {
114*fcf3ce44SJohn Forte 	0,
115*fcf3ce44SJohn Forte 	NUM_OF_ENTITY_ATTRS,
116*fcf3ce44SJohn Forte 	NUM_OF_ISCSI_ATTRS,
117*fcf3ce44SJohn Forte 	NUM_OF_PORTAL_ATTRS,
118*fcf3ce44SJohn Forte 	NUM_OF_PG_ATTRS,
119*fcf3ce44SJohn Forte 	NUM_OF_DD_ATTRS,
120*fcf3ce44SJohn Forte 	NUM_OF_DDS_ATTRS,
121*fcf3ce44SJohn Forte 	0,			/* MAX_OBJ_TYPE */
122*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY1 */
123*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY2 */
124*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY3 */
125*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY4 */
126*fcf3ce44SJohn Forte 	NUM_OF_ASSOC_ISCSI_ATTRS,
127*fcf3ce44SJohn Forte 	NUM_OF_ASSOC_DD_ATTRS
128*fcf3ce44SJohn Forte };
129*fcf3ce44SJohn Forte 
130*fcf3ce44SJohn Forte /* the tag of UID of each type of object */
131*fcf3ce44SJohn Forte static const int UID_TAG[MAX_OBJ_TYPE_FOR_SIZE] = {
132*fcf3ce44SJohn Forte 	0,
133*fcf3ce44SJohn Forte 	ISNS_ENTITY_INDEX_ATTR_ID,
134*fcf3ce44SJohn Forte 	ISNS_ISCSI_NODE_INDEX_ATTR_ID,
135*fcf3ce44SJohn Forte 	ISNS_PORTAL_INDEX_ATTR_ID,
136*fcf3ce44SJohn Forte 	ISNS_PG_INDEX_ATTR_ID,
137*fcf3ce44SJohn Forte 	ISNS_DD_ID_ATTR_ID,
138*fcf3ce44SJohn Forte 	ISNS_DD_SET_ID_ATTR_ID,
139*fcf3ce44SJohn Forte 	0,			/* MAX_OBJ_TYPE */
140*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY1 */
141*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY2 */
142*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY3 */
143*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY4 */
144*fcf3ce44SJohn Forte 	ISNS_DD_ISCSI_INDEX_ATTR_ID,
145*fcf3ce44SJohn Forte 	ISNS_DD_ID_ATTR_ID
146*fcf3ce44SJohn Forte };
147*fcf3ce44SJohn Forte 
148*fcf3ce44SJohn Forte /* the index of UID of each type of object */
149*fcf3ce44SJohn Forte const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE] = {
150*fcf3ce44SJohn Forte 	0,
151*fcf3ce44SJohn Forte 	ATTR_INDEX_ENTITY(ISNS_ENTITY_INDEX_ATTR_ID),
152*fcf3ce44SJohn Forte 	ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_INDEX_ATTR_ID),
153*fcf3ce44SJohn Forte 	ATTR_INDEX_PORTAL(ISNS_PORTAL_INDEX_ATTR_ID),
154*fcf3ce44SJohn Forte 	ATTR_INDEX_PG(ISNS_PG_INDEX_ATTR_ID),
155*fcf3ce44SJohn Forte 	ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID),
156*fcf3ce44SJohn Forte 	ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID),
157*fcf3ce44SJohn Forte 	0,			/* MAX_OBJ_TYPE */
158*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY1 */
159*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY2 */
160*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY3 */
161*fcf3ce44SJohn Forte 	0,			/* OBJ_DUMMY4 */
162*fcf3ce44SJohn Forte 	ATTR_INDEX_ASSOC_ISCSI(ISNS_DD_ISCSI_INDEX_ATTR_ID),
163*fcf3ce44SJohn Forte 	ATTR_INDEX_ASSOC_DD(ISNS_DD_ID_ATTR_ID)
164*fcf3ce44SJohn Forte };
165*fcf3ce44SJohn Forte 
166*fcf3ce44SJohn Forte /* the index of the key attributes of each type of object */
167*fcf3ce44SJohn Forte static const int KEY_ATTR_INDEX[MAX_OBJ_TYPE][MAX_KEY_ATTRS] = {
168*fcf3ce44SJohn Forte 	{ 0 },
169*fcf3ce44SJohn Forte 	{ ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID), 0 },
170*fcf3ce44SJohn Forte 	{ ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID),
171*fcf3ce44SJohn Forte 		0 },
172*fcf3ce44SJohn Forte 	{ ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID),
173*fcf3ce44SJohn Forte 		ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID),
174*fcf3ce44SJohn Forte 		0 },
175*fcf3ce44SJohn Forte 	{ ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID),
176*fcf3ce44SJohn Forte 		ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID),
177*fcf3ce44SJohn Forte 		ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID) },
178*fcf3ce44SJohn Forte 	{ ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID), 0 },
179*fcf3ce44SJohn Forte 	{ ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID), 0 }
180*fcf3ce44SJohn Forte };
181*fcf3ce44SJohn Forte 
182*fcf3ce44SJohn Forte /* the operating methods for key attributes of each type of object */
183*fcf3ce44SJohn Forte static const int KEY_ATTR_OP[MAX_OBJ_TYPE][MAX_KEY_ATTRS] = {
184*fcf3ce44SJohn Forte 	{ 0 },
185*fcf3ce44SJohn Forte 	{ OP_STRING, 0 },
186*fcf3ce44SJohn Forte 	{ OP_STRING, 0 },
187*fcf3ce44SJohn Forte 	{ OP_MEMORY_IP6, OP_INTEGER, 0 },
188*fcf3ce44SJohn Forte 	{ OP_STRING, OP_MEMORY_IP6, OP_INTEGER },
189*fcf3ce44SJohn Forte 	{ OP_STRING, 0 },
190*fcf3ce44SJohn Forte 	{ OP_STRING, 0 }
191*fcf3ce44SJohn Forte };
192*fcf3ce44SJohn Forte 
193*fcf3ce44SJohn Forte /* the size of each type of object */
194*fcf3ce44SJohn Forte static const int SIZEOF_OBJ[MAX_OBJ_TYPE_FOR_SIZE] = {
195*fcf3ce44SJohn Forte 	0,
196*fcf3ce44SJohn Forte 	sizeof (isns_entity_t),
197*fcf3ce44SJohn Forte 	sizeof (isns_iscsi_t),
198*fcf3ce44SJohn Forte 	sizeof (isns_portal_t),
199*fcf3ce44SJohn Forte 	sizeof (isns_pg_t),
200*fcf3ce44SJohn Forte 	sizeof (isns_dd_t),
201*fcf3ce44SJohn Forte 	sizeof (isns_dds_t),
202*fcf3ce44SJohn Forte 	0,
203*fcf3ce44SJohn Forte 	0,
204*fcf3ce44SJohn Forte 	0,
205*fcf3ce44SJohn Forte 	0,
206*fcf3ce44SJohn Forte 	0,
207*fcf3ce44SJohn Forte 	sizeof (isns_assoc_iscsi_t),
208*fcf3ce44SJohn Forte 	sizeof (isns_assoc_dd_t)
209*fcf3ce44SJohn Forte };
210*fcf3ce44SJohn Forte 
211*fcf3ce44SJohn Forte #ifdef DEBUG
212*fcf3ce44SJohn Forte const int NUM_OF_REF[MAX_OBJ_TYPE_FOR_SIZE] = {
213*fcf3ce44SJohn Forte #else
214*fcf3ce44SJohn Forte static const int NUM_OF_REF[MAX_OBJ_TYPE_FOR_SIZE] = {
215*fcf3ce44SJohn Forte #endif
216*fcf3ce44SJohn Forte 	0,
217*fcf3ce44SJohn Forte 	0,
218*fcf3ce44SJohn Forte 	0,
219*fcf3ce44SJohn Forte 	0,
220*fcf3ce44SJohn Forte 	PG_REF_COUNT,
221*fcf3ce44SJohn Forte 	0,
222*fcf3ce44SJohn Forte 	0,
223*fcf3ce44SJohn Forte 	0,
224*fcf3ce44SJohn Forte 	0,
225*fcf3ce44SJohn Forte 	0,
226*fcf3ce44SJohn Forte 	0,
227*fcf3ce44SJohn Forte 	0,
228*fcf3ce44SJohn Forte 	0,
229*fcf3ce44SJohn Forte 	0
230*fcf3ce44SJohn Forte };
231*fcf3ce44SJohn Forte 
232*fcf3ce44SJohn Forte /* the type of the reference object */
233*fcf3ce44SJohn Forte static const int TYPE_OF_REF[MAX_OBJ_TYPE][MAX_REF_COUNT + 1] = {
234*fcf3ce44SJohn Forte 	{ 0 },
235*fcf3ce44SJohn Forte 	{ 0 },
236*fcf3ce44SJohn Forte 	{ OBJ_PG, OBJ_PORTAL, 0 },
237*fcf3ce44SJohn Forte 	{ OBJ_PG, OBJ_ISCSI, 0 },
238*fcf3ce44SJohn Forte 	{ 0, OBJ_ISCSI, OBJ_PORTAL },
239*fcf3ce44SJohn Forte 	{ 0 },
240*fcf3ce44SJohn Forte 	{ 0 }
241*fcf3ce44SJohn Forte };
242*fcf3ce44SJohn Forte 
243*fcf3ce44SJohn Forte /* the operating method for match operation of the reference object */
244*fcf3ce44SJohn Forte #define	MAX_REF_MATCH	(2)
245*fcf3ce44SJohn Forte static const int REF_MATCH_OPS[MAX_OBJ_TYPE][MAX_REF_MATCH] = {
246*fcf3ce44SJohn Forte 	{ 0, 0 },
247*fcf3ce44SJohn Forte 	{ 0, 0 },
248*fcf3ce44SJohn Forte 	{ OP_STRING, 0 },
249*fcf3ce44SJohn Forte 	{ OP_MEMORY_IP6, OP_INTEGER },
250*fcf3ce44SJohn Forte 	{ 0, 0 },
251*fcf3ce44SJohn Forte 	{ 0, 0 },
252*fcf3ce44SJohn Forte 	{ 0, 0 }
253*fcf3ce44SJohn Forte };
254*fcf3ce44SJohn Forte 
255*fcf3ce44SJohn Forte /* the index of the attribute of being matched object */
256*fcf3ce44SJohn Forte static const int REF_MATCH_ID1[MAX_OBJ_TYPE][MAX_REF_MATCH] = {
257*fcf3ce44SJohn Forte 	{ 0, 0 },
258*fcf3ce44SJohn Forte 	{ 0, 0 },
259*fcf3ce44SJohn Forte 	{ ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID), 0 },
260*fcf3ce44SJohn Forte 	{ ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID),
261*fcf3ce44SJohn Forte 		ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID) },
262*fcf3ce44SJohn Forte 	{ 0, 0 },
263*fcf3ce44SJohn Forte 	{ 0, 0 },
264*fcf3ce44SJohn Forte 	{ 0, 0 }
265*fcf3ce44SJohn Forte };
266*fcf3ce44SJohn Forte 
267*fcf3ce44SJohn Forte /* the index of the attribute of matching object */
268*fcf3ce44SJohn Forte static const int REF_MATCH_ID2[MAX_OBJ_TYPE][MAX_REF_MATCH] = {
269*fcf3ce44SJohn Forte 	{ 0, 0 },
270*fcf3ce44SJohn Forte 	{ 0, 0 },
271*fcf3ce44SJohn Forte 	{ ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID), 0 },
272*fcf3ce44SJohn Forte 	{ ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID),
273*fcf3ce44SJohn Forte 		ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID) },
274*fcf3ce44SJohn Forte 	{ 0, 0 },
275*fcf3ce44SJohn Forte 	{ 0, 0 },
276*fcf3ce44SJohn Forte 	{ 0, 0 }
277*fcf3ce44SJohn Forte };
278*fcf3ce44SJohn Forte 
279*fcf3ce44SJohn Forte /*
280*fcf3ce44SJohn Forte  * local functions.
281*fcf3ce44SJohn Forte  */
282*fcf3ce44SJohn Forte static uint32_t get_reg_period();
283*fcf3ce44SJohn Forte static char *make_unique_name(int *, uint32_t);
284*fcf3ce44SJohn Forte static lookup_ctrl_t *set_lookup_ctrl(lookup_ctrl_t *, isns_obj_t *);
285*fcf3ce44SJohn Forte static int setup_ref_lcp(lookup_ctrl_t *,
286*fcf3ce44SJohn Forte 	const isns_obj_t *, const isns_obj_t *);
287*fcf3ce44SJohn Forte static int setup_deref_lcp(lookup_ctrl_t *,
288*fcf3ce44SJohn Forte 	const isns_obj_t *, isns_type_t);
289*fcf3ce44SJohn Forte static int cb_get_parent(void *, void *);
290*fcf3ce44SJohn Forte static int cb_node_child(void *, void *);
291*fcf3ce44SJohn Forte static int cb_set_ref(void *, void *);
292*fcf3ce44SJohn Forte static int cb_clear_ref(void *, void *);
293*fcf3ce44SJohn Forte static int cb_add_child(void *, void *);
294*fcf3ce44SJohn Forte static int cb_remove_child(void *, void *);
295*fcf3ce44SJohn Forte static int cb_verify_ref(void *, void *);
296*fcf3ce44SJohn Forte static int cb_ref_new2old(void *, void *);
297*fcf3ce44SJohn Forte static int cb_new_ref(void *, void *);
298*fcf3ce44SJohn Forte static int ref_new2old(
299*fcf3ce44SJohn Forte 	lookup_ctrl_t *, isns_type_t, uint32_t, const isns_obj_t *);
300*fcf3ce44SJohn Forte static int ref_new2new(
301*fcf3ce44SJohn Forte 	lookup_ctrl_t *, const isns_obj_t *, const isns_obj_t *);
302*fcf3ce44SJohn Forte static int new_ref(const isns_obj_t *, const isns_obj_t *);
303*fcf3ce44SJohn Forte static uint32_t setup_parent_lcp(lookup_ctrl_t *, isns_obj_t *);
304*fcf3ce44SJohn Forte static int set_obj_offline(isns_obj_t *);
305*fcf3ce44SJohn Forte static int copy_attrs(isns_obj_t *, const isns_obj_t *);
306*fcf3ce44SJohn Forte 
307*fcf3ce44SJohn Forte static isns_obj_t *make_default_pg(const isns_obj_t *, const isns_obj_t *);
308*fcf3ce44SJohn Forte static isns_obj_t *(*const make_ref[MAX_OBJ_TYPE])
309*fcf3ce44SJohn Forte 	(const isns_obj_t *, const isns_obj_t *) = {
310*fcf3ce44SJohn Forte 		NULL,
311*fcf3ce44SJohn Forte 		NULL,
312*fcf3ce44SJohn Forte 		&make_default_pg,
313*fcf3ce44SJohn Forte 		&make_default_pg,
314*fcf3ce44SJohn Forte 		NULL,
315*fcf3ce44SJohn Forte 		NULL,
316*fcf3ce44SJohn Forte 		NULL
317*fcf3ce44SJohn Forte };
318*fcf3ce44SJohn Forte 
319*fcf3ce44SJohn Forte static uint32_t entity_hval(void *, uint16_t, uint32_t *);
320*fcf3ce44SJohn Forte static uint32_t iscsi_hval(void *, uint16_t, uint32_t *);
321*fcf3ce44SJohn Forte static uint32_t portal_hval(void *, uint16_t, uint32_t *);
322*fcf3ce44SJohn Forte static uint32_t pg_hval(void *, uint16_t, uint32_t *);
323*fcf3ce44SJohn Forte static uint32_t dd_hval(void *, uint16_t, uint32_t *);
324*fcf3ce44SJohn Forte static uint32_t dds_hval(void *, uint16_t, uint32_t *);
325*fcf3ce44SJohn Forte static uint32_t (*const hval_func[MAX_OBJ_TYPE])
326*fcf3ce44SJohn Forte 	(void *, uint16_t, uint32_t *) = {
327*fcf3ce44SJohn Forte 		NULL,
328*fcf3ce44SJohn Forte 		&entity_hval,
329*fcf3ce44SJohn Forte 		&iscsi_hval,
330*fcf3ce44SJohn Forte 		&portal_hval,
331*fcf3ce44SJohn Forte 		&pg_hval,
332*fcf3ce44SJohn Forte 		&dd_hval,
333*fcf3ce44SJohn Forte 		&dds_hval
334*fcf3ce44SJohn Forte };
335*fcf3ce44SJohn Forte 
336*fcf3ce44SJohn Forte /*
337*fcf3ce44SJohn Forte  * ****************************************************************************
338*fcf3ce44SJohn Forte  *
339*fcf3ce44SJohn Forte  * entity_hval:
340*fcf3ce44SJohn Forte  *	caculate the hash value of a network entity object.
341*fcf3ce44SJohn Forte  *
342*fcf3ce44SJohn Forte  * p	- the pointer pointers to network entity object or
343*fcf3ce44SJohn Forte  *	  the lookup control data, both have the key attribute
344*fcf3ce44SJohn Forte  *	  of a network entity object.
345*fcf3ce44SJohn Forte  * chunk- which chunk of the hash table.
346*fcf3ce44SJohn Forte  * flags- pointer to flags.
347*fcf3ce44SJohn Forte  * return - the hash value.
348*fcf3ce44SJohn Forte  *
349*fcf3ce44SJohn Forte  * ****************************************************************************
350*fcf3ce44SJohn Forte  */
351*fcf3ce44SJohn Forte static uint32_t
352*fcf3ce44SJohn Forte entity_hval(
353*fcf3ce44SJohn Forte 	void *p,
354*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_ARG_UNUSED */
355*fcf3ce44SJohn Forte 	uint16_t chunk,
356*fcf3ce44SJohn Forte 	uint32_t *flags
357*fcf3ce44SJohn Forte )
358*fcf3ce44SJohn Forte {
359*fcf3ce44SJohn Forte 	uchar_t *key;
360*fcf3ce44SJohn Forte 	isns_obj_t *obj;
361*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp;
362*fcf3ce44SJohn Forte 
363*fcf3ce44SJohn Forte 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
364*fcf3ce44SJohn Forte 		/* p pointers to a network entity object */
365*fcf3ce44SJohn Forte 		obj = (isns_obj_t *)p;
366*fcf3ce44SJohn Forte 		key = obj->attrs[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)].
367*fcf3ce44SJohn Forte 		    value.ptr;
368*fcf3ce44SJohn Forte 	} else {
369*fcf3ce44SJohn Forte 		/* p is lookup control data */
370*fcf3ce44SJohn Forte 		lcp = (lookup_ctrl_t *)p;
371*fcf3ce44SJohn Forte 		key = lcp->data[0].ptr;
372*fcf3ce44SJohn Forte 	}
373*fcf3ce44SJohn Forte 
374*fcf3ce44SJohn Forte 	return (htab_compute_hval(key));
375*fcf3ce44SJohn Forte }
376*fcf3ce44SJohn Forte 
377*fcf3ce44SJohn Forte /*
378*fcf3ce44SJohn Forte  * ****************************************************************************
379*fcf3ce44SJohn Forte  *
380*fcf3ce44SJohn Forte  * iscsi_hval:
381*fcf3ce44SJohn Forte  *	caculate the hash value of an iscsi storage node object.
382*fcf3ce44SJohn Forte  *
383*fcf3ce44SJohn Forte  * p	- the pointer pointers to iscsi storage node object or
384*fcf3ce44SJohn Forte  *	  the lookup control data, both have the key attribute
385*fcf3ce44SJohn Forte  *	  of an iscsi storage node object.
386*fcf3ce44SJohn Forte  * chunk- which chunk of the hash table.
387*fcf3ce44SJohn Forte  * flags- pointer to flags.
388*fcf3ce44SJohn Forte  * return - the hash value.
389*fcf3ce44SJohn Forte  *
390*fcf3ce44SJohn Forte  * ****************************************************************************
391*fcf3ce44SJohn Forte  */
392*fcf3ce44SJohn Forte static uint32_t
393*fcf3ce44SJohn Forte iscsi_hval(
394*fcf3ce44SJohn Forte 	void *p,
395*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_ARG_UNUSED */
396*fcf3ce44SJohn Forte 	uint16_t chunk,
397*fcf3ce44SJohn Forte 	uint32_t *flags
398*fcf3ce44SJohn Forte )
399*fcf3ce44SJohn Forte {
400*fcf3ce44SJohn Forte 	uchar_t *key;
401*fcf3ce44SJohn Forte 	isns_obj_t *obj;
402*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp;
403*fcf3ce44SJohn Forte 
404*fcf3ce44SJohn Forte 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
405*fcf3ce44SJohn Forte 		/* p pointers to an iscsi storage node object */
406*fcf3ce44SJohn Forte 		obj = (isns_obj_t *)p;
407*fcf3ce44SJohn Forte 		key = obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)].
408*fcf3ce44SJohn Forte 		    value.ptr;
409*fcf3ce44SJohn Forte 	} else {
410*fcf3ce44SJohn Forte 		/* p is lookup control data */
411*fcf3ce44SJohn Forte 		lcp = (lookup_ctrl_t *)p;
412*fcf3ce44SJohn Forte 		key = lcp->data[0].ptr;
413*fcf3ce44SJohn Forte 	}
414*fcf3ce44SJohn Forte 
415*fcf3ce44SJohn Forte 	return (htab_compute_hval(key));
416*fcf3ce44SJohn Forte }
417*fcf3ce44SJohn Forte 
418*fcf3ce44SJohn Forte /*
419*fcf3ce44SJohn Forte  * ****************************************************************************
420*fcf3ce44SJohn Forte  *
421*fcf3ce44SJohn Forte  * portal_hval:
422*fcf3ce44SJohn Forte  *	caculate the hash value of a portal object.
423*fcf3ce44SJohn Forte  *
424*fcf3ce44SJohn Forte  * p	- the pointer pointers to a portal object or the lookup control
425*fcf3ce44SJohn Forte  *	  data, both have the key attributes of a portal object.
426*fcf3ce44SJohn Forte  * chunk- which chunk of the hash table.
427*fcf3ce44SJohn Forte  * flags- pointer to flags.
428*fcf3ce44SJohn Forte  * return - the hash value.
429*fcf3ce44SJohn Forte  *
430*fcf3ce44SJohn Forte  * ****************************************************************************
431*fcf3ce44SJohn Forte  */
432*fcf3ce44SJohn Forte static uint32_t
433*fcf3ce44SJohn Forte portal_hval(
434*fcf3ce44SJohn Forte 	void *p,
435*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_ARG_UNUSED */
436*fcf3ce44SJohn Forte 	uint16_t chunk,
437*fcf3ce44SJohn Forte 	uint32_t *flags
438*fcf3ce44SJohn Forte )
439*fcf3ce44SJohn Forte {
440*fcf3ce44SJohn Forte 	char buff[INET6_ADDRSTRLEN + 8] = { 0 };
441*fcf3ce44SJohn Forte 	char buff2[8] = { 0 };
442*fcf3ce44SJohn Forte 	uchar_t *key;
443*fcf3ce44SJohn Forte 	isns_obj_t *obj;
444*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp;
445*fcf3ce44SJohn Forte 
446*fcf3ce44SJohn Forte 	in6_addr_t *ip;
447*fcf3ce44SJohn Forte 	uint32_t port;
448*fcf3ce44SJohn Forte 
449*fcf3ce44SJohn Forte 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
450*fcf3ce44SJohn Forte 		/* p pointers to a portal object */
451*fcf3ce44SJohn Forte 		obj = (isns_obj_t *)p;
452*fcf3ce44SJohn Forte 		ip = obj->attrs[ATTR_INDEX_PORTAL
453*fcf3ce44SJohn Forte 		    (ISNS_PORTAL_IP_ADDR_ATTR_ID)].value.ip;
454*fcf3ce44SJohn Forte 		port = obj->attrs[ATTR_INDEX_PORTAL
455*fcf3ce44SJohn Forte 		    (ISNS_PORTAL_PORT_ATTR_ID)].value.ui;
456*fcf3ce44SJohn Forte 	} else {
457*fcf3ce44SJohn Forte 		/* p is lookup control data */
458*fcf3ce44SJohn Forte 		lcp = (lookup_ctrl_t *)p;
459*fcf3ce44SJohn Forte 		ip = lcp->data[0].ip;
460*fcf3ce44SJohn Forte 		port = lcp->data[1].ui;
461*fcf3ce44SJohn Forte 	}
462*fcf3ce44SJohn Forte 
463*fcf3ce44SJohn Forte 	key = (uchar_t *)inet_ntop(AF_INET6, (void *)ip,
464*fcf3ce44SJohn Forte 	    buff, sizeof (buff));
465*fcf3ce44SJohn Forte 	(void) snprintf(buff2, sizeof (buff2), "%d", port);
466*fcf3ce44SJohn Forte 	(void) strcat((char *)key, buff2);
467*fcf3ce44SJohn Forte 
468*fcf3ce44SJohn Forte 	return (htab_compute_hval(key));
469*fcf3ce44SJohn Forte }
470*fcf3ce44SJohn Forte 
471*fcf3ce44SJohn Forte /*
472*fcf3ce44SJohn Forte  * ****************************************************************************
473*fcf3ce44SJohn Forte  *
474*fcf3ce44SJohn Forte  * pg_hval:
475*fcf3ce44SJohn Forte  *	caculate the hash value of a portal group object.
476*fcf3ce44SJohn Forte  *
477*fcf3ce44SJohn Forte  * p	- the pointer pointers to a portal group object or the lookup
478*fcf3ce44SJohn Forte  *	  control data, both have the key attributes of a portal object.
479*fcf3ce44SJohn Forte  * chunk- which chunk of the hash table.
480*fcf3ce44SJohn Forte  * flags- pointer to flags.
481*fcf3ce44SJohn Forte  * return - the hash value.
482*fcf3ce44SJohn Forte  *
483*fcf3ce44SJohn Forte  * ****************************************************************************
484*fcf3ce44SJohn Forte  */
485*fcf3ce44SJohn Forte static uint32_t
486*fcf3ce44SJohn Forte pg_hval(
487*fcf3ce44SJohn Forte 	void *p,
488*fcf3ce44SJohn Forte 	uint16_t chunk,
489*fcf3ce44SJohn Forte 	uint32_t *flags
490*fcf3ce44SJohn Forte )
491*fcf3ce44SJohn Forte {
492*fcf3ce44SJohn Forte 	char buff[INET6_ADDRSTRLEN + 8] = { 0 };
493*fcf3ce44SJohn Forte 	char buff2[8] = { 0 };
494*fcf3ce44SJohn Forte 	uchar_t *key = NULL;
495*fcf3ce44SJohn Forte 	isns_obj_t *obj;
496*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp;
497*fcf3ce44SJohn Forte 
498*fcf3ce44SJohn Forte 	in6_addr_t *ip = NULL;
499*fcf3ce44SJohn Forte 	uint32_t port;
500*fcf3ce44SJohn Forte 
501*fcf3ce44SJohn Forte 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
502*fcf3ce44SJohn Forte 		/* p is a portal group object */
503*fcf3ce44SJohn Forte 		obj = (isns_obj_t *)p;
504*fcf3ce44SJohn Forte 		if (chunk == 0) {
505*fcf3ce44SJohn Forte 			/* the first chunk */
506*fcf3ce44SJohn Forte 			key = obj->attrs[ATTR_INDEX_PG
507*fcf3ce44SJohn Forte 			    (ISNS_PG_ISCSI_NAME_ATTR_ID)].value.ptr;
508*fcf3ce44SJohn Forte 		} else {
509*fcf3ce44SJohn Forte 			/* another chunk */
510*fcf3ce44SJohn Forte 			ip = obj->attrs[ATTR_INDEX_PG
511*fcf3ce44SJohn Forte 			    (ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)].value.ip;
512*fcf3ce44SJohn Forte 			port = obj->attrs[ATTR_INDEX_PG
513*fcf3ce44SJohn Forte 			    (ISNS_PG_PORTAL_PORT_ATTR_ID)].value.ui;
514*fcf3ce44SJohn Forte 		}
515*fcf3ce44SJohn Forte 	} else {
516*fcf3ce44SJohn Forte 		/* p is a lookup control data */
517*fcf3ce44SJohn Forte 		lcp = (lookup_ctrl_t *)p;
518*fcf3ce44SJohn Forte 		/* clear the chunk flags */
519*fcf3ce44SJohn Forte 		*flags &= ~FLAGS_CHUNK_MASK;
520*fcf3ce44SJohn Forte 		if (lcp->op[0] == OP_STRING) {
521*fcf3ce44SJohn Forte 			/* the first chunk */
522*fcf3ce44SJohn Forte 			key = lcp->data[0].ptr;
523*fcf3ce44SJohn Forte 		} else {
524*fcf3ce44SJohn Forte 			/* another chunk */
525*fcf3ce44SJohn Forte 			ip = lcp->data[0].ip;
526*fcf3ce44SJohn Forte 			port = lcp->data[1].ui;
527*fcf3ce44SJohn Forte 			*flags |= 1;
528*fcf3ce44SJohn Forte 		}
529*fcf3ce44SJohn Forte 	}
530*fcf3ce44SJohn Forte 
531*fcf3ce44SJohn Forte 	if (key == NULL) {
532*fcf3ce44SJohn Forte 		key = (uchar_t *)inet_ntop(AF_INET6, (void *)ip,
533*fcf3ce44SJohn Forte 		    buff, sizeof (buff));
534*fcf3ce44SJohn Forte 		(void) snprintf(buff2, sizeof (buff2), "%d", port);
535*fcf3ce44SJohn Forte 		(void) strcat((char *)key, buff2);
536*fcf3ce44SJohn Forte 	}
537*fcf3ce44SJohn Forte 
538*fcf3ce44SJohn Forte 	return (htab_compute_hval(key));
539*fcf3ce44SJohn Forte }
540*fcf3ce44SJohn Forte 
541*fcf3ce44SJohn Forte /*
542*fcf3ce44SJohn Forte  * ****************************************************************************
543*fcf3ce44SJohn Forte  *
544*fcf3ce44SJohn Forte  * dd_hval:
545*fcf3ce44SJohn Forte  *	caculate the hash value of a DD object.
546*fcf3ce44SJohn Forte  *
547*fcf3ce44SJohn Forte  * p	- the pointer pointers to a DD object or the lookup control data,
548*fcf3ce44SJohn Forte  *	  both have the key attributes of a DD object.
549*fcf3ce44SJohn Forte  * chunk- which chunk of the hash table.
550*fcf3ce44SJohn Forte  * flags- pointer to flags.
551*fcf3ce44SJohn Forte  * return - the hash value.
552*fcf3ce44SJohn Forte  *
553*fcf3ce44SJohn Forte  * ****************************************************************************
554*fcf3ce44SJohn Forte  */
555*fcf3ce44SJohn Forte static uint32_t
556*fcf3ce44SJohn Forte dd_hval(
557*fcf3ce44SJohn Forte 	void *p,
558*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_ARG_UNUSED */
559*fcf3ce44SJohn Forte 	uint16_t chunk,
560*fcf3ce44SJohn Forte 	uint32_t *flags
561*fcf3ce44SJohn Forte )
562*fcf3ce44SJohn Forte {
563*fcf3ce44SJohn Forte 	uchar_t *key;
564*fcf3ce44SJohn Forte 	isns_obj_t *obj;
565*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp;
566*fcf3ce44SJohn Forte 
567*fcf3ce44SJohn Forte 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
568*fcf3ce44SJohn Forte 		/* p is a DD object */
569*fcf3ce44SJohn Forte 		obj = (isns_obj_t *)p;
570*fcf3ce44SJohn Forte 		key = obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)].
571*fcf3ce44SJohn Forte 		    value.ptr;
572*fcf3ce44SJohn Forte 	} else {
573*fcf3ce44SJohn Forte 		/* p is a lookup control data */
574*fcf3ce44SJohn Forte 		lcp = (lookup_ctrl_t *)p;
575*fcf3ce44SJohn Forte 		key = lcp->data[0].ptr;
576*fcf3ce44SJohn Forte 	}
577*fcf3ce44SJohn Forte 
578*fcf3ce44SJohn Forte 	return (htab_compute_hval(key));
579*fcf3ce44SJohn Forte }
580*fcf3ce44SJohn Forte 
581*fcf3ce44SJohn Forte /*
582*fcf3ce44SJohn Forte  * ****************************************************************************
583*fcf3ce44SJohn Forte  *
584*fcf3ce44SJohn Forte  * dds_hval:
585*fcf3ce44SJohn Forte  *	caculate the hash value of a DD-set object.
586*fcf3ce44SJohn Forte  *
587*fcf3ce44SJohn Forte  * p	- the pointer pointers to a DD-set object or the lookup control data,
588*fcf3ce44SJohn Forte  *	  both have the key attributes of a DD-set object.
589*fcf3ce44SJohn Forte  * chunk- which chunk of the hash table.
590*fcf3ce44SJohn Forte  * flags- pointer to flags.
591*fcf3ce44SJohn Forte  * return - the hash value.
592*fcf3ce44SJohn Forte  *
593*fcf3ce44SJohn Forte  * ****************************************************************************
594*fcf3ce44SJohn Forte  */
595*fcf3ce44SJohn Forte static uint32_t
596*fcf3ce44SJohn Forte dds_hval(
597*fcf3ce44SJohn Forte 	void *p,
598*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_ARG_UNUSED */
599*fcf3ce44SJohn Forte 	uint16_t chunk,
600*fcf3ce44SJohn Forte 	uint32_t *flags
601*fcf3ce44SJohn Forte )
602*fcf3ce44SJohn Forte {
603*fcf3ce44SJohn Forte 	uchar_t *key;
604*fcf3ce44SJohn Forte 	isns_obj_t *obj;
605*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp;
606*fcf3ce44SJohn Forte 
607*fcf3ce44SJohn Forte 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
608*fcf3ce44SJohn Forte 		/* p is a DD-set object */
609*fcf3ce44SJohn Forte 		obj = (isns_obj_t *)p;
610*fcf3ce44SJohn Forte 		key = obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID)].
611*fcf3ce44SJohn Forte 		    value.ptr;
612*fcf3ce44SJohn Forte 	} else {
613*fcf3ce44SJohn Forte 		/* p is lookup control data */
614*fcf3ce44SJohn Forte 		lcp = (lookup_ctrl_t *)p;
615*fcf3ce44SJohn Forte 		key = lcp->data[0].ptr;
616*fcf3ce44SJohn Forte 	}
617*fcf3ce44SJohn Forte 
618*fcf3ce44SJohn Forte 	return (htab_compute_hval(key));
619*fcf3ce44SJohn Forte }
620*fcf3ce44SJohn Forte 
621*fcf3ce44SJohn Forte /*
622*fcf3ce44SJohn Forte  * ****************************************************************************
623*fcf3ce44SJohn Forte  *
624*fcf3ce44SJohn Forte  * obj_hval:
625*fcf3ce44SJohn Forte  *	caculate the hash value of an object.
626*fcf3ce44SJohn Forte  *
627*fcf3ce44SJohn Forte  * p	- the pointer pointers to an object or lookup control data,
628*fcf3ce44SJohn Forte  *	  both has the object type and the key attributes of an object.
629*fcf3ce44SJohn Forte  * chunk- which chunk of the hash table.
630*fcf3ce44SJohn Forte  * flags- pointer to flags.
631*fcf3ce44SJohn Forte  * return - the hash value.
632*fcf3ce44SJohn Forte  *
633*fcf3ce44SJohn Forte  * ****************************************************************************
634*fcf3ce44SJohn Forte  */
635*fcf3ce44SJohn Forte uint32_t
636*fcf3ce44SJohn Forte obj_hval(
637*fcf3ce44SJohn Forte 	void *p,
638*fcf3ce44SJohn Forte 	uint16_t chunk,
639*fcf3ce44SJohn Forte 	uint32_t *flags
640*fcf3ce44SJohn Forte )
641*fcf3ce44SJohn Forte {
642*fcf3ce44SJohn Forte 	isns_type_t type = ((isns_obj_t *)p)->type;
643*fcf3ce44SJohn Forte 
644*fcf3ce44SJohn Forte 	return (hval_func[type](p, chunk, flags));
645*fcf3ce44SJohn Forte }
646*fcf3ce44SJohn Forte 
647*fcf3ce44SJohn Forte /*
648*fcf3ce44SJohn Forte  * ****************************************************************************
649*fcf3ce44SJohn Forte  *
650*fcf3ce44SJohn Forte  * get_obj_uid:
651*fcf3ce44SJohn Forte  *	get the UID of an object.
652*fcf3ce44SJohn Forte  *
653*fcf3ce44SJohn Forte  * p	- the pointer pointers to an object.
654*fcf3ce44SJohn Forte  * return - the UID.
655*fcf3ce44SJohn Forte  *
656*fcf3ce44SJohn Forte  * ****************************************************************************
657*fcf3ce44SJohn Forte  */
658*fcf3ce44SJohn Forte uint32_t
659*fcf3ce44SJohn Forte get_obj_uid(
660*fcf3ce44SJohn Forte 	const void *p
661*fcf3ce44SJohn Forte )
662*fcf3ce44SJohn Forte {
663*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p;
664*fcf3ce44SJohn Forte 	isns_attr_t *attr = &obj->attrs[UID_ATTR_INDEX[obj->type]];
665*fcf3ce44SJohn Forte 	uint32_t uid = attr->value.ui;
666*fcf3ce44SJohn Forte 	return (uid);
667*fcf3ce44SJohn Forte }
668*fcf3ce44SJohn Forte 
669*fcf3ce44SJohn Forte /*
670*fcf3ce44SJohn Forte  * ****************************************************************************
671*fcf3ce44SJohn Forte  *
672*fcf3ce44SJohn Forte  * set_obj_uid:
673*fcf3ce44SJohn Forte  *	set the UID of an object.
674*fcf3ce44SJohn Forte  *
675*fcf3ce44SJohn Forte  * p	- the pointer pointers to an object.
676*fcf3ce44SJohn Forte  * uid	- the UID.
677*fcf3ce44SJohn Forte  * return - the UID.
678*fcf3ce44SJohn Forte  *
679*fcf3ce44SJohn Forte  * ****************************************************************************
680*fcf3ce44SJohn Forte  */
681*fcf3ce44SJohn Forte uint32_t
682*fcf3ce44SJohn Forte set_obj_uid(
683*fcf3ce44SJohn Forte 	void *p,
684*fcf3ce44SJohn Forte 	uint32_t uid
685*fcf3ce44SJohn Forte )
686*fcf3ce44SJohn Forte {
687*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p;
688*fcf3ce44SJohn Forte 	isns_attr_t *attr = &obj->attrs[UID_ATTR_INDEX[obj->type]];
689*fcf3ce44SJohn Forte 
690*fcf3ce44SJohn Forte 	/* set the tag, len and value */
691*fcf3ce44SJohn Forte 	attr->tag = UID_TAG[obj->type];
692*fcf3ce44SJohn Forte 	attr->len = 4;
693*fcf3ce44SJohn Forte 	attr->value.ui = uid;
694*fcf3ce44SJohn Forte 
695*fcf3ce44SJohn Forte 	return (uid);
696*fcf3ce44SJohn Forte }
697*fcf3ce44SJohn Forte 
698*fcf3ce44SJohn Forte /*
699*fcf3ce44SJohn Forte  * ****************************************************************************
700*fcf3ce44SJohn Forte  *
701*fcf3ce44SJohn Forte  * obj_cmp:
702*fcf3ce44SJohn Forte  *	compare between two objects or an object with a lookup control data.
703*fcf3ce44SJohn Forte  *
704*fcf3ce44SJohn Forte  * p1	- the pointer points to an object.
705*fcf3ce44SJohn Forte  * p2	- the pointer points to an object or a lookup control data.
706*fcf3ce44SJohn Forte  * flags- 0: p2 is an object; otherwise p2 is a lookup control data.
707*fcf3ce44SJohn Forte  * return - the comparsion result.
708*fcf3ce44SJohn Forte  *
709*fcf3ce44SJohn Forte  * ****************************************************************************
710*fcf3ce44SJohn Forte  */
711*fcf3ce44SJohn Forte int
712*fcf3ce44SJohn Forte obj_cmp(
713*fcf3ce44SJohn Forte 	void *p1,
714*fcf3ce44SJohn Forte 	void *p2,
715*fcf3ce44SJohn Forte 	int flags
716*fcf3ce44SJohn Forte )
717*fcf3ce44SJohn Forte {
718*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
719*fcf3ce44SJohn Forte 	lookup_ctrl_t buff = { 0 };
720*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp;
721*fcf3ce44SJohn Forte 	uint32_t uid;
722*fcf3ce44SJohn Forte 
723*fcf3ce44SJohn Forte 	if (flags == 0) {
724*fcf3ce44SJohn Forte 		lcp = set_lookup_ctrl(&buff, (isns_obj_t *)p2);
725*fcf3ce44SJohn Forte 	} else {
726*fcf3ce44SJohn Forte 		lcp = (lookup_ctrl_t *)p2;
727*fcf3ce44SJohn Forte 		uid = get_obj_uid(obj);
728*fcf3ce44SJohn Forte 		/* the object are linked with decending order by */
729*fcf3ce44SJohn Forte 		/* the object UID, if the object UID is greater than */
730*fcf3ce44SJohn Forte 		/* or equal to the current UID, it needs to compare */
731*fcf3ce44SJohn Forte 		/* for the next one. */
732*fcf3ce44SJohn Forte 		if (lcp->curr_uid != 0 && uid >= lcp->curr_uid) {
733*fcf3ce44SJohn Forte 			return (-1);
734*fcf3ce44SJohn Forte 		}
735*fcf3ce44SJohn Forte 	}
736*fcf3ce44SJohn Forte 
737*fcf3ce44SJohn Forte 	return (key_cmp(lcp, obj));
738*fcf3ce44SJohn Forte }
739*fcf3ce44SJohn Forte 
740*fcf3ce44SJohn Forte /*
741*fcf3ce44SJohn Forte  * ****************************************************************************
742*fcf3ce44SJohn Forte  *
743*fcf3ce44SJohn Forte  * replace_object:
744*fcf3ce44SJohn Forte  *	replace an existing object with the new one.
745*fcf3ce44SJohn Forte  *
746*fcf3ce44SJohn Forte  * p1	- the pointer points to an object being replaced.
747*fcf3ce44SJohn Forte  * p2	- the pointer points to a new object.
748*fcf3ce44SJohn Forte  * uid_p- points to uid for returning.
749*fcf3ce44SJohn Forte  * flag	- 0: do not free the source object, otherwise free it.
750*fcf3ce44SJohn Forte  * return - error code.
751*fcf3ce44SJohn Forte  *
752*fcf3ce44SJohn Forte  * ****************************************************************************
753*fcf3ce44SJohn Forte  */
754*fcf3ce44SJohn Forte int
755*fcf3ce44SJohn Forte replace_object(
756*fcf3ce44SJohn Forte 	void *p1,
757*fcf3ce44SJohn Forte 	void *p2,
758*fcf3ce44SJohn Forte 	uint32_t *uid_p,
759*fcf3ce44SJohn Forte 	int flag
760*fcf3ce44SJohn Forte )
761*fcf3ce44SJohn Forte {
762*fcf3ce44SJohn Forte 	int ec = 0;
763*fcf3ce44SJohn Forte 
764*fcf3ce44SJohn Forte #ifndef SKIP_SRC_AUTH
765*fcf3ce44SJohn Forte 	uint32_t *pp_dst, *pp_src, swap;
766*fcf3ce44SJohn Forte #endif
767*fcf3ce44SJohn Forte 	int online;
768*fcf3ce44SJohn Forte 
769*fcf3ce44SJohn Forte 	isns_obj_t *dst = (isns_obj_t *)p1;
770*fcf3ce44SJohn Forte 	isns_obj_t *src = (isns_obj_t *)p2;
771*fcf3ce44SJohn Forte 
772*fcf3ce44SJohn Forte 	if (src->type == OBJ_DD || src->type == OBJ_DDS) {
773*fcf3ce44SJohn Forte 		/* replace not allowed */
774*fcf3ce44SJohn Forte 		return (ERR_NAME_IN_USE);
775*fcf3ce44SJohn Forte 	}
776*fcf3ce44SJohn Forte 
777*fcf3ce44SJohn Forte 	online = is_obj_online(dst);
778*fcf3ce44SJohn Forte 
779*fcf3ce44SJohn Forte 	/* set cache update flag */
780*fcf3ce44SJohn Forte 	SET_CACHE_UPDATED();
781*fcf3ce44SJohn Forte 
782*fcf3ce44SJohn Forte 	/* update parent uid */
783*fcf3ce44SJohn Forte #ifndef SKIP_SRC_AUTH
784*fcf3ce44SJohn Forte 	pp_dst = get_parent_p(dst);
785*fcf3ce44SJohn Forte 	if (pp_dst != NULL) {
786*fcf3ce44SJohn Forte 		pp_src = get_parent_p(src);
787*fcf3ce44SJohn Forte 		swap = *pp_dst;
788*fcf3ce44SJohn Forte 		*pp_dst = *pp_src;
789*fcf3ce44SJohn Forte 		if (swap != 0) {
790*fcf3ce44SJohn Forte 			*pp_src = swap;
791*fcf3ce44SJohn Forte 		}
792*fcf3ce44SJohn Forte 	}
793*fcf3ce44SJohn Forte #endif
794*fcf3ce44SJohn Forte 
795*fcf3ce44SJohn Forte 	/* update all of attributes */
796*fcf3ce44SJohn Forte 	if (copy_attrs(dst, src) != 0) {
797*fcf3ce44SJohn Forte 		return (ISNS_RSP_INTERNAL_ERROR);
798*fcf3ce44SJohn Forte 	}
799*fcf3ce44SJohn Forte 
800*fcf3ce44SJohn Forte 	/* free up the src object */
801*fcf3ce44SJohn Forte 	if (flag != 0) {
802*fcf3ce44SJohn Forte 		(void) free_object(src);
803*fcf3ce44SJohn Forte 	} else if (online == 0) {
804*fcf3ce44SJohn Forte 		(void) set_obj_uid(src, get_obj_uid(dst));
805*fcf3ce44SJohn Forte 		(void) set_obj_offline(src);
806*fcf3ce44SJohn Forte 	}
807*fcf3ce44SJohn Forte 
808*fcf3ce44SJohn Forte 	/* update data store */
809*fcf3ce44SJohn Forte 	if (sys_q != NULL) {
810*fcf3ce44SJohn Forte 		ec = write_data(DATA_UPDATE, dst);
811*fcf3ce44SJohn Forte 	} else {
812*fcf3ce44SJohn Forte 		/* we should never have duplicated entry in data store */
813*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
814*fcf3ce44SJohn Forte 	}
815*fcf3ce44SJohn Forte 
816*fcf3ce44SJohn Forte 	/* trigger a scn */
817*fcf3ce44SJohn Forte 	if (ec == 0) {
818*fcf3ce44SJohn Forte 		if (scn_q != NULL) {
819*fcf3ce44SJohn Forte 			(void) make_scn((online == 0) ?
820*fcf3ce44SJohn Forte 			    ISNS_OBJECT_ADDED :
821*fcf3ce44SJohn Forte 			    ISNS_OBJECT_UPDATED,
822*fcf3ce44SJohn Forte 			    dst);
823*fcf3ce44SJohn Forte 		}
824*fcf3ce44SJohn Forte 		if (uid_p != NULL) {
825*fcf3ce44SJohn Forte 			*uid_p = get_obj_uid(dst);
826*fcf3ce44SJohn Forte 		}
827*fcf3ce44SJohn Forte 	}
828*fcf3ce44SJohn Forte 
829*fcf3ce44SJohn Forte 	return (ec);
830*fcf3ce44SJohn Forte }
831*fcf3ce44SJohn Forte 
832*fcf3ce44SJohn Forte /*
833*fcf3ce44SJohn Forte  * ****************************************************************************
834*fcf3ce44SJohn Forte  *
835*fcf3ce44SJohn Forte  * add_object:
836*fcf3ce44SJohn Forte  *	post function after adding a new object.
837*fcf3ce44SJohn Forte  *
838*fcf3ce44SJohn Forte  * p	- object which has been added.
839*fcf3ce44SJohn Forte  * return - error code.
840*fcf3ce44SJohn Forte  *
841*fcf3ce44SJohn Forte  * ****************************************************************************
842*fcf3ce44SJohn Forte  */
843*fcf3ce44SJohn Forte int
844*fcf3ce44SJohn Forte add_object(
845*fcf3ce44SJohn Forte 	void *p
846*fcf3ce44SJohn Forte )
847*fcf3ce44SJohn Forte {
848*fcf3ce44SJohn Forte 	int ec = 0;
849*fcf3ce44SJohn Forte 
850*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p;
851*fcf3ce44SJohn Forte 
852*fcf3ce44SJohn Forte 	/* add the new object to data store */
853*fcf3ce44SJohn Forte 	if (sys_q != NULL) {
854*fcf3ce44SJohn Forte 		ec = write_data(DATA_ADD, obj);
855*fcf3ce44SJohn Forte 	}
856*fcf3ce44SJohn Forte 
857*fcf3ce44SJohn Forte 	/* trigger a scn */
858*fcf3ce44SJohn Forte 	if (ec == 0 && scn_q != NULL) {
859*fcf3ce44SJohn Forte 		(void) make_scn(ISNS_OBJECT_ADDED, obj);
860*fcf3ce44SJohn Forte 	}
861*fcf3ce44SJohn Forte 
862*fcf3ce44SJohn Forte 	return (ec);
863*fcf3ce44SJohn Forte }
864*fcf3ce44SJohn Forte 
865*fcf3ce44SJohn Forte /*
866*fcf3ce44SJohn Forte  * ****************************************************************************
867*fcf3ce44SJohn Forte  *
868*fcf3ce44SJohn Forte  * obj_tab_init:
869*fcf3ce44SJohn Forte  *	initialize the object hash tables.
870*fcf3ce44SJohn Forte  *
871*fcf3ce44SJohn Forte  * c	- points to the cache.
872*fcf3ce44SJohn Forte  * return - error code.
873*fcf3ce44SJohn Forte  *
874*fcf3ce44SJohn Forte  * ****************************************************************************
875*fcf3ce44SJohn Forte  */
876*fcf3ce44SJohn Forte int
877*fcf3ce44SJohn Forte obj_tab_init(
878*fcf3ce44SJohn Forte 	struct cache *c
879*fcf3ce44SJohn Forte )
880*fcf3ce44SJohn Forte {
881*fcf3ce44SJohn Forte 	htab_t *t;
882*fcf3ce44SJohn Forte 
883*fcf3ce44SJohn Forte 	htab_init();
884*fcf3ce44SJohn Forte 
885*fcf3ce44SJohn Forte 	/*
886*fcf3ce44SJohn Forte 	 * allocate an array of pointer for the object hash tables.
887*fcf3ce44SJohn Forte 	 */
888*fcf3ce44SJohn Forte 	c->t = (struct htab **)calloc(sizeof (struct htab *), MAX_OBJ_TYPE);
889*fcf3ce44SJohn Forte 	if (c->t == NULL) {
890*fcf3ce44SJohn Forte 		return (1);
891*fcf3ce44SJohn Forte 	}
892*fcf3ce44SJohn Forte 
893*fcf3ce44SJohn Forte 	/*
894*fcf3ce44SJohn Forte 	 * hash table for network entity objects.
895*fcf3ce44SJohn Forte 	 */
896*fcf3ce44SJohn Forte 	t = htab_create(UID_FLAGS_SEQ, 8, 1);
897*fcf3ce44SJohn Forte 	if (t != NULL) {
898*fcf3ce44SJohn Forte 		t->c = c;
899*fcf3ce44SJohn Forte 		c->t[OBJ_ENTITY] = t;
900*fcf3ce44SJohn Forte 	} else {
901*fcf3ce44SJohn Forte 		return (1);
902*fcf3ce44SJohn Forte 	}
903*fcf3ce44SJohn Forte 
904*fcf3ce44SJohn Forte 	/*
905*fcf3ce44SJohn Forte 	 * hash table for iscsi storage node objects.
906*fcf3ce44SJohn Forte 	 */
907*fcf3ce44SJohn Forte 	t = htab_create(UID_FLAGS_SEQ, 8, 1);
908*fcf3ce44SJohn Forte 	if (t != NULL) {
909*fcf3ce44SJohn Forte 		t->c = c;
910*fcf3ce44SJohn Forte 		c->t[OBJ_ISCSI] = t;
911*fcf3ce44SJohn Forte 	} else {
912*fcf3ce44SJohn Forte 		return (1);
913*fcf3ce44SJohn Forte 	}
914*fcf3ce44SJohn Forte 
915*fcf3ce44SJohn Forte 	/*
916*fcf3ce44SJohn Forte 	 * hash table for portal objects.
917*fcf3ce44SJohn Forte 	 */
918*fcf3ce44SJohn Forte 	t = htab_create(UID_FLAGS_SEQ, 8, 1);
919*fcf3ce44SJohn Forte 	if (t != NULL) {
920*fcf3ce44SJohn Forte 		t->c = c;
921*fcf3ce44SJohn Forte 		c->t[OBJ_PORTAL] = t;
922*fcf3ce44SJohn Forte 	} else {
923*fcf3ce44SJohn Forte 		return (1);
924*fcf3ce44SJohn Forte 	}
925*fcf3ce44SJohn Forte 
926*fcf3ce44SJohn Forte 	/*
927*fcf3ce44SJohn Forte 	 * hash table for portal group objects.
928*fcf3ce44SJohn Forte 	 */
929*fcf3ce44SJohn Forte 	t = htab_create(UID_FLAGS_SEQ, 8, 2);
930*fcf3ce44SJohn Forte 	if (t != NULL) {
931*fcf3ce44SJohn Forte 		t->c = c;
932*fcf3ce44SJohn Forte 		c->t[OBJ_PG] = t;
933*fcf3ce44SJohn Forte 	} else {
934*fcf3ce44SJohn Forte 		return (1);
935*fcf3ce44SJohn Forte 	}
936*fcf3ce44SJohn Forte 
937*fcf3ce44SJohn Forte 	/*
938*fcf3ce44SJohn Forte 	 * hash table for discovery domain objects.
939*fcf3ce44SJohn Forte 	 */
940*fcf3ce44SJohn Forte 	t = htab_create(0, 6, 1);
941*fcf3ce44SJohn Forte 	if (t != NULL) {
942*fcf3ce44SJohn Forte 		t->c = c;
943*fcf3ce44SJohn Forte 		c->t[OBJ_DD] = t;
944*fcf3ce44SJohn Forte 	} else {
945*fcf3ce44SJohn Forte 		return (1);
946*fcf3ce44SJohn Forte 	}
947*fcf3ce44SJohn Forte 
948*fcf3ce44SJohn Forte 	/*
949*fcf3ce44SJohn Forte 	 * hash table for discovery domain set objects.
950*fcf3ce44SJohn Forte 	 */
951*fcf3ce44SJohn Forte 	t = htab_create(0, 4, 1);
952*fcf3ce44SJohn Forte 	if (t != NULL) {
953*fcf3ce44SJohn Forte 		t->c = c;
954*fcf3ce44SJohn Forte 		c->t[OBJ_DDS] = t;
955*fcf3ce44SJohn Forte 	} else {
956*fcf3ce44SJohn Forte 		return (1);
957*fcf3ce44SJohn Forte 	}
958*fcf3ce44SJohn Forte 
959*fcf3ce44SJohn Forte 	return (0);
960*fcf3ce44SJohn Forte }
961*fcf3ce44SJohn Forte 
962*fcf3ce44SJohn Forte /*
963*fcf3ce44SJohn Forte  * ****************************************************************************
964*fcf3ce44SJohn Forte  *
965*fcf3ce44SJohn Forte  * get_ref_np:
966*fcf3ce44SJohn Forte  *	get the ref pointer of the portal group object.
967*fcf3ce44SJohn Forte  *
968*fcf3ce44SJohn Forte  * obj	- portal group object.
969*fcf3ce44SJohn Forte  * return - ref pointer.
970*fcf3ce44SJohn Forte  *
971*fcf3ce44SJohn Forte  * ****************************************************************************
972*fcf3ce44SJohn Forte  */
973*fcf3ce44SJohn Forte static uint32_t *
974*fcf3ce44SJohn Forte get_ref_np(
975*fcf3ce44SJohn Forte 	isns_obj_t *obj,
976*fcf3ce44SJohn Forte 	int n
977*fcf3ce44SJohn Forte )
978*fcf3ce44SJohn Forte {
979*fcf3ce44SJohn Forte 	uint32_t *refp =
980*fcf3ce44SJohn Forte 	    obj->type == OBJ_PG ? &((isns_pg_t *)obj)->ref[n] : NULL;
981*fcf3ce44SJohn Forte 
982*fcf3ce44SJohn Forte 	return (refp);
983*fcf3ce44SJohn Forte }
984*fcf3ce44SJohn Forte 
985*fcf3ce44SJohn Forte #ifdef DEBUG
986*fcf3ce44SJohn Forte uint32_t
987*fcf3ce44SJohn Forte #else
988*fcf3ce44SJohn Forte static uint32_t
989*fcf3ce44SJohn Forte #endif
990*fcf3ce44SJohn Forte get_ref_n(
991*fcf3ce44SJohn Forte 	isns_obj_t *obj,
992*fcf3ce44SJohn Forte 	int n
993*fcf3ce44SJohn Forte )
994*fcf3ce44SJohn Forte {
995*fcf3ce44SJohn Forte 	return (*get_ref_np(obj, n));
996*fcf3ce44SJohn Forte }
997*fcf3ce44SJohn Forte 
998*fcf3ce44SJohn Forte static uint32_t *
999*fcf3ce44SJohn Forte get_ref_p(
1000*fcf3ce44SJohn Forte 	isns_obj_t *obj,
1001*fcf3ce44SJohn Forte 	isns_type_t rt
1002*fcf3ce44SJohn Forte )
1003*fcf3ce44SJohn Forte {
1004*fcf3ce44SJohn Forte 	isns_type_t t = obj->type;
1005*fcf3ce44SJohn Forte 
1006*fcf3ce44SJohn Forte 	int i = 0;
1007*fcf3ce44SJohn Forte 	while (i < NUM_OF_REF[t]) {
1008*fcf3ce44SJohn Forte 		if (rt == TYPE_OF_REF[t][i + 1]) {
1009*fcf3ce44SJohn Forte 			return (get_ref_np(obj, i));
1010*fcf3ce44SJohn Forte 		}
1011*fcf3ce44SJohn Forte 		i ++;
1012*fcf3ce44SJohn Forte 	}
1013*fcf3ce44SJohn Forte 
1014*fcf3ce44SJohn Forte 	return (NULL);
1015*fcf3ce44SJohn Forte }
1016*fcf3ce44SJohn Forte 
1017*fcf3ce44SJohn Forte uint32_t
1018*fcf3ce44SJohn Forte get_ref_t(
1019*fcf3ce44SJohn Forte 	isns_obj_t *obj,
1020*fcf3ce44SJohn Forte 	isns_type_t type
1021*fcf3ce44SJohn Forte )
1022*fcf3ce44SJohn Forte {
1023*fcf3ce44SJohn Forte 	uint32_t *refp = get_ref_p(obj, type);
1024*fcf3ce44SJohn Forte 
1025*fcf3ce44SJohn Forte 	if (refp != NULL) {
1026*fcf3ce44SJohn Forte 		return (*refp);
1027*fcf3ce44SJohn Forte 	/* LINTED E_NOP_ELSE_STMT */
1028*fcf3ce44SJohn Forte 	} else {
1029*fcf3ce44SJohn Forte 		ASSERT(0);
1030*fcf3ce44SJohn Forte 	}
1031*fcf3ce44SJohn Forte 
1032*fcf3ce44SJohn Forte 	return (0);
1033*fcf3ce44SJohn Forte }
1034*fcf3ce44SJohn Forte 
1035*fcf3ce44SJohn Forte /*
1036*fcf3ce44SJohn Forte  * ****************************************************************************
1037*fcf3ce44SJohn Forte  *
1038*fcf3ce44SJohn Forte  * get_parent_p:
1039*fcf3ce44SJohn Forte  *	get the pointer of the parent object.
1040*fcf3ce44SJohn Forte  *
1041*fcf3ce44SJohn Forte  * obj	- an object.
1042*fcf3ce44SJohn Forte  * return - parent object pointer.
1043*fcf3ce44SJohn Forte  *
1044*fcf3ce44SJohn Forte  * ****************************************************************************
1045*fcf3ce44SJohn Forte  */
1046*fcf3ce44SJohn Forte uint32_t *const
1047*fcf3ce44SJohn Forte get_parent_p(
1048*fcf3ce44SJohn Forte 	const isns_obj_t *obj
1049*fcf3ce44SJohn Forte )
1050*fcf3ce44SJohn Forte {
1051*fcf3ce44SJohn Forte 	uint32_t *pp;
1052*fcf3ce44SJohn Forte 	switch (obj->type) {
1053*fcf3ce44SJohn Forte 	case OBJ_ISCSI:
1054*fcf3ce44SJohn Forte 		pp = &((isns_iscsi_t *)obj)->puid;
1055*fcf3ce44SJohn Forte 		break;
1056*fcf3ce44SJohn Forte 	case OBJ_PORTAL:
1057*fcf3ce44SJohn Forte 		pp = &((isns_portal_t *)obj)->puid;
1058*fcf3ce44SJohn Forte 		break;
1059*fcf3ce44SJohn Forte 	case OBJ_PG:
1060*fcf3ce44SJohn Forte 		pp = &((isns_pg_t *)obj)->puid;
1061*fcf3ce44SJohn Forte 		break;
1062*fcf3ce44SJohn Forte 	case OBJ_ASSOC_ISCSI:
1063*fcf3ce44SJohn Forte 		pp = &((isns_assoc_iscsi_t *)obj)->puid;
1064*fcf3ce44SJohn Forte 		break;
1065*fcf3ce44SJohn Forte 	case OBJ_ASSOC_DD:
1066*fcf3ce44SJohn Forte 		pp = &((isns_assoc_dd_t *)obj)->puid;
1067*fcf3ce44SJohn Forte 		break;
1068*fcf3ce44SJohn Forte 	default:
1069*fcf3ce44SJohn Forte 		pp = NULL;
1070*fcf3ce44SJohn Forte 		break;
1071*fcf3ce44SJohn Forte 	}
1072*fcf3ce44SJohn Forte 
1073*fcf3ce44SJohn Forte 	return (pp);
1074*fcf3ce44SJohn Forte }
1075*fcf3ce44SJohn Forte 
1076*fcf3ce44SJohn Forte uint32_t
1077*fcf3ce44SJohn Forte get_parent_uid(
1078*fcf3ce44SJohn Forte 	const isns_obj_t *obj
1079*fcf3ce44SJohn Forte )
1080*fcf3ce44SJohn Forte {
1081*fcf3ce44SJohn Forte 	uint32_t *pp = get_parent_p(obj);
1082*fcf3ce44SJohn Forte 	if (pp != NULL) {
1083*fcf3ce44SJohn Forte 		return (*pp);
1084*fcf3ce44SJohn Forte 	}
1085*fcf3ce44SJohn Forte 
1086*fcf3ce44SJohn Forte 	return (0);
1087*fcf3ce44SJohn Forte }
1088*fcf3ce44SJohn Forte 
1089*fcf3ce44SJohn Forte /*
1090*fcf3ce44SJohn Forte  * ****************************************************************************
1091*fcf3ce44SJohn Forte  *
1092*fcf3ce44SJohn Forte  * get_child_np:
1093*fcf3ce44SJohn Forte  *	get the pointer of the UID array of the n'th child of an object.
1094*fcf3ce44SJohn Forte  *
1095*fcf3ce44SJohn Forte  * obj	- an object.
1096*fcf3ce44SJohn Forte  * n	- the child index.
1097*fcf3ce44SJohn Forte  * return - the pointer of the UID array.
1098*fcf3ce44SJohn Forte  *
1099*fcf3ce44SJohn Forte  * ****************************************************************************
1100*fcf3ce44SJohn Forte  */
1101*fcf3ce44SJohn Forte static uint32_t **
1102*fcf3ce44SJohn Forte get_child_np(
1103*fcf3ce44SJohn Forte 	isns_obj_t *obj,
1104*fcf3ce44SJohn Forte 	int n
1105*fcf3ce44SJohn Forte )
1106*fcf3ce44SJohn Forte {
1107*fcf3ce44SJohn Forte 	uint32_t **pp =
1108*fcf3ce44SJohn Forte 	    obj->type == OBJ_ENTITY ? &((isns_entity_t *)obj)->cuid[n] : NULL;
1109*fcf3ce44SJohn Forte 
1110*fcf3ce44SJohn Forte 	return (pp);
1111*fcf3ce44SJohn Forte }
1112*fcf3ce44SJohn Forte 
1113*fcf3ce44SJohn Forte /*
1114*fcf3ce44SJohn Forte  * ****************************************************************************
1115*fcf3ce44SJohn Forte  *
1116*fcf3ce44SJohn Forte  * get_child_n:
1117*fcf3ce44SJohn Forte  *	get the UID array of the n'th child of an object.
1118*fcf3ce44SJohn Forte  *
1119*fcf3ce44SJohn Forte  * obj	- an object.
1120*fcf3ce44SJohn Forte  * n	- the child index.
1121*fcf3ce44SJohn Forte  * return - the UID array.
1122*fcf3ce44SJohn Forte  *
1123*fcf3ce44SJohn Forte  * ****************************************************************************
1124*fcf3ce44SJohn Forte  */
1125*fcf3ce44SJohn Forte #ifdef DEBUG
1126*fcf3ce44SJohn Forte uint32_t *
1127*fcf3ce44SJohn Forte #else
1128*fcf3ce44SJohn Forte static uint32_t *
1129*fcf3ce44SJohn Forte #endif
1130*fcf3ce44SJohn Forte get_child_n(
1131*fcf3ce44SJohn Forte 	isns_obj_t *obj,
1132*fcf3ce44SJohn Forte 	int n
1133*fcf3ce44SJohn Forte )
1134*fcf3ce44SJohn Forte {
1135*fcf3ce44SJohn Forte 	uint32_t **pp = get_child_np(obj, n);
1136*fcf3ce44SJohn Forte 
1137*fcf3ce44SJohn Forte 	if (pp != NULL) {
1138*fcf3ce44SJohn Forte 		return (*pp);
1139*fcf3ce44SJohn Forte 	}
1140*fcf3ce44SJohn Forte 
1141*fcf3ce44SJohn Forte 	ASSERT(0);
1142*fcf3ce44SJohn Forte 	return (NULL);
1143*fcf3ce44SJohn Forte }
1144*fcf3ce44SJohn Forte 
1145*fcf3ce44SJohn Forte /*
1146*fcf3ce44SJohn Forte  * ****************************************************************************
1147*fcf3ce44SJohn Forte  *
1148*fcf3ce44SJohn Forte  * get_child_p:
1149*fcf3ce44SJohn Forte  *	get the pointer of the UID array of the child matching the type.
1150*fcf3ce44SJohn Forte  *
1151*fcf3ce44SJohn Forte  * base	- an object.
1152*fcf3ce44SJohn Forte  * child_type	- the child object type.
1153*fcf3ce44SJohn Forte  * return - the pointer of the UID array.
1154*fcf3ce44SJohn Forte  *
1155*fcf3ce44SJohn Forte  * ****************************************************************************
1156*fcf3ce44SJohn Forte  */
1157*fcf3ce44SJohn Forte static uint32_t **
1158*fcf3ce44SJohn Forte get_child_p(
1159*fcf3ce44SJohn Forte 	isns_obj_t *base,
1160*fcf3ce44SJohn Forte 	int child_type
1161*fcf3ce44SJohn Forte )
1162*fcf3ce44SJohn Forte {
1163*fcf3ce44SJohn Forte 	uint32_t **pp = NULL;
1164*fcf3ce44SJohn Forte 	int i = 0;
1165*fcf3ce44SJohn Forte 	while (i < NUM_OF_CHILD[base->type]) {
1166*fcf3ce44SJohn Forte 		if (child_type == TYPE_OF_CHILD[base->type][i]) {
1167*fcf3ce44SJohn Forte 			pp = get_child_np(base, i);
1168*fcf3ce44SJohn Forte 			break;
1169*fcf3ce44SJohn Forte 		}
1170*fcf3ce44SJohn Forte 		i ++;
1171*fcf3ce44SJohn Forte 	}
1172*fcf3ce44SJohn Forte 
1173*fcf3ce44SJohn Forte 	return (pp);
1174*fcf3ce44SJohn Forte }
1175*fcf3ce44SJohn Forte 
1176*fcf3ce44SJohn Forte /*
1177*fcf3ce44SJohn Forte  * ****************************************************************************
1178*fcf3ce44SJohn Forte  *
1179*fcf3ce44SJohn Forte  * get_child_t:
1180*fcf3ce44SJohn Forte  *	get the UID array of the child object matching the type.
1181*fcf3ce44SJohn Forte  *
1182*fcf3ce44SJohn Forte  * base	- an object.
1183*fcf3ce44SJohn Forte  * child_type	- the child object type.
1184*fcf3ce44SJohn Forte  * return - the UID array.
1185*fcf3ce44SJohn Forte  *
1186*fcf3ce44SJohn Forte  * ****************************************************************************
1187*fcf3ce44SJohn Forte  */
1188*fcf3ce44SJohn Forte uint32_t *
1189*fcf3ce44SJohn Forte get_child_t(
1190*fcf3ce44SJohn Forte 	isns_obj_t *base,
1191*fcf3ce44SJohn Forte 	int child_type
1192*fcf3ce44SJohn Forte )
1193*fcf3ce44SJohn Forte {
1194*fcf3ce44SJohn Forte 	uint32_t **pp = get_child_p(base, child_type);
1195*fcf3ce44SJohn Forte 
1196*fcf3ce44SJohn Forte 	if (pp != NULL) {
1197*fcf3ce44SJohn Forte 		return (*pp);
1198*fcf3ce44SJohn Forte 	} else {
1199*fcf3ce44SJohn Forte 		return (NULL);
1200*fcf3ce44SJohn Forte 	}
1201*fcf3ce44SJohn Forte }
1202*fcf3ce44SJohn Forte 
1203*fcf3ce44SJohn Forte /*
1204*fcf3ce44SJohn Forte  * ****************************************************************************
1205*fcf3ce44SJohn Forte  *
1206*fcf3ce44SJohn Forte  * key_cmp:
1207*fcf3ce44SJohn Forte  *	compare the object against the lookup control data.
1208*fcf3ce44SJohn Forte  *
1209*fcf3ce44SJohn Forte  * lcp	- the lookup control data.
1210*fcf3ce44SJohn Forte  * obj	- an object.
1211*fcf3ce44SJohn Forte  * return - comparison result.
1212*fcf3ce44SJohn Forte  *
1213*fcf3ce44SJohn Forte  * ****************************************************************************
1214*fcf3ce44SJohn Forte  */
1215*fcf3ce44SJohn Forte int
1216*fcf3ce44SJohn Forte key_cmp(
1217*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
1218*fcf3ce44SJohn Forte 	isns_obj_t *obj
1219*fcf3ce44SJohn Forte )
1220*fcf3ce44SJohn Forte {
1221*fcf3ce44SJohn Forte 	int i = 0;
1222*fcf3ce44SJohn Forte 	int match = 1;
1223*fcf3ce44SJohn Forte 	while (i < MAX_LOOKUP_CTRL && lcp->op[i] > 0 && match) {
1224*fcf3ce44SJohn Forte 		isns_attr_t *attr = &obj->attrs[lcp->id[i]];
1225*fcf3ce44SJohn Forte 		switch (lcp->op[i]) {
1226*fcf3ce44SJohn Forte 			case OP_STRING:
1227*fcf3ce44SJohn Forte 				match = (strcmp((const char *)lcp->data[i].ptr,
1228*fcf3ce44SJohn Forte 				    (const char *)attr->value.ptr) == 0);
1229*fcf3ce44SJohn Forte 				break;
1230*fcf3ce44SJohn Forte 			case OP_INTEGER:
1231*fcf3ce44SJohn Forte 				match = (lcp->data[i].ui == attr->value.ui);
1232*fcf3ce44SJohn Forte 				break;
1233*fcf3ce44SJohn Forte 			case OP_MEMORY_IP6:
1234*fcf3ce44SJohn Forte 				match = !memcmp((void *)lcp->data[i].ip,
1235*fcf3ce44SJohn Forte 				    (void *)attr->value.ip,
1236*fcf3ce44SJohn Forte 				    sizeof (in6_addr_t));
1237*fcf3ce44SJohn Forte 				break;
1238*fcf3ce44SJohn Forte 			default:
1239*fcf3ce44SJohn Forte 				ASSERT(0);
1240*fcf3ce44SJohn Forte 				match = 0;
1241*fcf3ce44SJohn Forte 				break;
1242*fcf3ce44SJohn Forte 		}
1243*fcf3ce44SJohn Forte 		i ++;
1244*fcf3ce44SJohn Forte 	}
1245*fcf3ce44SJohn Forte 
1246*fcf3ce44SJohn Forte 	if (i && match) {
1247*fcf3ce44SJohn Forte 		return (0);
1248*fcf3ce44SJohn Forte 	} else {
1249*fcf3ce44SJohn Forte 		return (1);
1250*fcf3ce44SJohn Forte 	}
1251*fcf3ce44SJohn Forte }
1252*fcf3ce44SJohn Forte 
1253*fcf3ce44SJohn Forte /*
1254*fcf3ce44SJohn Forte  * ****************************************************************************
1255*fcf3ce44SJohn Forte  *
1256*fcf3ce44SJohn Forte  * set_lookup_ctrl:
1257*fcf3ce44SJohn Forte  *	fill in the lookup control data for an object.
1258*fcf3ce44SJohn Forte  *
1259*fcf3ce44SJohn Forte  * lcp	- the lookup control data.
1260*fcf3ce44SJohn Forte  * obj	- an object.
1261*fcf3ce44SJohn Forte  * return - the lookup control data.
1262*fcf3ce44SJohn Forte  *
1263*fcf3ce44SJohn Forte  * ****************************************************************************
1264*fcf3ce44SJohn Forte  */
1265*fcf3ce44SJohn Forte static lookup_ctrl_t *
1266*fcf3ce44SJohn Forte set_lookup_ctrl(
1267*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
1268*fcf3ce44SJohn Forte 	isns_obj_t *obj
1269*fcf3ce44SJohn Forte )
1270*fcf3ce44SJohn Forte {
1271*fcf3ce44SJohn Forte 	isns_type_t type = obj->type;
1272*fcf3ce44SJohn Forte 	uint32_t id, op;
1273*fcf3ce44SJohn Forte 	int i = 0;
1274*fcf3ce44SJohn Forte 
1275*fcf3ce44SJohn Forte 	lcp->type = type;
1276*fcf3ce44SJohn Forte 	while (i < MAX_KEY_ATTRS) {
1277*fcf3ce44SJohn Forte 		op = KEY_ATTR_OP[type][i];
1278*fcf3ce44SJohn Forte 		if (op != 0) {
1279*fcf3ce44SJohn Forte 			id = KEY_ATTR_INDEX[type][i];
1280*fcf3ce44SJohn Forte 			lcp->id[i] = id;
1281*fcf3ce44SJohn Forte 			lcp->op[i] = op;
1282*fcf3ce44SJohn Forte 			lcp->data[i].ui = obj->attrs[id].value.ui;
1283*fcf3ce44SJohn Forte 		} else {
1284*fcf3ce44SJohn Forte 			break;
1285*fcf3ce44SJohn Forte 		}
1286*fcf3ce44SJohn Forte 		i ++;
1287*fcf3ce44SJohn Forte 	}
1288*fcf3ce44SJohn Forte 
1289*fcf3ce44SJohn Forte 	return (lcp);
1290*fcf3ce44SJohn Forte }
1291*fcf3ce44SJohn Forte 
1292*fcf3ce44SJohn Forte /*
1293*fcf3ce44SJohn Forte  * ****************************************************************************
1294*fcf3ce44SJohn Forte  *
1295*fcf3ce44SJohn Forte  * assign_attr:
1296*fcf3ce44SJohn Forte  *	assign an attribute.
1297*fcf3ce44SJohn Forte  *
1298*fcf3ce44SJohn Forte  * attr	- the attribute being assigned.
1299*fcf3ce44SJohn Forte  * tmp	- the attribute.
1300*fcf3ce44SJohn Forte  * return - error code.
1301*fcf3ce44SJohn Forte  *
1302*fcf3ce44SJohn Forte  * ****************************************************************************
1303*fcf3ce44SJohn Forte  */
1304*fcf3ce44SJohn Forte int
1305*fcf3ce44SJohn Forte assign_attr(
1306*fcf3ce44SJohn Forte 	isns_attr_t *attr,
1307*fcf3ce44SJohn Forte 	const isns_attr_t *tmp
1308*fcf3ce44SJohn Forte )
1309*fcf3ce44SJohn Forte {
1310*fcf3ce44SJohn Forte 	uint32_t t;
1311*fcf3ce44SJohn Forte 
1312*fcf3ce44SJohn Forte 	switch (tmp->tag) {
1313*fcf3ce44SJohn Forte 	case ISNS_EID_ATTR_ID:
1314*fcf3ce44SJohn Forte 	case ISNS_DD_SET_NAME_ATTR_ID:
1315*fcf3ce44SJohn Forte 	case ISNS_DD_NAME_ATTR_ID:
1316*fcf3ce44SJohn Forte 		if (tmp->len == 0 && attr->len == 0) {
1317*fcf3ce44SJohn Forte 			int len;
1318*fcf3ce44SJohn Forte 			char *name = make_unique_name(&len, tmp->tag);
1319*fcf3ce44SJohn Forte 			if (name != NULL) {
1320*fcf3ce44SJohn Forte 				attr->value.ptr = (uchar_t *)name;
1321*fcf3ce44SJohn Forte 				attr->tag = tmp->tag;
1322*fcf3ce44SJohn Forte 				attr->len = len;
1323*fcf3ce44SJohn Forte 			} else {
1324*fcf3ce44SJohn Forte 				/* memory exhausted */
1325*fcf3ce44SJohn Forte 				return (1);
1326*fcf3ce44SJohn Forte 			}
1327*fcf3ce44SJohn Forte 		}
1328*fcf3ce44SJohn Forte 	case ISNS_PORTAL_NAME_ATTR_ID:
1329*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NAME_ATTR_ID:
1330*fcf3ce44SJohn Forte 	case ISNS_ISCSI_ALIAS_ATTR_ID:
1331*fcf3ce44SJohn Forte 	case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
1332*fcf3ce44SJohn Forte 	case ISNS_PG_ISCSI_NAME_ATTR_ID:
1333*fcf3ce44SJohn Forte 	case ISNS_DD_ISCSI_NAME_ATTR_ID:
1334*fcf3ce44SJohn Forte 		if (tmp->len == 0) {
1335*fcf3ce44SJohn Forte 			return (0);
1336*fcf3ce44SJohn Forte 		} else if (tmp->len > attr->len) {
1337*fcf3ce44SJohn Forte 			attr->value.ptr = realloc(attr->value.ptr, tmp->len);
1338*fcf3ce44SJohn Forte 		}
1339*fcf3ce44SJohn Forte 		if (attr->value.ptr != NULL) {
1340*fcf3ce44SJohn Forte 			(void) strcpy((char *)attr->value.ptr,
1341*fcf3ce44SJohn Forte 			    (char *)tmp->value.ptr);
1342*fcf3ce44SJohn Forte 			attr->tag = tmp->tag;
1343*fcf3ce44SJohn Forte 			attr->len = tmp->len;
1344*fcf3ce44SJohn Forte 		} else {
1345*fcf3ce44SJohn Forte 			/* memory exhausted */
1346*fcf3ce44SJohn Forte 			return (1);
1347*fcf3ce44SJohn Forte 		}
1348*fcf3ce44SJohn Forte 		break;
1349*fcf3ce44SJohn Forte 	case ISNS_MGMT_IP_ADDR_ATTR_ID:
1350*fcf3ce44SJohn Forte 	case ISNS_PORTAL_IP_ADDR_ATTR_ID:
1351*fcf3ce44SJohn Forte 	case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
1352*fcf3ce44SJohn Forte 		if (attr->value.ip == NULL) {
1353*fcf3ce44SJohn Forte 			attr->value.ip = (in6_addr_t *)calloc(1, tmp->len);
1354*fcf3ce44SJohn Forte 		}
1355*fcf3ce44SJohn Forte 		if (attr->value.ip != NULL) {
1356*fcf3ce44SJohn Forte 			(void) memcpy((void *)attr->value.ip,
1357*fcf3ce44SJohn Forte 			    (void *)tmp->value.ip, tmp->len);
1358*fcf3ce44SJohn Forte 			attr->tag = tmp->tag;
1359*fcf3ce44SJohn Forte 			attr->len = tmp->len;
1360*fcf3ce44SJohn Forte 		} else {
1361*fcf3ce44SJohn Forte 			/* memory exhausted */
1362*fcf3ce44SJohn Forte 			return (1);
1363*fcf3ce44SJohn Forte 		}
1364*fcf3ce44SJohn Forte 		break;
1365*fcf3ce44SJohn Forte 	case ISNS_ENTITY_INDEX_ATTR_ID:
1366*fcf3ce44SJohn Forte 	case ISNS_PORTAL_INDEX_ATTR_ID:
1367*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
1368*fcf3ce44SJohn Forte 	case ISNS_PG_INDEX_ATTR_ID:
1369*fcf3ce44SJohn Forte 	case ISNS_DD_SET_ID_ATTR_ID:
1370*fcf3ce44SJohn Forte 	case ISNS_DD_ID_ATTR_ID:
1371*fcf3ce44SJohn Forte 		if (attr->value.ui != 0) {
1372*fcf3ce44SJohn Forte 			break;
1373*fcf3ce44SJohn Forte 		}
1374*fcf3ce44SJohn Forte 	case ISNS_ENTITY_PROTOCOL_ATTR_ID:
1375*fcf3ce44SJohn Forte 	case ISNS_VERSION_RANGE_ATTR_ID:
1376*fcf3ce44SJohn Forte 
1377*fcf3ce44SJohn Forte 	case ISNS_PORTAL_PORT_ATTR_ID:
1378*fcf3ce44SJohn Forte 	case ISNS_ESI_PORT_ATTR_ID:
1379*fcf3ce44SJohn Forte 	case ISNS_SCN_PORT_ATTR_ID:
1380*fcf3ce44SJohn Forte 
1381*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
1382*fcf3ce44SJohn Forte 	case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
1383*fcf3ce44SJohn Forte 
1384*fcf3ce44SJohn Forte 	case ISNS_PG_PORTAL_PORT_ATTR_ID:
1385*fcf3ce44SJohn Forte 	case ISNS_PG_TAG_ATTR_ID:
1386*fcf3ce44SJohn Forte 
1387*fcf3ce44SJohn Forte 	case ISNS_DD_SET_STATUS_ATTR_ID:
1388*fcf3ce44SJohn Forte 	case ISNS_DD_ISCSI_INDEX_ATTR_ID:
1389*fcf3ce44SJohn Forte 		attr->tag = tmp->tag;
1390*fcf3ce44SJohn Forte 		attr->len = tmp->len;
1391*fcf3ce44SJohn Forte 		attr->value.ui = tmp->value.ui;
1392*fcf3ce44SJohn Forte 		break;
1393*fcf3ce44SJohn Forte 	case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
1394*fcf3ce44SJohn Forte 		attr->tag = tmp->tag;
1395*fcf3ce44SJohn Forte 		attr->len = tmp->len;
1396*fcf3ce44SJohn Forte 		attr->value.ui = tmp->value.ui;
1397*fcf3ce44SJohn Forte 		t = get_reg_period();
1398*fcf3ce44SJohn Forte 		if (attr->value.ui > t) {
1399*fcf3ce44SJohn Forte 			attr->value.ui = t;
1400*fcf3ce44SJohn Forte 		} else if (attr->value.ui < ONE_DAY) {
1401*fcf3ce44SJohn Forte 			attr->value.ui = ONE_DAY;
1402*fcf3ce44SJohn Forte 		}
1403*fcf3ce44SJohn Forte 		break;
1404*fcf3ce44SJohn Forte 	case ISNS_ESI_INTERVAL_ATTR_ID:
1405*fcf3ce44SJohn Forte 		attr->tag = tmp->tag;
1406*fcf3ce44SJohn Forte 		attr->len = tmp->len;
1407*fcf3ce44SJohn Forte 		attr->value.ui = tmp->value.ui;
1408*fcf3ce44SJohn Forte 		if (attr->value.ui > ONE_DAY) {
1409*fcf3ce44SJohn Forte 			attr->value.ui = ONE_DAY;
1410*fcf3ce44SJohn Forte 		} else if (attr->value.ui < MIN_ESI_INTVAL) {
1411*fcf3ce44SJohn Forte 			attr->value.ui = MIN_ESI_INTVAL; /* 20 seconds */
1412*fcf3ce44SJohn Forte 		}
1413*fcf3ce44SJohn Forte 		break;
1414*fcf3ce44SJohn Forte 	default:
1415*fcf3ce44SJohn Forte 		ASSERT(0);
1416*fcf3ce44SJohn Forte 		/* don't assign the attribute */
1417*fcf3ce44SJohn Forte 		break;
1418*fcf3ce44SJohn Forte 	}
1419*fcf3ce44SJohn Forte 	return (0);
1420*fcf3ce44SJohn Forte }
1421*fcf3ce44SJohn Forte 
1422*fcf3ce44SJohn Forte /*
1423*fcf3ce44SJohn Forte  * ****************************************************************************
1424*fcf3ce44SJohn Forte  *
1425*fcf3ce44SJohn Forte  * copy_attrs:
1426*fcf3ce44SJohn Forte  *	copy all of attributes from one object to another.
1427*fcf3ce44SJohn Forte  *
1428*fcf3ce44SJohn Forte  * dst	- the destination object.
1429*fcf3ce44SJohn Forte  * tmp	- the source object.
1430*fcf3ce44SJohn Forte  * return - error code.
1431*fcf3ce44SJohn Forte  *
1432*fcf3ce44SJohn Forte  * ****************************************************************************
1433*fcf3ce44SJohn Forte  */
1434*fcf3ce44SJohn Forte static int
1435*fcf3ce44SJohn Forte copy_attrs(
1436*fcf3ce44SJohn Forte 	isns_obj_t *dst,
1437*fcf3ce44SJohn Forte 	const isns_obj_t *src
1438*fcf3ce44SJohn Forte )
1439*fcf3ce44SJohn Forte {
1440*fcf3ce44SJohn Forte 	int i = 0;
1441*fcf3ce44SJohn Forte 	int n = NUM_OF_ATTRS[dst->type];
1442*fcf3ce44SJohn Forte 
1443*fcf3ce44SJohn Forte 	isns_attr_t *dst_attr;
1444*fcf3ce44SJohn Forte 	const isns_attr_t *src_attr;
1445*fcf3ce44SJohn Forte 
1446*fcf3ce44SJohn Forte 	while (i < n) {
1447*fcf3ce44SJohn Forte 		src_attr = &(src->attrs[i]);
1448*fcf3ce44SJohn Forte 		if (src_attr->tag != 0) {
1449*fcf3ce44SJohn Forte 			dst_attr = &(dst->attrs[i]);
1450*fcf3ce44SJohn Forte 			if (assign_attr(dst_attr, src_attr) != 0) {
1451*fcf3ce44SJohn Forte 				return (1);
1452*fcf3ce44SJohn Forte 			}
1453*fcf3ce44SJohn Forte 		}
1454*fcf3ce44SJohn Forte 		i ++;
1455*fcf3ce44SJohn Forte 	}
1456*fcf3ce44SJohn Forte 
1457*fcf3ce44SJohn Forte 	return (0);
1458*fcf3ce44SJohn Forte }
1459*fcf3ce44SJohn Forte 
1460*fcf3ce44SJohn Forte /*
1461*fcf3ce44SJohn Forte  * ****************************************************************************
1462*fcf3ce44SJohn Forte  *
1463*fcf3ce44SJohn Forte  * extract_attr:
1464*fcf3ce44SJohn Forte  *	extract an attribute from a TLV format data.
1465*fcf3ce44SJohn Forte  *
1466*fcf3ce44SJohn Forte  * attr	- the attribute.
1467*fcf3ce44SJohn Forte  * tlv	- the TLV format data.
1468*fcf3ce44SJohn Forte  * return - error code.
1469*fcf3ce44SJohn Forte  *
1470*fcf3ce44SJohn Forte  * ****************************************************************************
1471*fcf3ce44SJohn Forte  */
1472*fcf3ce44SJohn Forte int
1473*fcf3ce44SJohn Forte extract_attr(
1474*fcf3ce44SJohn Forte 	isns_attr_t *attr,
1475*fcf3ce44SJohn Forte 	const isns_tlv_t *tlv,
1476*fcf3ce44SJohn Forte 	int flag
1477*fcf3ce44SJohn Forte )
1478*fcf3ce44SJohn Forte {
1479*fcf3ce44SJohn Forte 	int ec = 0;
1480*fcf3ce44SJohn Forte 
1481*fcf3ce44SJohn Forte 	uint32_t min_len = 4, max_len = 224;
1482*fcf3ce44SJohn Forte 
1483*fcf3ce44SJohn Forte 	switch (tlv->attr_id) {
1484*fcf3ce44SJohn Forte 	case ISNS_EID_ATTR_ID:
1485*fcf3ce44SJohn Forte 		min_len = 0;
1486*fcf3ce44SJohn Forte 	case ISNS_PORTAL_NAME_ATTR_ID:
1487*fcf3ce44SJohn Forte 	case ISNS_ISCSI_ALIAS_ATTR_ID:
1488*fcf3ce44SJohn Forte 	case ISNS_DD_SET_NAME_ATTR_ID:
1489*fcf3ce44SJohn Forte 	case ISNS_DD_NAME_ATTR_ID:
1490*fcf3ce44SJohn Forte 		max_len = 256;
1491*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NAME_ATTR_ID:
1492*fcf3ce44SJohn Forte 	case ISNS_PG_ISCSI_NAME_ATTR_ID:
1493*fcf3ce44SJohn Forte 		if (tlv->attr_len < min_len || tlv->attr_len > max_len) {
1494*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
1495*fcf3ce44SJohn Forte 		} else {
1496*fcf3ce44SJohn Forte 			attr->tag = tlv->attr_id;
1497*fcf3ce44SJohn Forte 			attr->len = tlv->attr_len;
1498*fcf3ce44SJohn Forte 			attr->value.ptr = (uchar_t *)&(tlv->attr_value[0]);
1499*fcf3ce44SJohn Forte 		}
1500*fcf3ce44SJohn Forte 		break;
1501*fcf3ce44SJohn Forte 	case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
1502*fcf3ce44SJohn Forte 		attr->tag = tlv->attr_id;
1503*fcf3ce44SJohn Forte 		attr->len = tlv->attr_len;
1504*fcf3ce44SJohn Forte 		attr->value.ptr = (uchar_t *)&(tlv->attr_value[0]);
1505*fcf3ce44SJohn Forte 		break;
1506*fcf3ce44SJohn Forte 	case ISNS_MGMT_IP_ADDR_ATTR_ID:
1507*fcf3ce44SJohn Forte 	case ISNS_PORTAL_IP_ADDR_ATTR_ID:
1508*fcf3ce44SJohn Forte 	case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
1509*fcf3ce44SJohn Forte 		if (tlv->attr_len != 16) {
1510*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
1511*fcf3ce44SJohn Forte 		} else {
1512*fcf3ce44SJohn Forte 			attr->tag = tlv->attr_id;
1513*fcf3ce44SJohn Forte 			attr->len = tlv->attr_len;
1514*fcf3ce44SJohn Forte 			attr->value.ip = (void *)&(tlv->attr_value[0]);
1515*fcf3ce44SJohn Forte 		}
1516*fcf3ce44SJohn Forte 		break;
1517*fcf3ce44SJohn Forte 	case ISNS_ENTITY_PROTOCOL_ATTR_ID:
1518*fcf3ce44SJohn Forte 	case ISNS_VERSION_RANGE_ATTR_ID:
1519*fcf3ce44SJohn Forte 	case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
1520*fcf3ce44SJohn Forte 		/* fall throught */
1521*fcf3ce44SJohn Forte 	case ISNS_PORTAL_PORT_ATTR_ID:
1522*fcf3ce44SJohn Forte 	case ISNS_ESI_INTERVAL_ATTR_ID:
1523*fcf3ce44SJohn Forte 	case ISNS_ESI_PORT_ATTR_ID:
1524*fcf3ce44SJohn Forte 	case ISNS_SCN_PORT_ATTR_ID:
1525*fcf3ce44SJohn Forte 		/* fall throught */
1526*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
1527*fcf3ce44SJohn Forte 		/* fall throught */
1528*fcf3ce44SJohn Forte 	case ISNS_PG_PORTAL_PORT_ATTR_ID:
1529*fcf3ce44SJohn Forte 		/* fall throught */
1530*fcf3ce44SJohn Forte 	case ISNS_DD_SET_ID_ATTR_ID:
1531*fcf3ce44SJohn Forte 	case ISNS_DD_SET_STATUS_ATTR_ID:
1532*fcf3ce44SJohn Forte 		/* fall throught */
1533*fcf3ce44SJohn Forte 	case ISNS_DD_ID_ATTR_ID:
1534*fcf3ce44SJohn Forte 		if (tlv->attr_len != 4) {
1535*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
1536*fcf3ce44SJohn Forte 			break;
1537*fcf3ce44SJohn Forte 		}
1538*fcf3ce44SJohn Forte 	case ISNS_PG_TAG_ATTR_ID:
1539*fcf3ce44SJohn Forte 		attr->tag = tlv->attr_id;
1540*fcf3ce44SJohn Forte 		attr->len = tlv->attr_len;
1541*fcf3ce44SJohn Forte 		if (tlv->attr_len == 4) {
1542*fcf3ce44SJohn Forte 			attr->value.ui = ntohl(*(uint32_t *)
1543*fcf3ce44SJohn Forte 			    &(tlv->attr_value[0]));
1544*fcf3ce44SJohn Forte 		} else {
1545*fcf3ce44SJohn Forte 			attr->value.ui = 0;
1546*fcf3ce44SJohn Forte 		}
1547*fcf3ce44SJohn Forte 		break;
1548*fcf3ce44SJohn Forte 	case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
1549*fcf3ce44SJohn Forte 		/* ignore scn bitmap attribute during object registration, */
1550*fcf3ce44SJohn Forte 		/* it is registered by scn_reg message. */
1551*fcf3ce44SJohn Forte 	case ISNS_ENTITY_ISAKMP_P1_ATTR_ID:
1552*fcf3ce44SJohn Forte 	case ISNS_ENTITY_CERT_ATTR_ID:
1553*fcf3ce44SJohn Forte 	case ISNS_PORTAL_SEC_BMP_ATTR_ID:
1554*fcf3ce44SJohn Forte 	case ISNS_PORTAL_ISAKMP_P1_ATTR_ID:
1555*fcf3ce44SJohn Forte 	case ISNS_PORTAL_ISAKMP_P2_ATTR_ID:
1556*fcf3ce44SJohn Forte 	case ISNS_PORTAL_CERT_ATTR_ID:
1557*fcf3ce44SJohn Forte 		break;
1558*fcf3ce44SJohn Forte 	case ISNS_PORTAL_INDEX_ATTR_ID:
1559*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
1560*fcf3ce44SJohn Forte 	case ISNS_PG_INDEX_ATTR_ID:
1561*fcf3ce44SJohn Forte 		if (flag == 0) {
1562*fcf3ce44SJohn Forte 			if (tlv->attr_len != 4) {
1563*fcf3ce44SJohn Forte 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
1564*fcf3ce44SJohn Forte 			} else {
1565*fcf3ce44SJohn Forte 				attr->tag = tlv->attr_id;
1566*fcf3ce44SJohn Forte 				attr->len = tlv->attr_len;
1567*fcf3ce44SJohn Forte 				attr->value.ui = ntohl(*(uint32_t *)
1568*fcf3ce44SJohn Forte 				    &(tlv->attr_value[0]));
1569*fcf3ce44SJohn Forte 			}
1570*fcf3ce44SJohn Forte 			break;
1571*fcf3ce44SJohn Forte 		}
1572*fcf3ce44SJohn Forte 	case ISNS_ENTITY_INDEX_ATTR_ID:
1573*fcf3ce44SJohn Forte 	case ISNS_TIMESTAMP_ATTR_ID:
1574*fcf3ce44SJohn Forte 	default:
1575*fcf3ce44SJohn Forte 		if (flag == 0) {
1576*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INVALID_QRY;
1577*fcf3ce44SJohn Forte 		} else {
1578*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INVALID_REGIS;
1579*fcf3ce44SJohn Forte 		}
1580*fcf3ce44SJohn Forte 		break;
1581*fcf3ce44SJohn Forte 	}
1582*fcf3ce44SJohn Forte 
1583*fcf3ce44SJohn Forte 	return (ec);
1584*fcf3ce44SJohn Forte }
1585*fcf3ce44SJohn Forte 
1586*fcf3ce44SJohn Forte /*
1587*fcf3ce44SJohn Forte  * ****************************************************************************
1588*fcf3ce44SJohn Forte  *
1589*fcf3ce44SJohn Forte  * copy_attr:
1590*fcf3ce44SJohn Forte  *	copy an attribute from a TLV format data.
1591*fcf3ce44SJohn Forte  *
1592*fcf3ce44SJohn Forte  * attr	- the attribute.
1593*fcf3ce44SJohn Forte  * tlv	- the TLV format data.
1594*fcf3ce44SJohn Forte  * return - error code.
1595*fcf3ce44SJohn Forte  *
1596*fcf3ce44SJohn Forte  * ****************************************************************************
1597*fcf3ce44SJohn Forte  */
1598*fcf3ce44SJohn Forte static int
1599*fcf3ce44SJohn Forte copy_attr(
1600*fcf3ce44SJohn Forte 	isns_attr_t *attr,
1601*fcf3ce44SJohn Forte 	const isns_tlv_t *tlv
1602*fcf3ce44SJohn Forte )
1603*fcf3ce44SJohn Forte {
1604*fcf3ce44SJohn Forte 	int ec = 0;
1605*fcf3ce44SJohn Forte 
1606*fcf3ce44SJohn Forte 	isns_attr_t tmp = { 0 };
1607*fcf3ce44SJohn Forte 
1608*fcf3ce44SJohn Forte 	/* extract the attribute first */
1609*fcf3ce44SJohn Forte 	ec = extract_attr(&tmp, tlv, 1);
1610*fcf3ce44SJohn Forte 
1611*fcf3ce44SJohn Forte 	/* assign the attribute */
1612*fcf3ce44SJohn Forte 	if (ec == 0 && tmp.tag != 0) {
1613*fcf3ce44SJohn Forte 		if (assign_attr(attr, &tmp) != 0) {
1614*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
1615*fcf3ce44SJohn Forte 		}
1616*fcf3ce44SJohn Forte 	}
1617*fcf3ce44SJohn Forte 
1618*fcf3ce44SJohn Forte 	return (ec);
1619*fcf3ce44SJohn Forte }
1620*fcf3ce44SJohn Forte 
1621*fcf3ce44SJohn Forte /*
1622*fcf3ce44SJohn Forte  * ****************************************************************************
1623*fcf3ce44SJohn Forte  *
1624*fcf3ce44SJohn Forte  * get_timestamp:
1625*fcf3ce44SJohn Forte  *	get current timestamp.
1626*fcf3ce44SJohn Forte  *
1627*fcf3ce44SJohn Forte  * return - current timestamp.
1628*fcf3ce44SJohn Forte  *
1629*fcf3ce44SJohn Forte  * ****************************************************************************
1630*fcf3ce44SJohn Forte  */
1631*fcf3ce44SJohn Forte uint32_t
1632*fcf3ce44SJohn Forte get_timestamp(
1633*fcf3ce44SJohn Forte )
1634*fcf3ce44SJohn Forte {
1635*fcf3ce44SJohn Forte 	uint32_t t;
1636*fcf3ce44SJohn Forte 	int flag;
1637*fcf3ce44SJohn Forte 
1638*fcf3ce44SJohn Forte 	/* block the scheduler */
1639*fcf3ce44SJohn Forte 	(void) pthread_mutex_lock(&el_mtx);
1640*fcf3ce44SJohn Forte 
1641*fcf3ce44SJohn Forte 	/* get most current time */
1642*fcf3ce44SJohn Forte 	if (sys_q != NULL) {
1643*fcf3ce44SJohn Forte 		/* need to wakeup idle */
1644*fcf3ce44SJohn Forte 		flag = 1;
1645*fcf3ce44SJohn Forte 	} else {
1646*fcf3ce44SJohn Forte 		flag = 0;
1647*fcf3ce44SJohn Forte 	}
1648*fcf3ce44SJohn Forte 	t = get_stopwatch(flag);
1649*fcf3ce44SJohn Forte 
1650*fcf3ce44SJohn Forte 	/* unblock it */
1651*fcf3ce44SJohn Forte 	(void) pthread_mutex_unlock(&el_mtx);
1652*fcf3ce44SJohn Forte 
1653*fcf3ce44SJohn Forte 	return (t);
1654*fcf3ce44SJohn Forte }
1655*fcf3ce44SJohn Forte 
1656*fcf3ce44SJohn Forte /*
1657*fcf3ce44SJohn Forte  * ****************************************************************************
1658*fcf3ce44SJohn Forte  *
1659*fcf3ce44SJohn Forte  * get_reg_period:
1660*fcf3ce44SJohn Forte  *	get the longest registration period.
1661*fcf3ce44SJohn Forte  *
1662*fcf3ce44SJohn Forte  * return - the longest registration period.
1663*fcf3ce44SJohn Forte  *
1664*fcf3ce44SJohn Forte  * ****************************************************************************
1665*fcf3ce44SJohn Forte  */
1666*fcf3ce44SJohn Forte static uint32_t
1667*fcf3ce44SJohn Forte get_reg_period(
1668*fcf3ce44SJohn Forte )
1669*fcf3ce44SJohn Forte {
1670*fcf3ce44SJohn Forte 	uint32_t t;
1671*fcf3ce44SJohn Forte 	uint32_t period;
1672*fcf3ce44SJohn Forte 
1673*fcf3ce44SJohn Forte 	/* get most current time */
1674*fcf3ce44SJohn Forte 	t = get_timestamp();
1675*fcf3ce44SJohn Forte 
1676*fcf3ce44SJohn Forte 	/* just one second before the end of the world */
1677*fcf3ce44SJohn Forte 	period = INFINITY - t - 1;
1678*fcf3ce44SJohn Forte 
1679*fcf3ce44SJohn Forte 	return (period);
1680*fcf3ce44SJohn Forte }
1681*fcf3ce44SJohn Forte 
1682*fcf3ce44SJohn Forte /*
1683*fcf3ce44SJohn Forte  * ****************************************************************************
1684*fcf3ce44SJohn Forte  *
1685*fcf3ce44SJohn Forte  * obj_calloc:
1686*fcf3ce44SJohn Forte  *	allocate memory space for an object.
1687*fcf3ce44SJohn Forte  *
1688*fcf3ce44SJohn Forte  * type	- the object type.
1689*fcf3ce44SJohn Forte  * return - pointer of the object being allocated.
1690*fcf3ce44SJohn Forte  *
1691*fcf3ce44SJohn Forte  * ****************************************************************************
1692*fcf3ce44SJohn Forte  */
1693*fcf3ce44SJohn Forte isns_obj_t *
1694*fcf3ce44SJohn Forte obj_calloc(
1695*fcf3ce44SJohn Forte 	int type
1696*fcf3ce44SJohn Forte )
1697*fcf3ce44SJohn Forte {
1698*fcf3ce44SJohn Forte 	isns_obj_t *obj = NULL;
1699*fcf3ce44SJohn Forte 
1700*fcf3ce44SJohn Forte 	obj = (isns_obj_t *)calloc(1, SIZEOF_OBJ[type]);
1701*fcf3ce44SJohn Forte 	if (obj != NULL) {
1702*fcf3ce44SJohn Forte 		obj->type = type;
1703*fcf3ce44SJohn Forte #ifdef DEBUG
1704*fcf3ce44SJohn Forte 	if (verbose_mc) {
1705*fcf3ce44SJohn Forte 		printf("object(%d) allocated\n", type);
1706*fcf3ce44SJohn Forte 	}
1707*fcf3ce44SJohn Forte #endif
1708*fcf3ce44SJohn Forte 	}
1709*fcf3ce44SJohn Forte 
1710*fcf3ce44SJohn Forte 	return (obj);
1711*fcf3ce44SJohn Forte }
1712*fcf3ce44SJohn Forte 
1713*fcf3ce44SJohn Forte /*
1714*fcf3ce44SJohn Forte  * ****************************************************************************
1715*fcf3ce44SJohn Forte  *
1716*fcf3ce44SJohn Forte  * make_default_entity:
1717*fcf3ce44SJohn Forte  *	generate a default network entity object.
1718*fcf3ce44SJohn Forte  *
1719*fcf3ce44SJohn Forte  * return - pointer of the default network entity object.
1720*fcf3ce44SJohn Forte  *
1721*fcf3ce44SJohn Forte  * ****************************************************************************
1722*fcf3ce44SJohn Forte  */
1723*fcf3ce44SJohn Forte isns_obj_t *
1724*fcf3ce44SJohn Forte make_default_entity(
1725*fcf3ce44SJohn Forte )
1726*fcf3ce44SJohn Forte {
1727*fcf3ce44SJohn Forte 	uint32_t t;
1728*fcf3ce44SJohn Forte 
1729*fcf3ce44SJohn Forte 	isns_obj_t *obj = obj_calloc(OBJ_ENTITY);
1730*fcf3ce44SJohn Forte 	isns_attr_t *attr;
1731*fcf3ce44SJohn Forte 	if (obj != NULL) {
1732*fcf3ce44SJohn Forte 		int len;
1733*fcf3ce44SJohn Forte 		char *eid = make_unique_name(&len, ISNS_EID_ATTR_ID);
1734*fcf3ce44SJohn Forte 		if (!eid) {
1735*fcf3ce44SJohn Forte 			free(obj);
1736*fcf3ce44SJohn Forte 			return (NULL);
1737*fcf3ce44SJohn Forte 		}
1738*fcf3ce44SJohn Forte 		attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)];
1739*fcf3ce44SJohn Forte 
1740*fcf3ce44SJohn Forte 		/* set default entity name */
1741*fcf3ce44SJohn Forte 		attr->tag = ISNS_EID_ATTR_ID;
1742*fcf3ce44SJohn Forte 		attr->len = len;
1743*fcf3ce44SJohn Forte 		attr->value.ptr = (uchar_t *)eid;
1744*fcf3ce44SJohn Forte 
1745*fcf3ce44SJohn Forte 		/* set default registration period */
1746*fcf3ce44SJohn Forte 		attr = &obj->attrs[
1747*fcf3ce44SJohn Forte 		    ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
1748*fcf3ce44SJohn Forte 		if (attr->tag == 0) {
1749*fcf3ce44SJohn Forte 			attr->tag = ISNS_ENTITY_REG_PERIOD_ATTR_ID;
1750*fcf3ce44SJohn Forte 			attr->len = 4;
1751*fcf3ce44SJohn Forte 			t = get_reg_period();
1752*fcf3ce44SJohn Forte 			attr->value.ui = t;
1753*fcf3ce44SJohn Forte 		}
1754*fcf3ce44SJohn Forte 	}
1755*fcf3ce44SJohn Forte 
1756*fcf3ce44SJohn Forte 	return (obj);
1757*fcf3ce44SJohn Forte }
1758*fcf3ce44SJohn Forte 
1759*fcf3ce44SJohn Forte /*
1760*fcf3ce44SJohn Forte  * ****************************************************************************
1761*fcf3ce44SJohn Forte  *
1762*fcf3ce44SJohn Forte  * make_default_pg:
1763*fcf3ce44SJohn Forte  *	generate a default portal group object.
1764*fcf3ce44SJohn Forte  *
1765*fcf3ce44SJohn Forte  * iscsi  - the iscsi storage node object.
1766*fcf3ce44SJohn Forte  * portal - the portal object.
1767*fcf3ce44SJohn Forte  * return - pointer of the default portal group object.
1768*fcf3ce44SJohn Forte  *
1769*fcf3ce44SJohn Forte  * ****************************************************************************
1770*fcf3ce44SJohn Forte  */
1771*fcf3ce44SJohn Forte static isns_obj_t *
1772*fcf3ce44SJohn Forte make_default_pg(
1773*fcf3ce44SJohn Forte 	const isns_obj_t *p1,
1774*fcf3ce44SJohn Forte 	const isns_obj_t *p2
1775*fcf3ce44SJohn Forte )
1776*fcf3ce44SJohn Forte {
1777*fcf3ce44SJohn Forte 	const isns_obj_t *iscsi, *portal;
1778*fcf3ce44SJohn Forte 	const isns_attr_t *name, *addr, *port;
1779*fcf3ce44SJohn Forte 	isns_obj_t *pg;
1780*fcf3ce44SJohn Forte 
1781*fcf3ce44SJohn Forte 	uchar_t *pg_name;
1782*fcf3ce44SJohn Forte 	in6_addr_t *pg_addr;
1783*fcf3ce44SJohn Forte 
1784*fcf3ce44SJohn Forte 	isns_attr_t *attr;
1785*fcf3ce44SJohn Forte 
1786*fcf3ce44SJohn Forte 	uint32_t *refp;
1787*fcf3ce44SJohn Forte 
1788*fcf3ce44SJohn Forte 	if (p1->type == OBJ_ISCSI) {
1789*fcf3ce44SJohn Forte 		iscsi = p1;
1790*fcf3ce44SJohn Forte 		portal = p2;
1791*fcf3ce44SJohn Forte 	} else {
1792*fcf3ce44SJohn Forte 		iscsi = p2;
1793*fcf3ce44SJohn Forte 		portal = p1;
1794*fcf3ce44SJohn Forte 	}
1795*fcf3ce44SJohn Forte 	name = &iscsi->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
1796*fcf3ce44SJohn Forte 	addr = &portal->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID)];
1797*fcf3ce44SJohn Forte 	port = &portal->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID)];
1798*fcf3ce44SJohn Forte 
1799*fcf3ce44SJohn Forte 	pg = obj_calloc(OBJ_PG);
1800*fcf3ce44SJohn Forte 	pg_name = (uchar_t *)malloc(name->len);
1801*fcf3ce44SJohn Forte 	pg_addr = (in6_addr_t *)malloc(addr->len);
1802*fcf3ce44SJohn Forte 	if (pg != NULL && pg_name != NULL && pg_addr != NULL) {
1803*fcf3ce44SJohn Forte 		(void) strcpy((char *)pg_name, (char *)name->value.ptr);
1804*fcf3ce44SJohn Forte 		attr = &pg->attrs[ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID)];
1805*fcf3ce44SJohn Forte 		attr->tag = ISNS_PG_ISCSI_NAME_ATTR_ID;
1806*fcf3ce44SJohn Forte 		attr->len = name->len;
1807*fcf3ce44SJohn Forte 		attr->value.ptr = pg_name;
1808*fcf3ce44SJohn Forte 
1809*fcf3ce44SJohn Forte 		(void) memcpy((void *)pg_addr,
1810*fcf3ce44SJohn Forte 		    (void *)addr->value.ip, addr->len);
1811*fcf3ce44SJohn Forte 		attr = &pg->attrs[ATTR_INDEX_PG(
1812*fcf3ce44SJohn Forte 		    ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)];
1813*fcf3ce44SJohn Forte 		attr->tag = ISNS_PG_PORTAL_IP_ADDR_ATTR_ID;
1814*fcf3ce44SJohn Forte 		attr->len = addr->len;
1815*fcf3ce44SJohn Forte 		attr->value.ip = pg_addr;
1816*fcf3ce44SJohn Forte 
1817*fcf3ce44SJohn Forte 		attr = &pg->attrs[ATTR_INDEX_PG(
1818*fcf3ce44SJohn Forte 		    ISNS_PG_PORTAL_PORT_ATTR_ID)];
1819*fcf3ce44SJohn Forte 		attr->tag = ISNS_PG_PORTAL_PORT_ATTR_ID;
1820*fcf3ce44SJohn Forte 		attr->len = port->len;
1821*fcf3ce44SJohn Forte 		attr->value.ui = port->value.ui;
1822*fcf3ce44SJohn Forte 
1823*fcf3ce44SJohn Forte 		attr = &pg->attrs[ATTR_INDEX_PG(
1824*fcf3ce44SJohn Forte 		    ISNS_PG_TAG_ATTR_ID)];
1825*fcf3ce44SJohn Forte 		attr->tag = ISNS_PG_TAG_ATTR_ID;
1826*fcf3ce44SJohn Forte 		attr->len = 4;
1827*fcf3ce44SJohn Forte 		attr->value.ui = ISNS_DEFAULT_PGT;
1828*fcf3ce44SJohn Forte 
1829*fcf3ce44SJohn Forte 		refp = get_ref_p(pg, OBJ_ISCSI);
1830*fcf3ce44SJohn Forte 		*refp = get_obj_uid(iscsi);
1831*fcf3ce44SJohn Forte 
1832*fcf3ce44SJohn Forte 		refp = get_ref_p(pg, OBJ_PORTAL);
1833*fcf3ce44SJohn Forte 		*refp = get_obj_uid(portal);
1834*fcf3ce44SJohn Forte 
1835*fcf3ce44SJohn Forte 		(void) set_parent_obj(pg, get_parent_uid(iscsi));
1836*fcf3ce44SJohn Forte 	} else {
1837*fcf3ce44SJohn Forte 		free(pg);
1838*fcf3ce44SJohn Forte 		free(pg_name);
1839*fcf3ce44SJohn Forte 		free(pg_addr);
1840*fcf3ce44SJohn Forte 		pg = NULL;
1841*fcf3ce44SJohn Forte 	}
1842*fcf3ce44SJohn Forte 
1843*fcf3ce44SJohn Forte 	return (pg);
1844*fcf3ce44SJohn Forte }
1845*fcf3ce44SJohn Forte 
1846*fcf3ce44SJohn Forte /*
1847*fcf3ce44SJohn Forte  * ****************************************************************************
1848*fcf3ce44SJohn Forte  *
1849*fcf3ce44SJohn Forte  * reg_get_entity:
1850*fcf3ce44SJohn Forte  *	parse the Operating Attributes of the DevAttrReg message and
1851*fcf3ce44SJohn Forte  *	create the Network Entity object if it has one.
1852*fcf3ce44SJohn Forte  *
1853*fcf3ce44SJohn Forte  * p	- the pointer of the object for returning.
1854*fcf3ce44SJohn Forte  * op	- the operating attributes.
1855*fcf3ce44SJohn Forte  * op_len - the length of the operating attributes.
1856*fcf3ce44SJohn Forte  * return - error code.
1857*fcf3ce44SJohn Forte  *
1858*fcf3ce44SJohn Forte  * ****************************************************************************
1859*fcf3ce44SJohn Forte  */
1860*fcf3ce44SJohn Forte int
1861*fcf3ce44SJohn Forte reg_get_entity(
1862*fcf3ce44SJohn Forte 	isns_obj_t **p,
1863*fcf3ce44SJohn Forte 	isns_tlv_t **op,
1864*fcf3ce44SJohn Forte 	uint16_t *op_len
1865*fcf3ce44SJohn Forte )
1866*fcf3ce44SJohn Forte {
1867*fcf3ce44SJohn Forte 	int ec = 0;
1868*fcf3ce44SJohn Forte 
1869*fcf3ce44SJohn Forte 	isns_tlv_t *tmp;
1870*fcf3ce44SJohn Forte 	uint16_t tmp_len;
1871*fcf3ce44SJohn Forte 	isns_attr_t *attr;
1872*fcf3ce44SJohn Forte 
1873*fcf3ce44SJohn Forte 	isns_obj_t *entity = NULL;
1874*fcf3ce44SJohn Forte 
1875*fcf3ce44SJohn Forte 	tmp = *op;
1876*fcf3ce44SJohn Forte 	tmp_len = *op_len;
1877*fcf3ce44SJohn Forte 
1878*fcf3ce44SJohn Forte 	/* parse the entity object */
1879*fcf3ce44SJohn Forte 	if (tmp_len >= 8 && IS_ENTITY_KEY(tmp->attr_id)) {
1880*fcf3ce44SJohn Forte 		entity = obj_calloc(OBJ_ENTITY);
1881*fcf3ce44SJohn Forte 		if (entity != NULL) {
1882*fcf3ce44SJohn Forte 			do {
1883*fcf3ce44SJohn Forte 				attr = &entity->attrs[
1884*fcf3ce44SJohn Forte 				    ATTR_INDEX_ENTITY(tmp->attr_id)];
1885*fcf3ce44SJohn Forte 				ec = copy_attr(attr, tmp);
1886*fcf3ce44SJohn Forte 				NEXT_TLV(tmp, tmp_len);
1887*fcf3ce44SJohn Forte 			} while (ec == 0 &&
1888*fcf3ce44SJohn Forte 			    tmp_len >= 8 &&
1889*fcf3ce44SJohn Forte 			    IS_ENTITY_ATTR(tmp->attr_id));
1890*fcf3ce44SJohn Forte 		} else {
1891*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
1892*fcf3ce44SJohn Forte 		}
1893*fcf3ce44SJohn Forte 
1894*fcf3ce44SJohn Forte 		if (ec == 0) {
1895*fcf3ce44SJohn Forte 			/* set default registration period */
1896*fcf3ce44SJohn Forte 			attr = &entity->attrs[
1897*fcf3ce44SJohn Forte 			    ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
1898*fcf3ce44SJohn Forte 			if (attr->tag == 0) {
1899*fcf3ce44SJohn Forte 				attr->tag = ISNS_ENTITY_REG_PERIOD_ATTR_ID;
1900*fcf3ce44SJohn Forte 				attr->len = 4;
1901*fcf3ce44SJohn Forte 				attr->value.ui = get_reg_period();
1902*fcf3ce44SJohn Forte 			}
1903*fcf3ce44SJohn Forte 		} else if (entity != NULL) {
1904*fcf3ce44SJohn Forte 			free(entity);
1905*fcf3ce44SJohn Forte 			entity = NULL;
1906*fcf3ce44SJohn Forte 		}
1907*fcf3ce44SJohn Forte 	}
1908*fcf3ce44SJohn Forte 
1909*fcf3ce44SJohn Forte 	*p = entity;
1910*fcf3ce44SJohn Forte 	*op = tmp;
1911*fcf3ce44SJohn Forte 	*op_len = tmp_len;
1912*fcf3ce44SJohn Forte 
1913*fcf3ce44SJohn Forte 	return (ec);
1914*fcf3ce44SJohn Forte }
1915*fcf3ce44SJohn Forte 
1916*fcf3ce44SJohn Forte /*
1917*fcf3ce44SJohn Forte  * ****************************************************************************
1918*fcf3ce44SJohn Forte  *
1919*fcf3ce44SJohn Forte  * reg_get_iscsi:
1920*fcf3ce44SJohn Forte  *	parse the Operating Attributes of the DevAttrReg message and
1921*fcf3ce44SJohn Forte  *	create an iSCSI Storage Node object.
1922*fcf3ce44SJohn Forte  *
1923*fcf3ce44SJohn Forte  * p	- the pointer of the object for returning.
1924*fcf3ce44SJohn Forte  * pg_key1 - the pointer of iscsi storage node name for returning.
1925*fcf3ce44SJohn Forte  * op	- the operating attributes.
1926*fcf3ce44SJohn Forte  * op_len - the length of the operating attributes.
1927*fcf3ce44SJohn Forte  * return - error code.
1928*fcf3ce44SJohn Forte  *
1929*fcf3ce44SJohn Forte  * ****************************************************************************
1930*fcf3ce44SJohn Forte  */
1931*fcf3ce44SJohn Forte static int
1932*fcf3ce44SJohn Forte reg_get_iscsi(
1933*fcf3ce44SJohn Forte 	isns_obj_t **p,
1934*fcf3ce44SJohn Forte 	isns_attr_t *pg_key1,
1935*fcf3ce44SJohn Forte 	isns_tlv_t **op,
1936*fcf3ce44SJohn Forte 	uint16_t *op_len
1937*fcf3ce44SJohn Forte )
1938*fcf3ce44SJohn Forte {
1939*fcf3ce44SJohn Forte 	int ec = 0;
1940*fcf3ce44SJohn Forte 
1941*fcf3ce44SJohn Forte 	isns_tlv_t *tmp;
1942*fcf3ce44SJohn Forte 	uint16_t tmp_len;
1943*fcf3ce44SJohn Forte 	isns_attr_t *attr;
1944*fcf3ce44SJohn Forte 
1945*fcf3ce44SJohn Forte 	isns_obj_t *obj = NULL;
1946*fcf3ce44SJohn Forte 
1947*fcf3ce44SJohn Forte 	tmp = *op;
1948*fcf3ce44SJohn Forte 	tmp_len = *op_len;
1949*fcf3ce44SJohn Forte 
1950*fcf3ce44SJohn Forte 	/* keep the iscsi storage node name for */
1951*fcf3ce44SJohn Forte 	/* parsing a pg object which is immediately */
1952*fcf3ce44SJohn Forte 	/* followed with a PGT by the iscsi storage node */
1953*fcf3ce44SJohn Forte 	pg_key1->tag = PG_KEY1;
1954*fcf3ce44SJohn Forte 	pg_key1->len = tmp->attr_len;
1955*fcf3ce44SJohn Forte 	pg_key1->value.ptr = (uchar_t *)&tmp->attr_value[0];
1956*fcf3ce44SJohn Forte 
1957*fcf3ce44SJohn Forte 	/* parse one iscsi storage node object */
1958*fcf3ce44SJohn Forte 	obj = obj_calloc(OBJ_ISCSI);
1959*fcf3ce44SJohn Forte 	if (obj != NULL) {
1960*fcf3ce44SJohn Forte 		/* parse key & non-key attributes */
1961*fcf3ce44SJohn Forte 		do {
1962*fcf3ce44SJohn Forte 			attr = &obj->attrs[
1963*fcf3ce44SJohn Forte 			    ATTR_INDEX_ISCSI(tmp->attr_id)];
1964*fcf3ce44SJohn Forte 			ec = copy_attr(attr, tmp);
1965*fcf3ce44SJohn Forte 			NEXT_TLV(tmp, tmp_len);
1966*fcf3ce44SJohn Forte 		} while (ec == 0 &&
1967*fcf3ce44SJohn Forte 		    tmp_len >= 8 &&
1968*fcf3ce44SJohn Forte 		    IS_ISCSI_ATTR(tmp->attr_id));
1969*fcf3ce44SJohn Forte 	} else {
1970*fcf3ce44SJohn Forte 		/* no memory */
1971*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
1972*fcf3ce44SJohn Forte 	}
1973*fcf3ce44SJohn Forte 
1974*fcf3ce44SJohn Forte 	*p = obj;
1975*fcf3ce44SJohn Forte 	*op = tmp;
1976*fcf3ce44SJohn Forte 	*op_len = tmp_len;
1977*fcf3ce44SJohn Forte 
1978*fcf3ce44SJohn Forte 	return (ec);
1979*fcf3ce44SJohn Forte }
1980*fcf3ce44SJohn Forte 
1981*fcf3ce44SJohn Forte /*
1982*fcf3ce44SJohn Forte  * ****************************************************************************
1983*fcf3ce44SJohn Forte  *
1984*fcf3ce44SJohn Forte  * reg_get_portal:
1985*fcf3ce44SJohn Forte  *	parse the Operating Attributes of the DevAttrReg message and
1986*fcf3ce44SJohn Forte  *	create a Portal object.
1987*fcf3ce44SJohn Forte  *
1988*fcf3ce44SJohn Forte  * p	- the pointer of the object for returning.
1989*fcf3ce44SJohn Forte  * pg_key1 - the pointer of portal ip addr for returning.
1990*fcf3ce44SJohn Forte  * pg_key2 - the pointer of portal port for returning.
1991*fcf3ce44SJohn Forte  * op	- the operating attributes.
1992*fcf3ce44SJohn Forte  * op_len - the length of the operating attributes.
1993*fcf3ce44SJohn Forte  * return - error code.
1994*fcf3ce44SJohn Forte  *
1995*fcf3ce44SJohn Forte  * ****************************************************************************
1996*fcf3ce44SJohn Forte  */
1997*fcf3ce44SJohn Forte static int
1998*fcf3ce44SJohn Forte reg_get_portal(
1999*fcf3ce44SJohn Forte 	isns_obj_t **p,
2000*fcf3ce44SJohn Forte 	isns_attr_t *pg_key1,
2001*fcf3ce44SJohn Forte 	isns_attr_t *pg_key2,
2002*fcf3ce44SJohn Forte 	isns_tlv_t **op,
2003*fcf3ce44SJohn Forte 	uint16_t *op_len
2004*fcf3ce44SJohn Forte )
2005*fcf3ce44SJohn Forte {
2006*fcf3ce44SJohn Forte 	int ec = 0;
2007*fcf3ce44SJohn Forte 
2008*fcf3ce44SJohn Forte 	isns_tlv_t *tmp;
2009*fcf3ce44SJohn Forte 	uint16_t tmp_len;
2010*fcf3ce44SJohn Forte 	isns_attr_t *attr;
2011*fcf3ce44SJohn Forte 
2012*fcf3ce44SJohn Forte 	isns_obj_t *obj = NULL;
2013*fcf3ce44SJohn Forte 
2014*fcf3ce44SJohn Forte 	isns_tlv_t *ip;
2015*fcf3ce44SJohn Forte 
2016*fcf3ce44SJohn Forte 	tmp = *op;
2017*fcf3ce44SJohn Forte 	tmp_len = *op_len;
2018*fcf3ce44SJohn Forte 
2019*fcf3ce44SJohn Forte 	/* keep the portal ip addr */
2020*fcf3ce44SJohn Forte 	pg_key1->tag = PG_KEY2;
2021*fcf3ce44SJohn Forte 	pg_key1->len = tmp->attr_len;
2022*fcf3ce44SJohn Forte 	pg_key1->value.ip = (void *)&tmp->attr_value[0];
2023*fcf3ce44SJohn Forte 	ip = tmp;
2024*fcf3ce44SJohn Forte 
2025*fcf3ce44SJohn Forte 	NEXT_TLV(tmp, tmp_len);
2026*fcf3ce44SJohn Forte 	if (tmp_len > 8 &&
2027*fcf3ce44SJohn Forte 	    tmp->attr_id == PORTAL_KEY2 &&
2028*fcf3ce44SJohn Forte 	    tmp->attr_len == 4) {
2029*fcf3ce44SJohn Forte 		/* keep the portal port */
2030*fcf3ce44SJohn Forte 		pg_key2->tag = PG_KEY3;
2031*fcf3ce44SJohn Forte 		pg_key2->len = tmp->attr_len;
2032*fcf3ce44SJohn Forte 		pg_key2->value.ui = ntohl(*(uint32_t *)&tmp->attr_value[0]);
2033*fcf3ce44SJohn Forte 
2034*fcf3ce44SJohn Forte 		/* parse one portal object */
2035*fcf3ce44SJohn Forte 		obj = obj_calloc(OBJ_PORTAL);
2036*fcf3ce44SJohn Forte 		if (obj != NULL) {
2037*fcf3ce44SJohn Forte 			/* copy ip addr attribute */
2038*fcf3ce44SJohn Forte 			attr = &obj->attrs[
2039*fcf3ce44SJohn Forte 			    ATTR_INDEX_PORTAL(ip->attr_id)];
2040*fcf3ce44SJohn Forte 			ec = copy_attr(attr, ip);
2041*fcf3ce44SJohn Forte 			/* copy port attribute */
2042*fcf3ce44SJohn Forte 			if (ec == 0) {
2043*fcf3ce44SJohn Forte 				attr = &obj->attrs[
2044*fcf3ce44SJohn Forte 				    ATTR_INDEX_PORTAL(tmp->attr_id)];
2045*fcf3ce44SJohn Forte 				ec = copy_attr(attr, tmp);
2046*fcf3ce44SJohn Forte 			}
2047*fcf3ce44SJohn Forte 			/* parse non-key attributes */
2048*fcf3ce44SJohn Forte 			NEXT_TLV(tmp, tmp_len);
2049*fcf3ce44SJohn Forte 			while (ec == 0 &&
2050*fcf3ce44SJohn Forte 			    tmp_len >= 8 &&
2051*fcf3ce44SJohn Forte 			    IS_PORTAL_ATTR(tmp->attr_id)) {
2052*fcf3ce44SJohn Forte 				attr = &obj->attrs[
2053*fcf3ce44SJohn Forte 				    ATTR_INDEX_PORTAL(
2054*fcf3ce44SJohn Forte 				    tmp->attr_id)];
2055*fcf3ce44SJohn Forte 				ec = copy_attr(attr, tmp);
2056*fcf3ce44SJohn Forte 				NEXT_TLV(tmp, tmp_len);
2057*fcf3ce44SJohn Forte 			}
2058*fcf3ce44SJohn Forte 		} else {
2059*fcf3ce44SJohn Forte 			/* no memory */
2060*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
2061*fcf3ce44SJohn Forte 		}
2062*fcf3ce44SJohn Forte 	} else {
2063*fcf3ce44SJohn Forte 		/* ip address is not followed by port */
2064*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
2065*fcf3ce44SJohn Forte 	}
2066*fcf3ce44SJohn Forte 
2067*fcf3ce44SJohn Forte 	*p = obj;
2068*fcf3ce44SJohn Forte 	*op = tmp;
2069*fcf3ce44SJohn Forte 	*op_len = tmp_len;
2070*fcf3ce44SJohn Forte 
2071*fcf3ce44SJohn Forte 	return (ec);
2072*fcf3ce44SJohn Forte }
2073*fcf3ce44SJohn Forte 
2074*fcf3ce44SJohn Forte /*
2075*fcf3ce44SJohn Forte  * ****************************************************************************
2076*fcf3ce44SJohn Forte  *
2077*fcf3ce44SJohn Forte  * reg_get_pg:
2078*fcf3ce44SJohn Forte  *	parse the Operating Attributes of the DevAttrReg message and
2079*fcf3ce44SJohn Forte  *	create a Portal Group object.
2080*fcf3ce44SJohn Forte  *
2081*fcf3ce44SJohn Forte  * p	- the pointer of the object for returning.
2082*fcf3ce44SJohn Forte  * op	- the operating attributes.
2083*fcf3ce44SJohn Forte  * op_len - the length of the operating attributes.
2084*fcf3ce44SJohn Forte  * return - error code.
2085*fcf3ce44SJohn Forte  *
2086*fcf3ce44SJohn Forte  * ****************************************************************************
2087*fcf3ce44SJohn Forte  */
2088*fcf3ce44SJohn Forte static int
2089*fcf3ce44SJohn Forte reg_get_pg(
2090*fcf3ce44SJohn Forte 	isns_obj_t **p,
2091*fcf3ce44SJohn Forte 	isns_tlv_t **op,
2092*fcf3ce44SJohn Forte 	uint16_t *op_len
2093*fcf3ce44SJohn Forte )
2094*fcf3ce44SJohn Forte {
2095*fcf3ce44SJohn Forte 	int ec = 0;
2096*fcf3ce44SJohn Forte 
2097*fcf3ce44SJohn Forte 	isns_tlv_t *tmp;
2098*fcf3ce44SJohn Forte 	uint16_t tmp_len;
2099*fcf3ce44SJohn Forte 	isns_attr_t *attr;
2100*fcf3ce44SJohn Forte 
2101*fcf3ce44SJohn Forte 	isns_obj_t *obj = NULL;
2102*fcf3ce44SJohn Forte 
2103*fcf3ce44SJohn Forte 	tmp = *op;
2104*fcf3ce44SJohn Forte 	tmp_len = *op_len;
2105*fcf3ce44SJohn Forte 
2106*fcf3ce44SJohn Forte 	/* parse a complete pg object */
2107*fcf3ce44SJohn Forte 	obj = obj_calloc(OBJ_PG);
2108*fcf3ce44SJohn Forte 	if (obj != NULL) {
2109*fcf3ce44SJohn Forte 		/* parse attributes */
2110*fcf3ce44SJohn Forte 		do {
2111*fcf3ce44SJohn Forte 			attr = &obj->attrs[
2112*fcf3ce44SJohn Forte 			    ATTR_INDEX_PG(tmp->attr_id)];
2113*fcf3ce44SJohn Forte 			ec = copy_attr(attr, tmp);
2114*fcf3ce44SJohn Forte 			NEXT_TLV(tmp, tmp_len);
2115*fcf3ce44SJohn Forte 		} while (ec == 0 &&
2116*fcf3ce44SJohn Forte 		    tmp_len >= 8 &&
2117*fcf3ce44SJohn Forte 		    IS_PG_ATTR(tmp->attr_id));
2118*fcf3ce44SJohn Forte 	} else {
2119*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
2120*fcf3ce44SJohn Forte 	}
2121*fcf3ce44SJohn Forte 
2122*fcf3ce44SJohn Forte 	*p = obj;
2123*fcf3ce44SJohn Forte 	*op = tmp;
2124*fcf3ce44SJohn Forte 	*op_len = tmp_len;
2125*fcf3ce44SJohn Forte 
2126*fcf3ce44SJohn Forte 	return (ec);
2127*fcf3ce44SJohn Forte }
2128*fcf3ce44SJohn Forte 
2129*fcf3ce44SJohn Forte /*
2130*fcf3ce44SJohn Forte  * ****************************************************************************
2131*fcf3ce44SJohn Forte  *
2132*fcf3ce44SJohn Forte  * reg_get_pg1:
2133*fcf3ce44SJohn Forte  *	parse the Operating Attributes of the DevAttrReg message and
2134*fcf3ce44SJohn Forte  *	create a Portal Group object which is followed to a Portal object.
2135*fcf3ce44SJohn Forte  *
2136*fcf3ce44SJohn Forte  * p	- the pointer of the object for returning.
2137*fcf3ce44SJohn Forte  * pgt	- the size-3 array of pointers which have the pg portal ip addr, port
2138*fcf3ce44SJohn Forte  *	  and the pg tag attributes.
2139*fcf3ce44SJohn Forte  * op	- the operating attributes.
2140*fcf3ce44SJohn Forte  * op_len - the length of the operating attributes.
2141*fcf3ce44SJohn Forte  * return - error code.
2142*fcf3ce44SJohn Forte  *
2143*fcf3ce44SJohn Forte  * ****************************************************************************
2144*fcf3ce44SJohn Forte  */
2145*fcf3ce44SJohn Forte static int
2146*fcf3ce44SJohn Forte reg_get_pg1(
2147*fcf3ce44SJohn Forte 	isns_obj_t **p,
2148*fcf3ce44SJohn Forte 	isns_attr_t const *pgt,
2149*fcf3ce44SJohn Forte 	isns_tlv_t **op,
2150*fcf3ce44SJohn Forte 	uint16_t *op_len
2151*fcf3ce44SJohn Forte )
2152*fcf3ce44SJohn Forte {
2153*fcf3ce44SJohn Forte 	int ec = 0;
2154*fcf3ce44SJohn Forte 
2155*fcf3ce44SJohn Forte 	isns_tlv_t *tmp;
2156*fcf3ce44SJohn Forte 	uint16_t tmp_len;
2157*fcf3ce44SJohn Forte 	isns_attr_t *attr;
2158*fcf3ce44SJohn Forte 
2159*fcf3ce44SJohn Forte 	isns_obj_t *obj = NULL;
2160*fcf3ce44SJohn Forte 	int i = 0;
2161*fcf3ce44SJohn Forte 
2162*fcf3ce44SJohn Forte 	tmp = *op;
2163*fcf3ce44SJohn Forte 	tmp_len = *op_len;
2164*fcf3ce44SJohn Forte 
2165*fcf3ce44SJohn Forte 	if (pgt[0].tag == PG_KEY2 &&
2166*fcf3ce44SJohn Forte 	    pgt[1].tag == PG_KEY3) {
2167*fcf3ce44SJohn Forte 		/* the pg iscsi storage node name is */
2168*fcf3ce44SJohn Forte 		/* followed to a portal group tag */
2169*fcf3ce44SJohn Forte 		obj = obj_calloc(OBJ_PG);
2170*fcf3ce44SJohn Forte 		if (obj != NULL) {
2171*fcf3ce44SJohn Forte 			/* copy pg iscsi storage node name */
2172*fcf3ce44SJohn Forte 			attr = &obj->attrs[
2173*fcf3ce44SJohn Forte 			    ATTR_INDEX_PG(tmp->attr_id)];
2174*fcf3ce44SJohn Forte 			ec = copy_attr(attr, tmp);
2175*fcf3ce44SJohn Forte 			/* copy pg ip addr, pg port & pgt */
2176*fcf3ce44SJohn Forte 			while (ec == 0 && i < 3) {
2177*fcf3ce44SJohn Forte 				attr = &obj->attrs[
2178*fcf3ce44SJohn Forte 				    ATTR_INDEX_PG(pgt[i].tag)];
2179*fcf3ce44SJohn Forte 				ec = assign_attr(attr, &pgt[i]);
2180*fcf3ce44SJohn Forte 				i ++;
2181*fcf3ce44SJohn Forte 			}
2182*fcf3ce44SJohn Forte 			NEXT_TLV(tmp, tmp_len);
2183*fcf3ce44SJohn Forte 		} else {
2184*fcf3ce44SJohn Forte 			/* no memory */
2185*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
2186*fcf3ce44SJohn Forte 		}
2187*fcf3ce44SJohn Forte 	} else {
2188*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
2189*fcf3ce44SJohn Forte 	}
2190*fcf3ce44SJohn Forte 
2191*fcf3ce44SJohn Forte 	*p = obj;
2192*fcf3ce44SJohn Forte 	*op = tmp;
2193*fcf3ce44SJohn Forte 	*op_len = tmp_len;
2194*fcf3ce44SJohn Forte 
2195*fcf3ce44SJohn Forte 	return (ec);
2196*fcf3ce44SJohn Forte }
2197*fcf3ce44SJohn Forte 
2198*fcf3ce44SJohn Forte /*
2199*fcf3ce44SJohn Forte  * ****************************************************************************
2200*fcf3ce44SJohn Forte  *
2201*fcf3ce44SJohn Forte  * reg_get_pg2:
2202*fcf3ce44SJohn Forte  *	parse the Operating Attributes of the DevAttrReg message and
2203*fcf3ce44SJohn Forte  *	create a Portal Group object which is followed to a iSCSI
2204*fcf3ce44SJohn Forte  *	Storage Node object.
2205*fcf3ce44SJohn Forte  *
2206*fcf3ce44SJohn Forte  * p	- the pointer of the object for returning.
2207*fcf3ce44SJohn Forte  * pgt	- the size-3 array of pointers which have the pg iscsi storage
2208*fcf3ce44SJohn Forte  *	  node name and the pg tag attributes.
2209*fcf3ce44SJohn Forte  * op	- the operating attributes.
2210*fcf3ce44SJohn Forte  * op_len - the length of the operating attributes.
2211*fcf3ce44SJohn Forte  * return - error code.
2212*fcf3ce44SJohn Forte  *
2213*fcf3ce44SJohn Forte  * ****************************************************************************
2214*fcf3ce44SJohn Forte  */
2215*fcf3ce44SJohn Forte static int
2216*fcf3ce44SJohn Forte reg_get_pg2(
2217*fcf3ce44SJohn Forte 	isns_obj_t **p,
2218*fcf3ce44SJohn Forte 	isns_attr_t const *pgt,
2219*fcf3ce44SJohn Forte 	isns_tlv_t **op,
2220*fcf3ce44SJohn Forte 	uint16_t *op_len
2221*fcf3ce44SJohn Forte )
2222*fcf3ce44SJohn Forte {
2223*fcf3ce44SJohn Forte 	int ec = 0;
2224*fcf3ce44SJohn Forte 
2225*fcf3ce44SJohn Forte 	isns_tlv_t *tmp;
2226*fcf3ce44SJohn Forte 	uint16_t tmp_len;
2227*fcf3ce44SJohn Forte 	isns_attr_t *attr;
2228*fcf3ce44SJohn Forte 
2229*fcf3ce44SJohn Forte 	isns_obj_t *obj = NULL;
2230*fcf3ce44SJohn Forte 	int i = 0;
2231*fcf3ce44SJohn Forte 
2232*fcf3ce44SJohn Forte 	isns_tlv_t *ip;
2233*fcf3ce44SJohn Forte 
2234*fcf3ce44SJohn Forte 	tmp = *op;
2235*fcf3ce44SJohn Forte 	tmp_len = *op_len;
2236*fcf3ce44SJohn Forte 
2237*fcf3ce44SJohn Forte 	/* keep ip address */
2238*fcf3ce44SJohn Forte 	ip = tmp;
2239*fcf3ce44SJohn Forte 	NEXT_TLV(tmp, tmp_len);
2240*fcf3ce44SJohn Forte 
2241*fcf3ce44SJohn Forte 	if (tmp_len > 8 &&
2242*fcf3ce44SJohn Forte 	    /* expect pg portal port */
2243*fcf3ce44SJohn Forte 	    tmp->attr_id == PG_KEY3 &&
2244*fcf3ce44SJohn Forte 	    tmp->attr_len == 4 &&
2245*fcf3ce44SJohn Forte 	    /* expect pg tag */
2246*fcf3ce44SJohn Forte 	    pgt[2].tag == PG_PGT &&
2247*fcf3ce44SJohn Forte 	    /* expect pg iscsi storage node name only */
2248*fcf3ce44SJohn Forte 	    pgt[1].tag == 0 &&
2249*fcf3ce44SJohn Forte 	    pgt[0].tag == PG_KEY1) {
2250*fcf3ce44SJohn Forte 		/* the pg portal ip addr & port is followed */
2251*fcf3ce44SJohn Forte 		/* to a pg tag and we have the iscsi storage */
2252*fcf3ce44SJohn Forte 		/* node parsed previously */
2253*fcf3ce44SJohn Forte 		obj = obj_calloc(OBJ_PG);
2254*fcf3ce44SJohn Forte 		if (obj != NULL) {
2255*fcf3ce44SJohn Forte 			/* copy the pg ip addr */
2256*fcf3ce44SJohn Forte 			attr = &obj->attrs[
2257*fcf3ce44SJohn Forte 			    ATTR_INDEX_PG(ip->attr_id)];
2258*fcf3ce44SJohn Forte 			ec = copy_attr(attr, ip);
2259*fcf3ce44SJohn Forte 			/* copy the pg port */
2260*fcf3ce44SJohn Forte 			if (ec == 0) {
2261*fcf3ce44SJohn Forte 				attr = &obj->attrs[
2262*fcf3ce44SJohn Forte 				    ATTR_INDEX_PG(tmp->attr_id)];
2263*fcf3ce44SJohn Forte 				ec = copy_attr(attr, tmp);
2264*fcf3ce44SJohn Forte 			}
2265*fcf3ce44SJohn Forte 			/* copy pg iscsi storage node name & pgt */
2266*fcf3ce44SJohn Forte 			while (ec == 0 && i < 3) {
2267*fcf3ce44SJohn Forte 				attr = &obj->attrs[
2268*fcf3ce44SJohn Forte 				    ATTR_INDEX_PG(pgt[i].tag)];
2269*fcf3ce44SJohn Forte 				ec = assign_attr(attr, &pgt[i]);
2270*fcf3ce44SJohn Forte 				i += 2;
2271*fcf3ce44SJohn Forte 			}
2272*fcf3ce44SJohn Forte 			NEXT_TLV(tmp, tmp_len);
2273*fcf3ce44SJohn Forte 		} else {
2274*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
2275*fcf3ce44SJohn Forte 		}
2276*fcf3ce44SJohn Forte 	} else {
2277*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
2278*fcf3ce44SJohn Forte 	}
2279*fcf3ce44SJohn Forte 
2280*fcf3ce44SJohn Forte 	*p = obj;
2281*fcf3ce44SJohn Forte 	*op = tmp;
2282*fcf3ce44SJohn Forte 	*op_len = tmp_len;
2283*fcf3ce44SJohn Forte 
2284*fcf3ce44SJohn Forte 	return (ec);
2285*fcf3ce44SJohn Forte }
2286*fcf3ce44SJohn Forte 
2287*fcf3ce44SJohn Forte /*
2288*fcf3ce44SJohn Forte  * ****************************************************************************
2289*fcf3ce44SJohn Forte  *
2290*fcf3ce44SJohn Forte  * reg_get_obj:
2291*fcf3ce44SJohn Forte  *	parse and create one object from the rest of Operating Attributes
2292*fcf3ce44SJohn Forte  *	of the DevAttrReg message, the object can be iSCSI Storage Node,
2293*fcf3ce44SJohn Forte  *	Portal or Portal Group.
2294*fcf3ce44SJohn Forte  *
2295*fcf3ce44SJohn Forte  * p	- the pointer of the object for returning.
2296*fcf3ce44SJohn Forte  * pgt	- an attribute array with size 3, the elements are:
2297*fcf3ce44SJohn Forte  *	  0: the first pg key attribute, it is either the name of an
2298*fcf3ce44SJohn Forte  *	     iscsi storage node object or the ip addr of a portal object.
2299*fcf3ce44SJohn Forte  *	  1: the second pg key attribute, i.e. the portal port.
2300*fcf3ce44SJohn Forte  *	  2: the portal group tag attribute.
2301*fcf3ce44SJohn Forte  * op	- the operating attributes.
2302*fcf3ce44SJohn Forte  * op_len - the length of the operating attributes.
2303*fcf3ce44SJohn Forte  * return - error code.
2304*fcf3ce44SJohn Forte  *
2305*fcf3ce44SJohn Forte  * ****************************************************************************
2306*fcf3ce44SJohn Forte  */
2307*fcf3ce44SJohn Forte int
2308*fcf3ce44SJohn Forte reg_get_obj(
2309*fcf3ce44SJohn Forte 	isns_obj_t **p,
2310*fcf3ce44SJohn Forte 	isns_attr_t *pgt,
2311*fcf3ce44SJohn Forte 	isns_tlv_t **op,
2312*fcf3ce44SJohn Forte 	uint16_t *op_len
2313*fcf3ce44SJohn Forte )
2314*fcf3ce44SJohn Forte {
2315*fcf3ce44SJohn Forte 	int ec = 0;
2316*fcf3ce44SJohn Forte 
2317*fcf3ce44SJohn Forte 	int derefd = 0;
2318*fcf3ce44SJohn Forte 
2319*fcf3ce44SJohn Forte 	uint32_t pg_tag;
2320*fcf3ce44SJohn Forte 
2321*fcf3ce44SJohn Forte 	if (*op_len == 0) {
2322*fcf3ce44SJohn Forte 		*p = NULL;
2323*fcf3ce44SJohn Forte 		return (0);
2324*fcf3ce44SJohn Forte 	}
2325*fcf3ce44SJohn Forte 
2326*fcf3ce44SJohn Forte 	switch ((*op)->attr_id) {
2327*fcf3ce44SJohn Forte 	case ISCSI_KEY:
2328*fcf3ce44SJohn Forte 		ec = reg_get_iscsi(p, &pgt[0], op, op_len);
2329*fcf3ce44SJohn Forte 		pgt[1].tag = 0;
2330*fcf3ce44SJohn Forte 		pgt[2].tag = 0;
2331*fcf3ce44SJohn Forte 		break;
2332*fcf3ce44SJohn Forte 	case PORTAL_KEY1:
2333*fcf3ce44SJohn Forte 		ec = reg_get_portal(p, &pgt[0], &pgt[1], op, op_len);
2334*fcf3ce44SJohn Forte 		pgt[2].tag = 0;
2335*fcf3ce44SJohn Forte 		break;
2336*fcf3ce44SJohn Forte 	case PG_KEY1:
2337*fcf3ce44SJohn Forte 		if (pgt[2].tag == PG_PGT) {
2338*fcf3ce44SJohn Forte 			/* pg iscsi storage node name is */
2339*fcf3ce44SJohn Forte 			/* followed to a pgt */
2340*fcf3ce44SJohn Forte 			ec = reg_get_pg1(p, pgt, op, op_len);
2341*fcf3ce44SJohn Forte 		} else {
2342*fcf3ce44SJohn Forte 			/* a complete pg object */
2343*fcf3ce44SJohn Forte 			ec = reg_get_pg(p, op, op_len);
2344*fcf3ce44SJohn Forte 			pgt[0].tag = 0;
2345*fcf3ce44SJohn Forte 			pgt[1].tag = 0;
2346*fcf3ce44SJohn Forte 			pgt[2].tag = 0;
2347*fcf3ce44SJohn Forte 		}
2348*fcf3ce44SJohn Forte 		break;
2349*fcf3ce44SJohn Forte 	case PG_KEY2:
2350*fcf3ce44SJohn Forte 		/* pg portal ip addr is followed to a pgt */
2351*fcf3ce44SJohn Forte 		ec = reg_get_pg2(p, pgt, op, op_len);
2352*fcf3ce44SJohn Forte 		break;
2353*fcf3ce44SJohn Forte 	case PG_PGT:
2354*fcf3ce44SJohn Forte 		switch (pgt[0].tag) {
2355*fcf3ce44SJohn Forte 		case 0:
2356*fcf3ce44SJohn Forte 			/* portal group tag does not follow */
2357*fcf3ce44SJohn Forte 			/* iscsi storage node or portal object */
2358*fcf3ce44SJohn Forte 			*p = NULL;
2359*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
2360*fcf3ce44SJohn Forte 			break;
2361*fcf3ce44SJohn Forte 		case PG_KEY1:
2362*fcf3ce44SJohn Forte 		case PG_KEY2:
2363*fcf3ce44SJohn Forte 			pgt[2].tag = PG_PGT;
2364*fcf3ce44SJohn Forte 			pgt[2].len = (*op)->attr_len;
2365*fcf3ce44SJohn Forte 			pg_tag = 0;
2366*fcf3ce44SJohn Forte 			switch ((*op)->attr_len) {
2367*fcf3ce44SJohn Forte 			case 4:
2368*fcf3ce44SJohn Forte 				pg_tag = ntohl(*(uint32_t *)
2369*fcf3ce44SJohn Forte 				    &(*op)->attr_value[0]);
2370*fcf3ce44SJohn Forte 			case 0:
2371*fcf3ce44SJohn Forte 				pgt[2].value.ui = pg_tag;
2372*fcf3ce44SJohn Forte 				break;
2373*fcf3ce44SJohn Forte 			default:
2374*fcf3ce44SJohn Forte 				*p = NULL;
2375*fcf3ce44SJohn Forte 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
2376*fcf3ce44SJohn Forte 				break;
2377*fcf3ce44SJohn Forte 			}
2378*fcf3ce44SJohn Forte 			if (ec == 0) {
2379*fcf3ce44SJohn Forte 				derefd = 1;
2380*fcf3ce44SJohn Forte 				NEXT_TLV(*op, *op_len);
2381*fcf3ce44SJohn Forte 				ec = reg_get_obj(p, pgt, op, op_len);
2382*fcf3ce44SJohn Forte 			}
2383*fcf3ce44SJohn Forte 			break;
2384*fcf3ce44SJohn Forte 		default:
2385*fcf3ce44SJohn Forte 			/* should never happen */
2386*fcf3ce44SJohn Forte 			ASSERT(0);
2387*fcf3ce44SJohn Forte 			*p = NULL;
2388*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
2389*fcf3ce44SJohn Forte 			break;
2390*fcf3ce44SJohn Forte 		}
2391*fcf3ce44SJohn Forte 		break;
2392*fcf3ce44SJohn Forte 	default:
2393*fcf3ce44SJohn Forte 		*p = NULL;
2394*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
2395*fcf3ce44SJohn Forte 		break;
2396*fcf3ce44SJohn Forte 	}
2397*fcf3ce44SJohn Forte 
2398*fcf3ce44SJohn Forte 	if (ec == 0 && derefd == 0) {
2399*fcf3ce44SJohn Forte 		ec = update_deref_obj(*p);
2400*fcf3ce44SJohn Forte 	}
2401*fcf3ce44SJohn Forte 
2402*fcf3ce44SJohn Forte 	if (ec != 0 && *p != NULL) {
2403*fcf3ce44SJohn Forte 		free_one_object(*p);
2404*fcf3ce44SJohn Forte 		*p = NULL;
2405*fcf3ce44SJohn Forte 	}
2406*fcf3ce44SJohn Forte 
2407*fcf3ce44SJohn Forte 	return (ec);
2408*fcf3ce44SJohn Forte }
2409*fcf3ce44SJohn Forte 
2410*fcf3ce44SJohn Forte /*
2411*fcf3ce44SJohn Forte  * ****************************************************************************
2412*fcf3ce44SJohn Forte  *
2413*fcf3ce44SJohn Forte  * reg_auth_src:
2414*fcf3ce44SJohn Forte  *	Authorize the source attribute the DevAttrReg message.
2415*fcf3ce44SJohn Forte  *	The update can only performed by the node who has the owenership.
2416*fcf3ce44SJohn Forte  *
2417*fcf3ce44SJohn Forte  * p	- the pointer of the object for returning.
2418*fcf3ce44SJohn Forte  * pgt	- an attribute array with size 3, the elements are:
2419*fcf3ce44SJohn Forte  *	  0: the first pg key attribute, it is either the name of an
2420*fcf3ce44SJohn Forte  *	     iscsi storage node object or the ip addr of a portal object.
2421*fcf3ce44SJohn Forte  *	  1: the second pg key attribute, i.e. the portal port.
2422*fcf3ce44SJohn Forte  *	  2: the portal group tag attribute.
2423*fcf3ce44SJohn Forte  * op	- the operating attributes.
2424*fcf3ce44SJohn Forte  * op_len - the length of the operating attributes.
2425*fcf3ce44SJohn Forte  * return - error code.
2426*fcf3ce44SJohn Forte  *
2427*fcf3ce44SJohn Forte  * ****************************************************************************
2428*fcf3ce44SJohn Forte  */
2429*fcf3ce44SJohn Forte int
2430*fcf3ce44SJohn Forte reg_auth_src(
2431*fcf3ce44SJohn Forte 	isns_type_t type,
2432*fcf3ce44SJohn Forte 	uint32_t uid,
2433*fcf3ce44SJohn Forte 	uchar_t *src
2434*fcf3ce44SJohn Forte )
2435*fcf3ce44SJohn Forte {
2436*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
2437*fcf3ce44SJohn Forte 	uint32_t puid;
2438*fcf3ce44SJohn Forte 
2439*fcf3ce44SJohn Forte 	puid = is_parent_there(src);
2440*fcf3ce44SJohn Forte 
2441*fcf3ce44SJohn Forte 	if (TYPE_OF_PARENT[type] != 0) {
2442*fcf3ce44SJohn Forte 		SET_UID_LCP(&lc, type, uid);
2443*fcf3ce44SJohn Forte 		uid = cache_lookup(&lc, NULL, cb_get_parent);
2444*fcf3ce44SJohn Forte 		type = TYPE_OF_PARENT[type];
2445*fcf3ce44SJohn Forte 	}
2446*fcf3ce44SJohn Forte 
2447*fcf3ce44SJohn Forte 	if (uid != 0 && puid == 0) {
2448*fcf3ce44SJohn Forte 		SET_UID_LCP(&lc, type, uid);
2449*fcf3ce44SJohn Forte 		uid = cache_lookup(&lc, NULL, cb_node_child);
2450*fcf3ce44SJohn Forte 	}
2451*fcf3ce44SJohn Forte 
2452*fcf3ce44SJohn Forte 	if (puid != uid) {
2453*fcf3ce44SJohn Forte 		return (0);
2454*fcf3ce44SJohn Forte 	}
2455*fcf3ce44SJohn Forte 
2456*fcf3ce44SJohn Forte 	return (1);
2457*fcf3ce44SJohn Forte }
2458*fcf3ce44SJohn Forte 
2459*fcf3ce44SJohn Forte /*
2460*fcf3ce44SJohn Forte  * ****************************************************************************
2461*fcf3ce44SJohn Forte  *
2462*fcf3ce44SJohn Forte  * is_obj_online:
2463*fcf3ce44SJohn Forte  *	determine if the object is currently registered with the server.
2464*fcf3ce44SJohn Forte  *
2465*fcf3ce44SJohn Forte  * obj - the object being checked.
2466*fcf3ce44SJohn Forte  * return - 0: not registered, otherwise registered.
2467*fcf3ce44SJohn Forte  *
2468*fcf3ce44SJohn Forte  * ****************************************************************************
2469*fcf3ce44SJohn Forte  */
2470*fcf3ce44SJohn Forte int
2471*fcf3ce44SJohn Forte is_obj_online(
2472*fcf3ce44SJohn Forte 	const isns_obj_t *obj
2473*fcf3ce44SJohn Forte )
2474*fcf3ce44SJohn Forte {
2475*fcf3ce44SJohn Forte 	int online = 1;
2476*fcf3ce44SJohn Forte 
2477*fcf3ce44SJohn Forte 	switch (obj->type) {
2478*fcf3ce44SJohn Forte 	case OBJ_ISCSI:
2479*fcf3ce44SJohn Forte 		online = obj->attrs[ATTR_INDEX_ISCSI(
2480*fcf3ce44SJohn Forte 		    ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui == 0 ? 0 : 1;
2481*fcf3ce44SJohn Forte 		break;
2482*fcf3ce44SJohn Forte 	default:
2483*fcf3ce44SJohn Forte 		break;
2484*fcf3ce44SJohn Forte 	}
2485*fcf3ce44SJohn Forte 
2486*fcf3ce44SJohn Forte 	return (online);
2487*fcf3ce44SJohn Forte }
2488*fcf3ce44SJohn Forte 
2489*fcf3ce44SJohn Forte static int
2490*fcf3ce44SJohn Forte set_obj_offline(
2491*fcf3ce44SJohn Forte 	isns_obj_t *obj
2492*fcf3ce44SJohn Forte )
2493*fcf3ce44SJohn Forte {
2494*fcf3ce44SJohn Forte 	switch (obj->type) {
2495*fcf3ce44SJohn Forte 	case OBJ_ISCSI:
2496*fcf3ce44SJohn Forte 		obj->attrs[ATTR_INDEX_ISCSI(
2497*fcf3ce44SJohn Forte 		    ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui = 0;
2498*fcf3ce44SJohn Forte 		break;
2499*fcf3ce44SJohn Forte 	default:
2500*fcf3ce44SJohn Forte 		break;
2501*fcf3ce44SJohn Forte 	}
2502*fcf3ce44SJohn Forte 
2503*fcf3ce44SJohn Forte 	return (0);
2504*fcf3ce44SJohn Forte }
2505*fcf3ce44SJohn Forte 
2506*fcf3ce44SJohn Forte /*
2507*fcf3ce44SJohn Forte  * ****************************************************************************
2508*fcf3ce44SJohn Forte  *
2509*fcf3ce44SJohn Forte  * assoc_clone:
2510*fcf3ce44SJohn Forte  *	clone the association object.
2511*fcf3ce44SJohn Forte  *
2512*fcf3ce44SJohn Forte  * p - the object being cloned.
2513*fcf3ce44SJohn Forte  * clone_flag - 0: the object is being removed;
2514*fcf3ce44SJohn Forte  *		1: only the association is being removed.
2515*fcf3ce44SJohn Forte  * return - the clone object.
2516*fcf3ce44SJohn Forte  *
2517*fcf3ce44SJohn Forte  * ****************************************************************************
2518*fcf3ce44SJohn Forte  */
2519*fcf3ce44SJohn Forte void *
2520*fcf3ce44SJohn Forte assoc_clone(
2521*fcf3ce44SJohn Forte 	void *p,
2522*fcf3ce44SJohn Forte 	int clone_flag
2523*fcf3ce44SJohn Forte )
2524*fcf3ce44SJohn Forte {
2525*fcf3ce44SJohn Forte 	isns_type_t type;
2526*fcf3ce44SJohn Forte 	isns_obj_t *clone;
2527*fcf3ce44SJohn Forte 	const isns_attr_t *src_attr;
2528*fcf3ce44SJohn Forte 	isns_attr_t *dst_attr;
2529*fcf3ce44SJohn Forte 	uint32_t id, op;
2530*fcf3ce44SJohn Forte 	int i = 0;
2531*fcf3ce44SJohn Forte 
2532*fcf3ce44SJohn Forte 	const isns_obj_t *obj;
2533*fcf3ce44SJohn Forte 	uint32_t dd_flag;
2534*fcf3ce44SJohn Forte 	int online;
2535*fcf3ce44SJohn Forte 
2536*fcf3ce44SJohn Forte 	int state;
2537*fcf3ce44SJohn Forte 
2538*fcf3ce44SJohn Forte 	obj = (isns_obj_t *)p;
2539*fcf3ce44SJohn Forte 
2540*fcf3ce44SJohn Forte 	if (obj->type != OBJ_ISCSI) {
2541*fcf3ce44SJohn Forte 		return (NULL);
2542*fcf3ce44SJohn Forte 	}
2543*fcf3ce44SJohn Forte 
2544*fcf3ce44SJohn Forte 	dd_flag = (get_dd_id(get_obj_uid(obj), ISNS_DEFAULT_DD_ID) == 0) ?
2545*fcf3ce44SJohn Forte 	    0 : 1;
2546*fcf3ce44SJohn Forte 	online = is_obj_online(obj);
2547*fcf3ce44SJohn Forte 
2548*fcf3ce44SJohn Forte 	state = (clone_flag << 2) | (dd_flag  << 1) | online;
2549*fcf3ce44SJohn Forte 
2550*fcf3ce44SJohn Forte 	/* clone_flag	dd_flag	online	action		*/
2551*fcf3ce44SJohn Forte 	/* 0		0	0	ASSERT(0)	*/
2552*fcf3ce44SJohn Forte 	/* 0		0	1	NULL		*/
2553*fcf3ce44SJohn Forte 	/* 0		1	0	itself		*/
2554*fcf3ce44SJohn Forte 	/* 0		1	1	clone it	*/
2555*fcf3ce44SJohn Forte 	/* 1		0	0	NULL		*/
2556*fcf3ce44SJohn Forte 	/* 1		0	1	itself		*/
2557*fcf3ce44SJohn Forte 	/* 1		1	0	itself		*/
2558*fcf3ce44SJohn Forte 	/* 1		1	1	itself		*/
2559*fcf3ce44SJohn Forte 
2560*fcf3ce44SJohn Forte 	switch (state) {
2561*fcf3ce44SJohn Forte 	case 0:
2562*fcf3ce44SJohn Forte 		ASSERT(0);
2563*fcf3ce44SJohn Forte 	case 1:
2564*fcf3ce44SJohn Forte 	case 4:
2565*fcf3ce44SJohn Forte 		return (NULL);
2566*fcf3ce44SJohn Forte 	case 2:
2567*fcf3ce44SJohn Forte 	case 5:
2568*fcf3ce44SJohn Forte 	case 6:
2569*fcf3ce44SJohn Forte 	case 7:
2570*fcf3ce44SJohn Forte 		return (p);
2571*fcf3ce44SJohn Forte 	case 3:
2572*fcf3ce44SJohn Forte 	default:
2573*fcf3ce44SJohn Forte 		break;
2574*fcf3ce44SJohn Forte 	}
2575*fcf3ce44SJohn Forte 
2576*fcf3ce44SJohn Forte 	type = obj->type;
2577*fcf3ce44SJohn Forte 	clone = obj_calloc(type);
2578*fcf3ce44SJohn Forte 
2579*fcf3ce44SJohn Forte 	if (clone != NULL) {
2580*fcf3ce44SJohn Forte 		id = UID_ATTR_INDEX[type];
2581*fcf3ce44SJohn Forte 		src_attr = &(obj->attrs[id]);
2582*fcf3ce44SJohn Forte 		dst_attr = &(clone->attrs[id]);
2583*fcf3ce44SJohn Forte 		if (assign_attr(dst_attr, src_attr) != 0) {
2584*fcf3ce44SJohn Forte 			free_one_object(clone);
2585*fcf3ce44SJohn Forte 			return (NULL);
2586*fcf3ce44SJohn Forte 		}
2587*fcf3ce44SJohn Forte 
2588*fcf3ce44SJohn Forte 		while (i < MAX_KEY_ATTRS) {
2589*fcf3ce44SJohn Forte 			op = KEY_ATTR_OP[type][i];
2590*fcf3ce44SJohn Forte 			if (op != 0) {
2591*fcf3ce44SJohn Forte 				id = KEY_ATTR_INDEX[type][i];
2592*fcf3ce44SJohn Forte 				src_attr = &(obj->attrs[id]);
2593*fcf3ce44SJohn Forte 				dst_attr = &(clone->attrs[id]);
2594*fcf3ce44SJohn Forte 				if (assign_attr(dst_attr, src_attr) != 0) {
2595*fcf3ce44SJohn Forte 					free_one_object(clone);
2596*fcf3ce44SJohn Forte 					return (NULL);
2597*fcf3ce44SJohn Forte 				}
2598*fcf3ce44SJohn Forte 			} else {
2599*fcf3ce44SJohn Forte 				break;
2600*fcf3ce44SJohn Forte 			}
2601*fcf3ce44SJohn Forte 			i ++;
2602*fcf3ce44SJohn Forte 		}
2603*fcf3ce44SJohn Forte 	}
2604*fcf3ce44SJohn Forte 
2605*fcf3ce44SJohn Forte 	return ((void *)clone);
2606*fcf3ce44SJohn Forte }
2607*fcf3ce44SJohn Forte 
2608*fcf3ce44SJohn Forte /*
2609*fcf3ce44SJohn Forte  * ****************************************************************************
2610*fcf3ce44SJohn Forte  *
2611*fcf3ce44SJohn Forte  * free_one_object:
2612*fcf3ce44SJohn Forte  *	free up one object.
2613*fcf3ce44SJohn Forte  *
2614*fcf3ce44SJohn Forte  * obj - the object being freed.
2615*fcf3ce44SJohn Forte  *
2616*fcf3ce44SJohn Forte  * ****************************************************************************
2617*fcf3ce44SJohn Forte  */
2618*fcf3ce44SJohn Forte void
2619*fcf3ce44SJohn Forte free_one_object(
2620*fcf3ce44SJohn Forte 	isns_obj_t *obj
2621*fcf3ce44SJohn Forte )
2622*fcf3ce44SJohn Forte {
2623*fcf3ce44SJohn Forte 	int i;
2624*fcf3ce44SJohn Forte 	uint32_t *cuid;
2625*fcf3ce44SJohn Forte 	if (obj == NULL) {
2626*fcf3ce44SJohn Forte 		return;
2627*fcf3ce44SJohn Forte 	}
2628*fcf3ce44SJohn Forte 	for (i = 0; i < NUM_OF_ATTRS[obj->type]; i++) {
2629*fcf3ce44SJohn Forte 		isns_attr_t *attr = &obj->attrs[i];
2630*fcf3ce44SJohn Forte 		switch (attr->tag) {
2631*fcf3ce44SJohn Forte 			case ISNS_EID_ATTR_ID:
2632*fcf3ce44SJohn Forte 			case ISNS_ISCSI_NAME_ATTR_ID:
2633*fcf3ce44SJohn Forte 			case ISNS_ISCSI_ALIAS_ATTR_ID:
2634*fcf3ce44SJohn Forte 			case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
2635*fcf3ce44SJohn Forte 			case ISNS_PG_ISCSI_NAME_ATTR_ID:
2636*fcf3ce44SJohn Forte 			case ISNS_PORTAL_IP_ADDR_ATTR_ID:
2637*fcf3ce44SJohn Forte 			case ISNS_PORTAL_NAME_ATTR_ID:
2638*fcf3ce44SJohn Forte 			case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
2639*fcf3ce44SJohn Forte 			case ISNS_DD_SET_NAME_ATTR_ID:
2640*fcf3ce44SJohn Forte 			case ISNS_DD_NAME_ATTR_ID:
2641*fcf3ce44SJohn Forte 			case ISNS_DD_ISCSI_NAME_ATTR_ID:
2642*fcf3ce44SJohn Forte 			case ISNS_DD_FC_PORT_NAME_ATTR_ID:
2643*fcf3ce44SJohn Forte 			case ISNS_DD_PORTAL_IP_ADDR_ATTR_ID:
2644*fcf3ce44SJohn Forte #ifdef DEBUG
2645*fcf3ce44SJohn Forte 				if (verbose_mc) {
2646*fcf3ce44SJohn Forte 					printf("memory(%d) deallocated\n",
2647*fcf3ce44SJohn Forte 					    attr->len);
2648*fcf3ce44SJohn Forte 				}
2649*fcf3ce44SJohn Forte #endif
2650*fcf3ce44SJohn Forte 				free(attr->value.ptr);
2651*fcf3ce44SJohn Forte 				attr->value.ptr = NULL;
2652*fcf3ce44SJohn Forte 				break;
2653*fcf3ce44SJohn Forte 			default:
2654*fcf3ce44SJohn Forte 				break;
2655*fcf3ce44SJohn Forte 		}
2656*fcf3ce44SJohn Forte 	}
2657*fcf3ce44SJohn Forte 
2658*fcf3ce44SJohn Forte 	/* free child uids */
2659*fcf3ce44SJohn Forte 	i = 0;
2660*fcf3ce44SJohn Forte 	while (i < NUM_OF_CHILD[obj->type]) {
2661*fcf3ce44SJohn Forte 		cuid = get_child_n(obj, i);
2662*fcf3ce44SJohn Forte 		free(cuid);
2663*fcf3ce44SJohn Forte 		i ++;
2664*fcf3ce44SJohn Forte 	}
2665*fcf3ce44SJohn Forte 
2666*fcf3ce44SJohn Forte 	/* at last, free the object itself */
2667*fcf3ce44SJohn Forte #ifdef DEBUG
2668*fcf3ce44SJohn Forte 	if (verbose_mc) {
2669*fcf3ce44SJohn Forte 		printf("object(%d) deallocated\n", obj->type);
2670*fcf3ce44SJohn Forte 	}
2671*fcf3ce44SJohn Forte #endif
2672*fcf3ce44SJohn Forte 	free(obj);
2673*fcf3ce44SJohn Forte }
2674*fcf3ce44SJohn Forte 
2675*fcf3ce44SJohn Forte /*
2676*fcf3ce44SJohn Forte  * ****************************************************************************
2677*fcf3ce44SJohn Forte  *
2678*fcf3ce44SJohn Forte  * free_object:
2679*fcf3ce44SJohn Forte  *	free up one object.
2680*fcf3ce44SJohn Forte  *
2681*fcf3ce44SJohn Forte  * obj - the object being freed.
2682*fcf3ce44SJohn Forte  *
2683*fcf3ce44SJohn Forte  * ****************************************************************************
2684*fcf3ce44SJohn Forte  */
2685*fcf3ce44SJohn Forte void
2686*fcf3ce44SJohn Forte free_object(
2687*fcf3ce44SJohn Forte 	isns_obj_t *obj
2688*fcf3ce44SJohn Forte )
2689*fcf3ce44SJohn Forte {
2690*fcf3ce44SJohn Forte 	free_one_object(obj);
2691*fcf3ce44SJohn Forte }
2692*fcf3ce44SJohn Forte 
2693*fcf3ce44SJohn Forte /*
2694*fcf3ce44SJohn Forte  * ****************************************************************************
2695*fcf3ce44SJohn Forte  *
2696*fcf3ce44SJohn Forte  * set_parent_obj:
2697*fcf3ce44SJohn Forte  *	set the parent object UID.
2698*fcf3ce44SJohn Forte  *
2699*fcf3ce44SJohn Forte  * obj - the child object.
2700*fcf3ce44SJohn Forte  * puid- the parent object UID.
2701*fcf3ce44SJohn Forte  * return - error code.
2702*fcf3ce44SJohn Forte  *
2703*fcf3ce44SJohn Forte  * ****************************************************************************
2704*fcf3ce44SJohn Forte  */
2705*fcf3ce44SJohn Forte int
2706*fcf3ce44SJohn Forte set_parent_obj(
2707*fcf3ce44SJohn Forte 	isns_obj_t *obj,
2708*fcf3ce44SJohn Forte 	uint32_t puid
2709*fcf3ce44SJohn Forte )
2710*fcf3ce44SJohn Forte {
2711*fcf3ce44SJohn Forte 	uint32_t *const p = get_parent_p(obj);
2712*fcf3ce44SJohn Forte 	if (p != NULL) {
2713*fcf3ce44SJohn Forte 		*p = puid;
2714*fcf3ce44SJohn Forte 	}
2715*fcf3ce44SJohn Forte 
2716*fcf3ce44SJohn Forte 	return (0);
2717*fcf3ce44SJohn Forte }
2718*fcf3ce44SJohn Forte 
2719*fcf3ce44SJohn Forte /*
2720*fcf3ce44SJohn Forte  * ****************************************************************************
2721*fcf3ce44SJohn Forte  *
2722*fcf3ce44SJohn Forte  * buff_child_obj:
2723*fcf3ce44SJohn Forte  *	add a child object UID to the child object array.
2724*fcf3ce44SJohn Forte  *
2725*fcf3ce44SJohn Forte  * obj - the parent object.
2726*fcf3ce44SJohn Forte  * child_type - the type of the child object.
2727*fcf3ce44SJohn Forte  * number  - the number of the child object.
2728*fcf3ce44SJohn Forte  * return - the length of the child object UID array.
2729*fcf3ce44SJohn Forte  *
2730*fcf3ce44SJohn Forte  * ****************************************************************************
2731*fcf3ce44SJohn Forte  */
2732*fcf3ce44SJohn Forte int
2733*fcf3ce44SJohn Forte buff_child_obj(
2734*fcf3ce44SJohn Forte 	const isns_type_t ptype,
2735*fcf3ce44SJohn Forte 	const isns_type_t ctype,
2736*fcf3ce44SJohn Forte 	const void *c,
2737*fcf3ce44SJohn Forte 	void const ***child
2738*fcf3ce44SJohn Forte )
2739*fcf3ce44SJohn Forte {
2740*fcf3ce44SJohn Forte 	int ec = 0;
2741*fcf3ce44SJohn Forte 
2742*fcf3ce44SJohn Forte 	int i = 0;
2743*fcf3ce44SJohn Forte 	void const ***pp, **p;
2744*fcf3ce44SJohn Forte 	uint32_t num, new_num;
2745*fcf3ce44SJohn Forte 
2746*fcf3ce44SJohn Forte 	pp = NULL;
2747*fcf3ce44SJohn Forte 	/* get the pointer of the array which the child belongs to */
2748*fcf3ce44SJohn Forte 	while (i < NUM_OF_CHILD[ptype]) {
2749*fcf3ce44SJohn Forte 		if (TYPE_OF_CHILD[ptype][i] == ctype) {
2750*fcf3ce44SJohn Forte 			pp = &child[i];
2751*fcf3ce44SJohn Forte 			break;
2752*fcf3ce44SJohn Forte 		}
2753*fcf3ce44SJohn Forte 		i ++;
2754*fcf3ce44SJohn Forte 	}
2755*fcf3ce44SJohn Forte 
2756*fcf3ce44SJohn Forte 	/* the child type is not applicable */
2757*fcf3ce44SJohn Forte 	if (pp == NULL) {
2758*fcf3ce44SJohn Forte 		return (ec);
2759*fcf3ce44SJohn Forte 	}
2760*fcf3ce44SJohn Forte 
2761*fcf3ce44SJohn Forte 	p = *pp;
2762*fcf3ce44SJohn Forte 	/* get an empty slot from the uid array for this child */
2763*fcf3ce44SJohn Forte 	if (p != NULL) {
2764*fcf3ce44SJohn Forte 		num = (uint32_t)*p;
2765*fcf3ce44SJohn Forte 		i = 0;
2766*fcf3ce44SJohn Forte 		while (i < num) {
2767*fcf3ce44SJohn Forte 			if (p[++i] == NULL) {
2768*fcf3ce44SJohn Forte 				/* found it */
2769*fcf3ce44SJohn Forte 				p[i] = c;
2770*fcf3ce44SJohn Forte 				return (ec);
2771*fcf3ce44SJohn Forte 			}
2772*fcf3ce44SJohn Forte 		}
2773*fcf3ce44SJohn Forte 		p = *pp;
2774*fcf3ce44SJohn Forte 		new_num = num + 1;
2775*fcf3ce44SJohn Forte 	} else {
2776*fcf3ce44SJohn Forte 		num = 0;
2777*fcf3ce44SJohn Forte 		new_num = 1;
2778*fcf3ce44SJohn Forte 	}
2779*fcf3ce44SJohn Forte 
2780*fcf3ce44SJohn Forte 	/* the array is full, enlarge the child uid array */
2781*fcf3ce44SJohn Forte 	p = (void const **)realloc(p, (new_num + 1) * sizeof (void *));
2782*fcf3ce44SJohn Forte 	if (p != NULL) {
2783*fcf3ce44SJohn Forte 		*pp = p;
2784*fcf3ce44SJohn Forte 		*p = (void *)new_num;
2785*fcf3ce44SJohn Forte 		p[new_num] = c;
2786*fcf3ce44SJohn Forte 	} else {
2787*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
2788*fcf3ce44SJohn Forte 	}
2789*fcf3ce44SJohn Forte 
2790*fcf3ce44SJohn Forte 	return (ec);
2791*fcf3ce44SJohn Forte }
2792*fcf3ce44SJohn Forte 
2793*fcf3ce44SJohn Forte /*
2794*fcf3ce44SJohn Forte  * ****************************************************************************
2795*fcf3ce44SJohn Forte  *
2796*fcf3ce44SJohn Forte  * update_child_object:
2797*fcf3ce44SJohn Forte  *	update the child object of a network entity object.
2798*fcf3ce44SJohn Forte  *
2799*fcf3ce44SJohn Forte  * puid - the UID of the parent object, i.e. the network entity object.
2800*fcf3ce44SJohn Forte  * child_type - the type of the child object.
2801*fcf3ce44SJohn Forte  * child_uid  - the uid of the child object.
2802*fcf3ce44SJohn Forte  * return - error code.
2803*fcf3ce44SJohn Forte  *
2804*fcf3ce44SJohn Forte  * ****************************************************************************
2805*fcf3ce44SJohn Forte  */
2806*fcf3ce44SJohn Forte int
2807*fcf3ce44SJohn Forte update_child_obj(
2808*fcf3ce44SJohn Forte 	const isns_type_t ptype,
2809*fcf3ce44SJohn Forte 	const uint32_t puid,
2810*fcf3ce44SJohn Forte 	void const ***child,
2811*fcf3ce44SJohn Forte 	int child_flag
2812*fcf3ce44SJohn Forte )
2813*fcf3ce44SJohn Forte {
2814*fcf3ce44SJohn Forte 	int ec = 0;
2815*fcf3ce44SJohn Forte 
2816*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
2817*fcf3ce44SJohn Forte 
2818*fcf3ce44SJohn Forte 	SET_UID_LCP(&lc, ptype, puid);
2819*fcf3ce44SJohn Forte 
2820*fcf3ce44SJohn Forte 	lc.data[1].ptr = (uchar_t *)child;
2821*fcf3ce44SJohn Forte 	lc.data[2].ui = child_flag;
2822*fcf3ce44SJohn Forte 
2823*fcf3ce44SJohn Forte 	ec = cache_lookup(&lc, NULL, cb_add_child);
2824*fcf3ce44SJohn Forte 
2825*fcf3ce44SJohn Forte 	return (ec);
2826*fcf3ce44SJohn Forte }
2827*fcf3ce44SJohn Forte 
2828*fcf3ce44SJohn Forte int
2829*fcf3ce44SJohn Forte update_ref_obj(
2830*fcf3ce44SJohn Forte 	const isns_obj_t *obj
2831*fcf3ce44SJohn Forte )
2832*fcf3ce44SJohn Forte {
2833*fcf3ce44SJohn Forte 	uint32_t uid;
2834*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
2835*fcf3ce44SJohn Forte 	isns_type_t t;
2836*fcf3ce44SJohn Forte 
2837*fcf3ce44SJohn Forte 	t = obj->type;
2838*fcf3ce44SJohn Forte 
2839*fcf3ce44SJohn Forte 	if (TYPE_OF_REF[t][0] != 0) {
2840*fcf3ce44SJohn Forte 		(void) setup_ref_lcp(&lc, obj, NULL);
2841*fcf3ce44SJohn Forte 
2842*fcf3ce44SJohn Forte 		lc.id[2] = t;
2843*fcf3ce44SJohn Forte 		lc.data[2].ui = get_obj_uid(obj);
2844*fcf3ce44SJohn Forte 
2845*fcf3ce44SJohn Forte 		uid = 0;
2846*fcf3ce44SJohn Forte 		do {
2847*fcf3ce44SJohn Forte 			lc.curr_uid = uid;
2848*fcf3ce44SJohn Forte 			(void) cache_lookup(&lc, &uid, cb_set_ref);
2849*fcf3ce44SJohn Forte 		} while (uid != 0);
2850*fcf3ce44SJohn Forte 	}
2851*fcf3ce44SJohn Forte 
2852*fcf3ce44SJohn Forte 	return (0);
2853*fcf3ce44SJohn Forte }
2854*fcf3ce44SJohn Forte 
2855*fcf3ce44SJohn Forte /*
2856*fcf3ce44SJohn Forte  * ****************************************************************************
2857*fcf3ce44SJohn Forte  *
2858*fcf3ce44SJohn Forte  * verify_ref_obj:
2859*fcf3ce44SJohn Forte  *	update the reference bit of a portal group object.
2860*fcf3ce44SJohn Forte  *
2861*fcf3ce44SJohn Forte  * obj - the object being ref'ed.
2862*fcf3ce44SJohn Forte  * return - error code.
2863*fcf3ce44SJohn Forte  *
2864*fcf3ce44SJohn Forte  * ****************************************************************************
2865*fcf3ce44SJohn Forte  */
2866*fcf3ce44SJohn Forte int
2867*fcf3ce44SJohn Forte verify_ref_obj(
2868*fcf3ce44SJohn Forte 	const isns_type_t ptype,
2869*fcf3ce44SJohn Forte 	const uint32_t puid,
2870*fcf3ce44SJohn Forte 	void const ***child
2871*fcf3ce44SJohn Forte )
2872*fcf3ce44SJohn Forte {
2873*fcf3ce44SJohn Forte 	int ec = 0;
2874*fcf3ce44SJohn Forte 
2875*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
2876*fcf3ce44SJohn Forte 
2877*fcf3ce44SJohn Forte 	SET_UID_LCP(&lc, ptype, puid);
2878*fcf3ce44SJohn Forte 
2879*fcf3ce44SJohn Forte 	lc.data[1].ptr = (uchar_t *)child;
2880*fcf3ce44SJohn Forte 
2881*fcf3ce44SJohn Forte 	ec = cache_lookup(&lc, NULL, cb_verify_ref);
2882*fcf3ce44SJohn Forte 
2883*fcf3ce44SJohn Forte 	return (ec);
2884*fcf3ce44SJohn Forte }
2885*fcf3ce44SJohn Forte 
2886*fcf3ce44SJohn Forte int
2887*fcf3ce44SJohn Forte update_deref_obj(
2888*fcf3ce44SJohn Forte 	isns_obj_t *obj
2889*fcf3ce44SJohn Forte )
2890*fcf3ce44SJohn Forte {
2891*fcf3ce44SJohn Forte 	int ec = 0;
2892*fcf3ce44SJohn Forte 
2893*fcf3ce44SJohn Forte 	isns_type_t t, rt;
2894*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
2895*fcf3ce44SJohn Forte 	int i, ref_count;
2896*fcf3ce44SJohn Forte 
2897*fcf3ce44SJohn Forte 	uint32_t uid, *refp;
2898*fcf3ce44SJohn Forte 
2899*fcf3ce44SJohn Forte 	t = obj->type;
2900*fcf3ce44SJohn Forte 	i = ref_count = 0;
2901*fcf3ce44SJohn Forte 	while (i < NUM_OF_REF[t]) {
2902*fcf3ce44SJohn Forte 		rt = TYPE_OF_REF[t][i + 1];
2903*fcf3ce44SJohn Forte 		(void) setup_deref_lcp(&lc, obj, rt);
2904*fcf3ce44SJohn Forte 		uid = is_obj_there(&lc);
2905*fcf3ce44SJohn Forte 		if (uid != 0) {
2906*fcf3ce44SJohn Forte 			refp = get_ref_p(obj, lc.type);
2907*fcf3ce44SJohn Forte 			*refp = uid;
2908*fcf3ce44SJohn Forte 			ref_count ++;
2909*fcf3ce44SJohn Forte 		}
2910*fcf3ce44SJohn Forte 		i ++;
2911*fcf3ce44SJohn Forte 	}
2912*fcf3ce44SJohn Forte 
2913*fcf3ce44SJohn Forte 	if (i > 0 && ref_count == 0) {
2914*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INVALID_REGIS;
2915*fcf3ce44SJohn Forte 	}
2916*fcf3ce44SJohn Forte 
2917*fcf3ce44SJohn Forte 	return (ec);
2918*fcf3ce44SJohn Forte }
2919*fcf3ce44SJohn Forte 
2920*fcf3ce44SJohn Forte /*
2921*fcf3ce44SJohn Forte  * ****************************************************************************
2922*fcf3ce44SJohn Forte  *
2923*fcf3ce44SJohn Forte  * register_object:
2924*fcf3ce44SJohn Forte  *	add one object to the object container.
2925*fcf3ce44SJohn Forte  *
2926*fcf3ce44SJohn Forte  * obj	- the object being added.
2927*fcf3ce44SJohn Forte  * uid_p- the pointer for returning object UID.
2928*fcf3ce44SJohn Forte  * update_p- the pointer for returning flag which indicates if the object
2929*fcf3ce44SJohn Forte  *		is newly registered or updated with an existing one.
2930*fcf3ce44SJohn Forte  * return - error code.
2931*fcf3ce44SJohn Forte  *
2932*fcf3ce44SJohn Forte  * ****************************************************************************
2933*fcf3ce44SJohn Forte  */
2934*fcf3ce44SJohn Forte int
2935*fcf3ce44SJohn Forte register_object(
2936*fcf3ce44SJohn Forte 	isns_obj_t *obj,
2937*fcf3ce44SJohn Forte 	uint32_t *uid_p,
2938*fcf3ce44SJohn Forte 	int *update_p
2939*fcf3ce44SJohn Forte )
2940*fcf3ce44SJohn Forte {
2941*fcf3ce44SJohn Forte 	return (cache_add(obj, 0, uid_p, update_p));
2942*fcf3ce44SJohn Forte }
2943*fcf3ce44SJohn Forte 
2944*fcf3ce44SJohn Forte /*
2945*fcf3ce44SJohn Forte  * ****************************************************************************
2946*fcf3ce44SJohn Forte  *
2947*fcf3ce44SJohn Forte  * register_assoc:
2948*fcf3ce44SJohn Forte  *	add one association object to the object container, the association
2949*fcf3ce44SJohn Forte  *	object has only the information for discovery domain membership, i.e.
2950*fcf3ce44SJohn Forte  *	a name and UID only.
2951*fcf3ce44SJohn Forte  *
2952*fcf3ce44SJohn Forte  * obj	- the association object being added.
2953*fcf3ce44SJohn Forte  * uid_p- the pointer for returning object UID.
2954*fcf3ce44SJohn Forte  * return - error code.
2955*fcf3ce44SJohn Forte  *
2956*fcf3ce44SJohn Forte  * ****************************************************************************
2957*fcf3ce44SJohn Forte  */
2958*fcf3ce44SJohn Forte int
2959*fcf3ce44SJohn Forte register_assoc(
2960*fcf3ce44SJohn Forte 	isns_obj_t *obj,
2961*fcf3ce44SJohn Forte 	uint32_t *uid_p
2962*fcf3ce44SJohn Forte )
2963*fcf3ce44SJohn Forte {
2964*fcf3ce44SJohn Forte 	return (cache_add(obj, 1, uid_p, NULL));
2965*fcf3ce44SJohn Forte }
2966*fcf3ce44SJohn Forte 
2967*fcf3ce44SJohn Forte /*
2968*fcf3ce44SJohn Forte  * ****************************************************************************
2969*fcf3ce44SJohn Forte  *
2970*fcf3ce44SJohn Forte  * is_obj_there:
2971*fcf3ce44SJohn Forte  *	check if the object is registered or not.
2972*fcf3ce44SJohn Forte  *
2973*fcf3ce44SJohn Forte  * lcp	- the lookup control data.
2974*fcf3ce44SJohn Forte  * return - the object UID.
2975*fcf3ce44SJohn Forte  *
2976*fcf3ce44SJohn Forte  * ****************************************************************************
2977*fcf3ce44SJohn Forte  */
2978*fcf3ce44SJohn Forte uint32_t
2979*fcf3ce44SJohn Forte is_obj_there(
2980*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
2981*fcf3ce44SJohn Forte )
2982*fcf3ce44SJohn Forte {
2983*fcf3ce44SJohn Forte 	uint32_t uid;
2984*fcf3ce44SJohn Forte 
2985*fcf3ce44SJohn Forte 	(void) cache_lookup(lcp, &uid, NULL);
2986*fcf3ce44SJohn Forte 
2987*fcf3ce44SJohn Forte 	return (uid);
2988*fcf3ce44SJohn Forte }
2989*fcf3ce44SJohn Forte 
2990*fcf3ce44SJohn Forte uint32_t
2991*fcf3ce44SJohn Forte is_parent_there(
2992*fcf3ce44SJohn Forte 	uchar_t *src
2993*fcf3ce44SJohn Forte )
2994*fcf3ce44SJohn Forte {
2995*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
2996*fcf3ce44SJohn Forte 
2997*fcf3ce44SJohn Forte 	lc.curr_uid = 0;
2998*fcf3ce44SJohn Forte 	lc.type = OBJ_ISCSI;
2999*fcf3ce44SJohn Forte 	lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
3000*fcf3ce44SJohn Forte 	lc.op[0] = OP_STRING;
3001*fcf3ce44SJohn Forte 	lc.data[0].ptr = src;
3002*fcf3ce44SJohn Forte 	lc.op[1] = 0;
3003*fcf3ce44SJohn Forte 
3004*fcf3ce44SJohn Forte 	return (cache_lookup(&lc, NULL, cb_get_parent));
3005*fcf3ce44SJohn Forte }
3006*fcf3ce44SJohn Forte 
3007*fcf3ce44SJohn Forte /*
3008*fcf3ce44SJohn Forte  * ****************************************************************************
3009*fcf3ce44SJohn Forte  *
3010*fcf3ce44SJohn Forte  * setup_ref_lcp:
3011*fcf3ce44SJohn Forte  *	prepare the lookup control data for looking up a portal group
3012*fcf3ce44SJohn Forte  *	object which references to a iscsi stroage node and/or a portal
3013*fcf3ce44SJohn Forte  *	object.
3014*fcf3ce44SJohn Forte  *
3015*fcf3ce44SJohn Forte  * lcp	- the lookup control data.
3016*fcf3ce44SJohn Forte  * iscsi- the ref'ed iscsi storage node object.
3017*fcf3ce44SJohn Forte  * portal- the ref'ed portal object.
3018*fcf3ce44SJohn Forte  * return - error code.
3019*fcf3ce44SJohn Forte  *
3020*fcf3ce44SJohn Forte  * ****************************************************************************
3021*fcf3ce44SJohn Forte  */
3022*fcf3ce44SJohn Forte static int
3023*fcf3ce44SJohn Forte setup_ref_lcp(
3024*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
3025*fcf3ce44SJohn Forte 	const isns_obj_t *iscsi,
3026*fcf3ce44SJohn Forte 	const isns_obj_t *portal
3027*fcf3ce44SJohn Forte )
3028*fcf3ce44SJohn Forte {
3029*fcf3ce44SJohn Forte 	int i = 0, j = 0;
3030*fcf3ce44SJohn Forte 
3031*fcf3ce44SJohn Forte 	lcp->curr_uid = 0;
3032*fcf3ce44SJohn Forte 	lcp->type = TYPE_OF_REF[iscsi->type][0];
3033*fcf3ce44SJohn Forte 
3034*fcf3ce44SJohn Forte 	/* extrace the matching attributes from iscsi storage node object */
3035*fcf3ce44SJohn Forte 	while (iscsi != NULL &&
3036*fcf3ce44SJohn Forte 	    i < MAX_REF_MATCH &&
3037*fcf3ce44SJohn Forte 	    REF_MATCH_OPS[iscsi->type][i] > 0) {
3038*fcf3ce44SJohn Forte 		lcp->id[i] = REF_MATCH_ID2[iscsi->type][i];
3039*fcf3ce44SJohn Forte 		lcp->op[i] = REF_MATCH_OPS[iscsi->type][i];
3040*fcf3ce44SJohn Forte 		lcp->data[i].ptr = iscsi->attrs[
3041*fcf3ce44SJohn Forte 		    REF_MATCH_ID1[iscsi->type][i]].value.ptr;
3042*fcf3ce44SJohn Forte 		i ++;
3043*fcf3ce44SJohn Forte 	}
3044*fcf3ce44SJohn Forte 
3045*fcf3ce44SJohn Forte 	/* extrace the matching attributes from portal object */
3046*fcf3ce44SJohn Forte 	while (portal != NULL &&
3047*fcf3ce44SJohn Forte 	    i < MAX_LOOKUP_CTRL &&
3048*fcf3ce44SJohn Forte 	    j < MAX_REF_MATCH &&
3049*fcf3ce44SJohn Forte 	    REF_MATCH_OPS[portal->type][j] > 0) {
3050*fcf3ce44SJohn Forte 		lcp->id[i] = REF_MATCH_ID2[portal->type][j];
3051*fcf3ce44SJohn Forte 		lcp->op[i] = REF_MATCH_OPS[portal->type][j];
3052*fcf3ce44SJohn Forte 		lcp->data[i].ptr = portal->attrs[
3053*fcf3ce44SJohn Forte 		    REF_MATCH_ID1[portal->type][j]].value.ptr;
3054*fcf3ce44SJohn Forte 		j ++;
3055*fcf3ce44SJohn Forte 		i ++;
3056*fcf3ce44SJohn Forte 	}
3057*fcf3ce44SJohn Forte 
3058*fcf3ce44SJohn Forte 	if (i < MAX_LOOKUP_CTRL) {
3059*fcf3ce44SJohn Forte 		lcp->op[i] = 0;
3060*fcf3ce44SJohn Forte 	}
3061*fcf3ce44SJohn Forte 
3062*fcf3ce44SJohn Forte 	return (0);
3063*fcf3ce44SJohn Forte }
3064*fcf3ce44SJohn Forte 
3065*fcf3ce44SJohn Forte static int
3066*fcf3ce44SJohn Forte setup_deref_lcp(
3067*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
3068*fcf3ce44SJohn Forte 	const isns_obj_t *pg,
3069*fcf3ce44SJohn Forte 	isns_type_t t
3070*fcf3ce44SJohn Forte )
3071*fcf3ce44SJohn Forte {
3072*fcf3ce44SJohn Forte 	int i = 0;
3073*fcf3ce44SJohn Forte 
3074*fcf3ce44SJohn Forte 	lcp->curr_uid = 0;
3075*fcf3ce44SJohn Forte 	lcp->type = t;
3076*fcf3ce44SJohn Forte 
3077*fcf3ce44SJohn Forte 	/* extrace the matching attributes from iscsi storage node object */
3078*fcf3ce44SJohn Forte 	while (i < MAX_REF_MATCH &&
3079*fcf3ce44SJohn Forte 	    REF_MATCH_OPS[t][i] > 0) {
3080*fcf3ce44SJohn Forte 		lcp->id[i] = REF_MATCH_ID1[t][i];
3081*fcf3ce44SJohn Forte 		lcp->op[i] = REF_MATCH_OPS[t][i];
3082*fcf3ce44SJohn Forte 		lcp->data[i].ptr = pg->attrs[
3083*fcf3ce44SJohn Forte 		    REF_MATCH_ID2[t][i]].value.ptr;
3084*fcf3ce44SJohn Forte 		i ++;
3085*fcf3ce44SJohn Forte 	}
3086*fcf3ce44SJohn Forte 
3087*fcf3ce44SJohn Forte 	if (i < MAX_LOOKUP_CTRL) {
3088*fcf3ce44SJohn Forte 		lcp->op[i] = 0;
3089*fcf3ce44SJohn Forte 	}
3090*fcf3ce44SJohn Forte 
3091*fcf3ce44SJohn Forte 	return (0);
3092*fcf3ce44SJohn Forte }
3093*fcf3ce44SJohn Forte 
3094*fcf3ce44SJohn Forte /*
3095*fcf3ce44SJohn Forte  * ****************************************************************************
3096*fcf3ce44SJohn Forte  *
3097*fcf3ce44SJohn Forte  * setup_parent_lcp:
3098*fcf3ce44SJohn Forte  *	prepare the lookup control data for looking up parent object
3099*fcf3ce44SJohn Forte  *	with a child object.
3100*fcf3ce44SJohn Forte  *
3101*fcf3ce44SJohn Forte  * lcp	- the lookup control data.
3102*fcf3ce44SJohn Forte  * obj	- the child object.
3103*fcf3ce44SJohn Forte  * return - parent object UID.
3104*fcf3ce44SJohn Forte  *
3105*fcf3ce44SJohn Forte  * ****************************************************************************
3106*fcf3ce44SJohn Forte  */
3107*fcf3ce44SJohn Forte static uint32_t
3108*fcf3ce44SJohn Forte setup_parent_lcp(
3109*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
3110*fcf3ce44SJohn Forte 	isns_obj_t *obj
3111*fcf3ce44SJohn Forte )
3112*fcf3ce44SJohn Forte {
3113*fcf3ce44SJohn Forte 	isns_type_t ptype;
3114*fcf3ce44SJohn Forte 	uint32_t puid;
3115*fcf3ce44SJohn Forte 
3116*fcf3ce44SJohn Forte 	puid = get_parent_uid(obj);
3117*fcf3ce44SJohn Forte 	if (puid != 0) {
3118*fcf3ce44SJohn Forte 		ptype = TYPE_OF_PARENT[obj->type];
3119*fcf3ce44SJohn Forte 		SET_UID_LCP(lcp, ptype, puid);
3120*fcf3ce44SJohn Forte 		lcp->data[1].ui = obj->type;
3121*fcf3ce44SJohn Forte 		lcp->data[2].ui = get_obj_uid(obj);
3122*fcf3ce44SJohn Forte 	}
3123*fcf3ce44SJohn Forte 
3124*fcf3ce44SJohn Forte 	return (puid);
3125*fcf3ce44SJohn Forte }
3126*fcf3ce44SJohn Forte 
3127*fcf3ce44SJohn Forte static int
3128*fcf3ce44SJohn Forte cb_get_parent(
3129*fcf3ce44SJohn Forte 	void *p1,
3130*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_ARG_UNUSED */
3131*fcf3ce44SJohn Forte 	void *p2
3132*fcf3ce44SJohn Forte )
3133*fcf3ce44SJohn Forte {
3134*fcf3ce44SJohn Forte 	return (get_parent_uid(p1));
3135*fcf3ce44SJohn Forte }
3136*fcf3ce44SJohn Forte 
3137*fcf3ce44SJohn Forte static int
3138*fcf3ce44SJohn Forte cb_node_child(
3139*fcf3ce44SJohn Forte 	void *p1,
3140*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_ARG_UNUSED */
3141*fcf3ce44SJohn Forte 	void *p2
3142*fcf3ce44SJohn Forte )
3143*fcf3ce44SJohn Forte {
3144*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
3145*fcf3ce44SJohn Forte 
3146*fcf3ce44SJohn Forte 	uint32_t num, uid;
3147*fcf3ce44SJohn Forte 
3148*fcf3ce44SJohn Forte 	uint32_t *cuid = get_child_t(obj, OBJ_ISCSI);
3149*fcf3ce44SJohn Forte 
3150*fcf3ce44SJohn Forte 	if (cuid != NULL) {
3151*fcf3ce44SJohn Forte 		num = *cuid;
3152*fcf3ce44SJohn Forte 	} else {
3153*fcf3ce44SJohn Forte 		num = 0;
3154*fcf3ce44SJohn Forte 	}
3155*fcf3ce44SJohn Forte 
3156*fcf3ce44SJohn Forte 	while (num > 0) {
3157*fcf3ce44SJohn Forte 		uid = *++cuid;
3158*fcf3ce44SJohn Forte 		if (uid != 0) {
3159*fcf3ce44SJohn Forte 			return (uid);
3160*fcf3ce44SJohn Forte 		}
3161*fcf3ce44SJohn Forte 		num --;
3162*fcf3ce44SJohn Forte 	}
3163*fcf3ce44SJohn Forte 
3164*fcf3ce44SJohn Forte 	return (0);
3165*fcf3ce44SJohn Forte }
3166*fcf3ce44SJohn Forte 
3167*fcf3ce44SJohn Forte /*
3168*fcf3ce44SJohn Forte  * ****************************************************************************
3169*fcf3ce44SJohn Forte  *
3170*fcf3ce44SJohn Forte  * cb_set_ref:
3171*fcf3ce44SJohn Forte  *	callback function which sets the reference bit to 1 according to
3172*fcf3ce44SJohn Forte  *	the type of object.
3173*fcf3ce44SJohn Forte  *
3174*fcf3ce44SJohn Forte  * p1	- the object.
3175*fcf3ce44SJohn Forte  * p2	- the lcp.
3176*fcf3ce44SJohn Forte  * return - error code.
3177*fcf3ce44SJohn Forte  *
3178*fcf3ce44SJohn Forte  * ****************************************************************************
3179*fcf3ce44SJohn Forte  */
3180*fcf3ce44SJohn Forte static int
3181*fcf3ce44SJohn Forte cb_set_ref(
3182*fcf3ce44SJohn Forte 	void *p1,
3183*fcf3ce44SJohn Forte 	void *p2
3184*fcf3ce44SJohn Forte )
3185*fcf3ce44SJohn Forte {
3186*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
3187*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3188*fcf3ce44SJohn Forte 
3189*fcf3ce44SJohn Forte 	isns_type_t t;
3190*fcf3ce44SJohn Forte 	uint32_t u;
3191*fcf3ce44SJohn Forte 
3192*fcf3ce44SJohn Forte 	uint32_t *refp;
3193*fcf3ce44SJohn Forte 
3194*fcf3ce44SJohn Forte 	t = lcp->id[2];
3195*fcf3ce44SJohn Forte 	u = lcp->data[2].ui;
3196*fcf3ce44SJohn Forte 	refp = get_ref_p(obj, t);
3197*fcf3ce44SJohn Forte 	*refp = u;
3198*fcf3ce44SJohn Forte 
3199*fcf3ce44SJohn Forte 	/* successful */
3200*fcf3ce44SJohn Forte 	return (0);
3201*fcf3ce44SJohn Forte }
3202*fcf3ce44SJohn Forte 
3203*fcf3ce44SJohn Forte /*
3204*fcf3ce44SJohn Forte  * ****************************************************************************
3205*fcf3ce44SJohn Forte  *
3206*fcf3ce44SJohn Forte  * cb_clear_ref:
3207*fcf3ce44SJohn Forte  *	callback function which clears the reference bit according to
3208*fcf3ce44SJohn Forte  *	the type of object.
3209*fcf3ce44SJohn Forte  *
3210*fcf3ce44SJohn Forte  * p1	- the object.
3211*fcf3ce44SJohn Forte  * p2	- the lcp.
3212*fcf3ce44SJohn Forte  * return - 1: the object is no longer ref'ed, 0: otherwise.
3213*fcf3ce44SJohn Forte  *
3214*fcf3ce44SJohn Forte  * ****************************************************************************
3215*fcf3ce44SJohn Forte  */
3216*fcf3ce44SJohn Forte static int
3217*fcf3ce44SJohn Forte cb_clear_ref(
3218*fcf3ce44SJohn Forte 	void *p1,
3219*fcf3ce44SJohn Forte 	void *p2
3220*fcf3ce44SJohn Forte )
3221*fcf3ce44SJohn Forte {
3222*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
3223*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3224*fcf3ce44SJohn Forte 
3225*fcf3ce44SJohn Forte 	isns_type_t t;
3226*fcf3ce44SJohn Forte 	uint32_t *refp;
3227*fcf3ce44SJohn Forte 
3228*fcf3ce44SJohn Forte 	int i = 0;
3229*fcf3ce44SJohn Forte 	uint32_t ref;
3230*fcf3ce44SJohn Forte 
3231*fcf3ce44SJohn Forte 	t = lcp->data[2].ui;
3232*fcf3ce44SJohn Forte 	refp = get_ref_p(obj, t);
3233*fcf3ce44SJohn Forte 	*refp = 0;
3234*fcf3ce44SJohn Forte 
3235*fcf3ce44SJohn Forte 	while (i < NUM_OF_REF[obj->type]) {
3236*fcf3ce44SJohn Forte 		ref = get_ref_n(obj, i);
3237*fcf3ce44SJohn Forte 		if (ref != 0) {
3238*fcf3ce44SJohn Forte 			return (0);
3239*fcf3ce44SJohn Forte 		}
3240*fcf3ce44SJohn Forte 		i ++;
3241*fcf3ce44SJohn Forte 	}
3242*fcf3ce44SJohn Forte 
3243*fcf3ce44SJohn Forte 	return (1);
3244*fcf3ce44SJohn Forte }
3245*fcf3ce44SJohn Forte 
3246*fcf3ce44SJohn Forte static int
3247*fcf3ce44SJohn Forte cb_add_child(
3248*fcf3ce44SJohn Forte 	void *p1,
3249*fcf3ce44SJohn Forte 	void *p2
3250*fcf3ce44SJohn Forte )
3251*fcf3ce44SJohn Forte {
3252*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
3253*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3254*fcf3ce44SJohn Forte 
3255*fcf3ce44SJohn Forte 	const void ***child;
3256*fcf3ce44SJohn Forte 	const void **vpp;
3257*fcf3ce44SJohn Forte 	uint32_t vnum;
3258*fcf3ce44SJohn Forte 	int child_flag;
3259*fcf3ce44SJohn Forte 
3260*fcf3ce44SJohn Forte 	uint32_t **upp, *up;
3261*fcf3ce44SJohn Forte 	uint32_t num;
3262*fcf3ce44SJohn Forte 
3263*fcf3ce44SJohn Forte 	isns_obj_t *o;
3264*fcf3ce44SJohn Forte 
3265*fcf3ce44SJohn Forte 	int i = 0;
3266*fcf3ce44SJohn Forte 
3267*fcf3ce44SJohn Forte 	child = (const void ***)lcp->data[1].ptr;
3268*fcf3ce44SJohn Forte 	child_flag = lcp->data[2].ui;
3269*fcf3ce44SJohn Forte 
3270*fcf3ce44SJohn Forte 	while (i < NUM_OF_CHILD[obj->type]) {
3271*fcf3ce44SJohn Forte 		vpp = child[i];
3272*fcf3ce44SJohn Forte 		if (vpp != NULL &&
3273*fcf3ce44SJohn Forte 		    (vnum = (uint32_t)*vpp) > 0 &&
3274*fcf3ce44SJohn Forte 		    *(vpp + 1) != NULL) {
3275*fcf3ce44SJohn Forte 			upp = get_child_np(obj, i);
3276*fcf3ce44SJohn Forte 			if (*upp == NULL) {
3277*fcf3ce44SJohn Forte 				if (child_flag == 0 &&
3278*fcf3ce44SJohn Forte 				    sizeof (typeof (**upp)) ==
3279*fcf3ce44SJohn Forte 				    sizeof (typeof (**child))) {
3280*fcf3ce44SJohn Forte 					*upp = (uint32_t *)vpp;
3281*fcf3ce44SJohn Forte 					vpp = NULL;
3282*fcf3ce44SJohn Forte 					child[i] = NULL;
3283*fcf3ce44SJohn Forte 				}
3284*fcf3ce44SJohn Forte 				num = vnum;
3285*fcf3ce44SJohn Forte 			} else {
3286*fcf3ce44SJohn Forte 				num = **upp + vnum;
3287*fcf3ce44SJohn Forte 			}
3288*fcf3ce44SJohn Forte 			if (vpp != NULL) {
3289*fcf3ce44SJohn Forte 				/* copy required */
3290*fcf3ce44SJohn Forte 				up = (uint32_t *)realloc(*upp,
3291*fcf3ce44SJohn Forte 				    (num + 1) * sizeof (uint32_t));
3292*fcf3ce44SJohn Forte 				if (up == NULL) {
3293*fcf3ce44SJohn Forte 					return (ISNS_RSP_INTERNAL_ERROR);
3294*fcf3ce44SJohn Forte 				}
3295*fcf3ce44SJohn Forte 				*upp = up;
3296*fcf3ce44SJohn Forte 				*up = num;
3297*fcf3ce44SJohn Forte 				up += num;
3298*fcf3ce44SJohn Forte 				vpp += vnum;
3299*fcf3ce44SJohn Forte 				while (vnum > 0) {
3300*fcf3ce44SJohn Forte 					if (*vpp == NULL) {
3301*fcf3ce44SJohn Forte 						*up = 0;
3302*fcf3ce44SJohn Forte 					} else if (child_flag == 0) {
3303*fcf3ce44SJohn Forte 						*up = (uint32_t)*vpp;
3304*fcf3ce44SJohn Forte 						*vpp = NULL;
3305*fcf3ce44SJohn Forte 					} else {
3306*fcf3ce44SJohn Forte 						o = (isns_obj_t *)*vpp;
3307*fcf3ce44SJohn Forte 						*up = get_obj_uid(o);
3308*fcf3ce44SJohn Forte 						if (is_obj_online(o) == 0) {
3309*fcf3ce44SJohn Forte 							free_object(o);
3310*fcf3ce44SJohn Forte 						}
3311*fcf3ce44SJohn Forte 						*vpp = NULL;
3312*fcf3ce44SJohn Forte 					}
3313*fcf3ce44SJohn Forte 					up --;
3314*fcf3ce44SJohn Forte 					vpp --;
3315*fcf3ce44SJohn Forte 					vnum --;
3316*fcf3ce44SJohn Forte 				}
3317*fcf3ce44SJohn Forte 			}
3318*fcf3ce44SJohn Forte 		}
3319*fcf3ce44SJohn Forte 		i ++;
3320*fcf3ce44SJohn Forte 	}
3321*fcf3ce44SJohn Forte 
3322*fcf3ce44SJohn Forte 	return (0);
3323*fcf3ce44SJohn Forte }
3324*fcf3ce44SJohn Forte 
3325*fcf3ce44SJohn Forte /*
3326*fcf3ce44SJohn Forte  * ****************************************************************************
3327*fcf3ce44SJohn Forte  *
3328*fcf3ce44SJohn Forte  * cb_remove_child:
3329*fcf3ce44SJohn Forte  *	callback function which removes a child object UID from the
3330*fcf3ce44SJohn Forte  *	children objet UID array of the parent object.
3331*fcf3ce44SJohn Forte  *
3332*fcf3ce44SJohn Forte  * p1	- the object.
3333*fcf3ce44SJohn Forte  * p2	- the lcp.
3334*fcf3ce44SJohn Forte  * return - 1: no more such type of child object, 0: otherwise.
3335*fcf3ce44SJohn Forte  *
3336*fcf3ce44SJohn Forte  * ****************************************************************************
3337*fcf3ce44SJohn Forte  */
3338*fcf3ce44SJohn Forte static int
3339*fcf3ce44SJohn Forte cb_remove_child(
3340*fcf3ce44SJohn Forte 	void *p1,
3341*fcf3ce44SJohn Forte 	void *p2
3342*fcf3ce44SJohn Forte )
3343*fcf3ce44SJohn Forte {
3344*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
3345*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3346*fcf3ce44SJohn Forte 	uint32_t child_type = lcp->data[1].ui;
3347*fcf3ce44SJohn Forte 	uint32_t child_uid = lcp->data[2].ui;
3348*fcf3ce44SJohn Forte 	uint32_t *cuidp, cuid, num_of_child = 0;
3349*fcf3ce44SJohn Forte 	int i;
3350*fcf3ce44SJohn Forte 
3351*fcf3ce44SJohn Forte 	/* get the children object UID array */
3352*fcf3ce44SJohn Forte 	cuidp = get_child_t(obj, child_type);
3353*fcf3ce44SJohn Forte 	if (cuidp != NULL) {
3354*fcf3ce44SJohn Forte 		num_of_child = *cuidp;
3355*fcf3ce44SJohn Forte 	}
3356*fcf3ce44SJohn Forte 
3357*fcf3ce44SJohn Forte 	/* remove it */
3358*fcf3ce44SJohn Forte 	while (num_of_child > 0) {
3359*fcf3ce44SJohn Forte 		cuid = *++cuidp;
3360*fcf3ce44SJohn Forte 		if (cuid == child_uid) {
3361*fcf3ce44SJohn Forte 			*cuidp = 0;
3362*fcf3ce44SJohn Forte 			break;
3363*fcf3ce44SJohn Forte 		}
3364*fcf3ce44SJohn Forte 		num_of_child --;
3365*fcf3ce44SJohn Forte 	}
3366*fcf3ce44SJohn Forte 
3367*fcf3ce44SJohn Forte 	/* check if all of child object UIDs are removed */
3368*fcf3ce44SJohn Forte 	i = 0;
3369*fcf3ce44SJohn Forte 	while (i < NUM_OF_CHILD[obj->type]) {
3370*fcf3ce44SJohn Forte 		cuidp = get_child_n(obj, i);
3371*fcf3ce44SJohn Forte 		if (cuidp != NULL) {
3372*fcf3ce44SJohn Forte 			num_of_child = *cuidp;
3373*fcf3ce44SJohn Forte 			while (num_of_child > 0) {
3374*fcf3ce44SJohn Forte 				cuid = *++cuidp;
3375*fcf3ce44SJohn Forte 				if (cuid != 0) {
3376*fcf3ce44SJohn Forte 					return (0);
3377*fcf3ce44SJohn Forte 				}
3378*fcf3ce44SJohn Forte 				num_of_child --;
3379*fcf3ce44SJohn Forte 			}
3380*fcf3ce44SJohn Forte 		}
3381*fcf3ce44SJohn Forte 		i ++;
3382*fcf3ce44SJohn Forte 	}
3383*fcf3ce44SJohn Forte 
3384*fcf3ce44SJohn Forte 	return (1);
3385*fcf3ce44SJohn Forte }
3386*fcf3ce44SJohn Forte 
3387*fcf3ce44SJohn Forte static int
3388*fcf3ce44SJohn Forte cb_verify_ref(
3389*fcf3ce44SJohn Forte 	void *p1,
3390*fcf3ce44SJohn Forte 	void *p2
3391*fcf3ce44SJohn Forte )
3392*fcf3ce44SJohn Forte {
3393*fcf3ce44SJohn Forte 	int ec = 0;
3394*fcf3ce44SJohn Forte 
3395*fcf3ce44SJohn Forte 	isns_obj_t *parent = (isns_obj_t *)p1;
3396*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3397*fcf3ce44SJohn Forte 
3398*fcf3ce44SJohn Forte 	const void ***child;
3399*fcf3ce44SJohn Forte 
3400*fcf3ce44SJohn Forte 	const void **vpp;
3401*fcf3ce44SJohn Forte 	const void *vp;
3402*fcf3ce44SJohn Forte 	uint32_t vnum;
3403*fcf3ce44SJohn Forte 
3404*fcf3ce44SJohn Forte 	const void **evpp;
3405*fcf3ce44SJohn Forte 	const void *evp;
3406*fcf3ce44SJohn Forte 	uint32_t evnum;
3407*fcf3ce44SJohn Forte 
3408*fcf3ce44SJohn Forte 	isns_type_t pt; /* parent object type */
3409*fcf3ce44SJohn Forte 	isns_type_t ct; /* child object type */
3410*fcf3ce44SJohn Forte 	isns_type_t rt; /* ref object type */
3411*fcf3ce44SJohn Forte 	isns_type_t et; /* peer object type */
3412*fcf3ce44SJohn Forte 
3413*fcf3ce44SJohn Forte 	uint32_t *up;
3414*fcf3ce44SJohn Forte 	uint32_t u;
3415*fcf3ce44SJohn Forte 	uint32_t unum;
3416*fcf3ce44SJohn Forte 
3417*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
3418*fcf3ce44SJohn Forte 	uint8_t flag[MAX_OBJ_TYPE + 1] = { 0 };
3419*fcf3ce44SJohn Forte 
3420*fcf3ce44SJohn Forte 	int i, j, k;
3421*fcf3ce44SJohn Forte 
3422*fcf3ce44SJohn Forte 	pt = parent->type;
3423*fcf3ce44SJohn Forte 
3424*fcf3ce44SJohn Forte 	child = (const void ***)lcp->data[1].ptr;
3425*fcf3ce44SJohn Forte 
3426*fcf3ce44SJohn Forte 	for (i = 0; i < NUM_OF_CHILD[pt]; i++) {
3427*fcf3ce44SJohn Forte 		ct = TYPE_OF_CHILD[pt][i];
3428*fcf3ce44SJohn Forte 		rt = TYPE_OF_REF[ct][0];
3429*fcf3ce44SJohn Forte 		if (rt == 0) {
3430*fcf3ce44SJohn Forte 			continue;
3431*fcf3ce44SJohn Forte 		}
3432*fcf3ce44SJohn Forte 
3433*fcf3ce44SJohn Forte 		et = TYPE_OF_REF[ct][1];
3434*fcf3ce44SJohn Forte 		vpp = child[i];
3435*fcf3ce44SJohn Forte 		if (vpp != NULL) {
3436*fcf3ce44SJohn Forte 			vnum = (uint32_t)*vpp;
3437*fcf3ce44SJohn Forte 			up = get_child_t(parent, et);
3438*fcf3ce44SJohn Forte 			if (up != NULL) {
3439*fcf3ce44SJohn Forte 				unum = *up;
3440*fcf3ce44SJohn Forte 			} else {
3441*fcf3ce44SJohn Forte 				unum = 0;
3442*fcf3ce44SJohn Forte 			}
3443*fcf3ce44SJohn Forte 		} else {
3444*fcf3ce44SJohn Forte 			vnum = 0;
3445*fcf3ce44SJohn Forte 		}
3446*fcf3ce44SJohn Forte 
3447*fcf3ce44SJohn Forte 		j = vnum;
3448*fcf3ce44SJohn Forte 		while (j > 0) {
3449*fcf3ce44SJohn Forte 			vp = vpp[j];
3450*fcf3ce44SJohn Forte 			if (vp != NULL) {
3451*fcf3ce44SJohn Forte 				(void) setup_ref_lcp(&lc, vp, NULL);
3452*fcf3ce44SJohn Forte 				k = unum;
3453*fcf3ce44SJohn Forte 				while (k > 0) {
3454*fcf3ce44SJohn Forte 					u = up[k];
3455*fcf3ce44SJohn Forte 					if (u != 0) {
3456*fcf3ce44SJohn Forte 						ec = ref_new2old(
3457*fcf3ce44SJohn Forte 						    &lc, et, u, vp);
3458*fcf3ce44SJohn Forte 						if (ec != 0) {
3459*fcf3ce44SJohn Forte 							return (ec);
3460*fcf3ce44SJohn Forte 						}
3461*fcf3ce44SJohn Forte 					}
3462*fcf3ce44SJohn Forte 					k --;
3463*fcf3ce44SJohn Forte 				} /* End of while each unum */
3464*fcf3ce44SJohn Forte 			}
3465*fcf3ce44SJohn Forte 			j --;
3466*fcf3ce44SJohn Forte 		} /* End of while each vnum */
3467*fcf3ce44SJohn Forte 
3468*fcf3ce44SJohn Forte 		if (flag[ct] != 0) {
3469*fcf3ce44SJohn Forte 			continue;
3470*fcf3ce44SJohn Forte 		}
3471*fcf3ce44SJohn Forte 
3472*fcf3ce44SJohn Forte 		evnum = 0;
3473*fcf3ce44SJohn Forte 		j = 0;
3474*fcf3ce44SJohn Forte 		while (j < NUM_OF_CHILD[pt]) {
3475*fcf3ce44SJohn Forte 			if (TYPE_OF_CHILD[pt][j] == et) {
3476*fcf3ce44SJohn Forte 				evpp = child[j];
3477*fcf3ce44SJohn Forte 				if (evpp != NULL) {
3478*fcf3ce44SJohn Forte 					evnum = (uint32_t)*evpp;
3479*fcf3ce44SJohn Forte 				}
3480*fcf3ce44SJohn Forte 				break;
3481*fcf3ce44SJohn Forte 			}
3482*fcf3ce44SJohn Forte 			j ++;
3483*fcf3ce44SJohn Forte 		}
3484*fcf3ce44SJohn Forte 
3485*fcf3ce44SJohn Forte 		j = vnum;
3486*fcf3ce44SJohn Forte 		while (j > 0) {
3487*fcf3ce44SJohn Forte 			vp = vpp[j];
3488*fcf3ce44SJohn Forte 			k = evnum;
3489*fcf3ce44SJohn Forte 			while (k > 0) {
3490*fcf3ce44SJohn Forte 				evp = evpp[k];
3491*fcf3ce44SJohn Forte 				if (vp != NULL && evp != NULL) {
3492*fcf3ce44SJohn Forte 					(void) setup_ref_lcp(&lc, vp, evp);
3493*fcf3ce44SJohn Forte 					ec = ref_new2new(&lc, vp, evp);
3494*fcf3ce44SJohn Forte 					if (ec != 0) {
3495*fcf3ce44SJohn Forte 						return (ec);
3496*fcf3ce44SJohn Forte 					}
3497*fcf3ce44SJohn Forte 				}
3498*fcf3ce44SJohn Forte 				k --;
3499*fcf3ce44SJohn Forte 			}
3500*fcf3ce44SJohn Forte 			j --;
3501*fcf3ce44SJohn Forte 		} /* End of while each vnum */
3502*fcf3ce44SJohn Forte 
3503*fcf3ce44SJohn Forte 		flag[et] = 1;
3504*fcf3ce44SJohn Forte 	} /* End of for each type of child */
3505*fcf3ce44SJohn Forte 
3506*fcf3ce44SJohn Forte 	return (ec);
3507*fcf3ce44SJohn Forte }
3508*fcf3ce44SJohn Forte 
3509*fcf3ce44SJohn Forte static int
3510*fcf3ce44SJohn Forte cb_ref_new2old(
3511*fcf3ce44SJohn Forte 	void *p1,
3512*fcf3ce44SJohn Forte 	void *p2
3513*fcf3ce44SJohn Forte )
3514*fcf3ce44SJohn Forte {
3515*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
3516*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3517*fcf3ce44SJohn Forte 
3518*fcf3ce44SJohn Forte 	isns_type_t et;
3519*fcf3ce44SJohn Forte 	uint32_t uu;
3520*fcf3ce44SJohn Forte 
3521*fcf3ce44SJohn Forte 	uint32_t ref;
3522*fcf3ce44SJohn Forte 
3523*fcf3ce44SJohn Forte 	int match;
3524*fcf3ce44SJohn Forte 
3525*fcf3ce44SJohn Forte 	et = lcp->id[2];
3526*fcf3ce44SJohn Forte 	uu = lcp->data[2].ui;
3527*fcf3ce44SJohn Forte 
3528*fcf3ce44SJohn Forte 	ref = get_ref_t(obj, et);
3529*fcf3ce44SJohn Forte 
3530*fcf3ce44SJohn Forte 	if (ref == uu) {
3531*fcf3ce44SJohn Forte 		match = 1;
3532*fcf3ce44SJohn Forte 	} else {
3533*fcf3ce44SJohn Forte 		match = 0;
3534*fcf3ce44SJohn Forte 	}
3535*fcf3ce44SJohn Forte 
3536*fcf3ce44SJohn Forte 	return (match);
3537*fcf3ce44SJohn Forte }
3538*fcf3ce44SJohn Forte 
3539*fcf3ce44SJohn Forte static int
3540*fcf3ce44SJohn Forte cb_new_ref(
3541*fcf3ce44SJohn Forte 	void *p1,
3542*fcf3ce44SJohn Forte 	void *p2
3543*fcf3ce44SJohn Forte )
3544*fcf3ce44SJohn Forte {
3545*fcf3ce44SJohn Forte 	int ec = 0;
3546*fcf3ce44SJohn Forte 
3547*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3548*fcf3ce44SJohn Forte 	isns_obj_t *a = (isns_obj_t *)p1;
3549*fcf3ce44SJohn Forte 	isns_obj_t *b = (isns_obj_t *)lcp->data[2].ptr;
3550*fcf3ce44SJohn Forte 
3551*fcf3ce44SJohn Forte 	ec = new_ref(a, b);
3552*fcf3ce44SJohn Forte 
3553*fcf3ce44SJohn Forte 	return (ec);
3554*fcf3ce44SJohn Forte }
3555*fcf3ce44SJohn Forte 
3556*fcf3ce44SJohn Forte static int
3557*fcf3ce44SJohn Forte ref_new2old(
3558*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
3559*fcf3ce44SJohn Forte 	isns_type_t et,
3560*fcf3ce44SJohn Forte 	uint32_t uu,
3561*fcf3ce44SJohn Forte 	const isns_obj_t *vp
3562*fcf3ce44SJohn Forte )
3563*fcf3ce44SJohn Forte {
3564*fcf3ce44SJohn Forte 	int ec = 0;
3565*fcf3ce44SJohn Forte 
3566*fcf3ce44SJohn Forte 	int match;
3567*fcf3ce44SJohn Forte 	uint32_t uid;
3568*fcf3ce44SJohn Forte 
3569*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
3570*fcf3ce44SJohn Forte 
3571*fcf3ce44SJohn Forte 	lcp->id[2] = et;
3572*fcf3ce44SJohn Forte 	lcp->data[2].ui = uu;
3573*fcf3ce44SJohn Forte 
3574*fcf3ce44SJohn Forte 	uid = 0;
3575*fcf3ce44SJohn Forte 	do {
3576*fcf3ce44SJohn Forte 		lcp->curr_uid = uid;
3577*fcf3ce44SJohn Forte 		match = cache_lookup(lcp, &uid, cb_ref_new2old);
3578*fcf3ce44SJohn Forte 	} while (match == 0 && uid != 0);
3579*fcf3ce44SJohn Forte 
3580*fcf3ce44SJohn Forte 	if (match == 0) {
3581*fcf3ce44SJohn Forte 		/* no such ref, create a default one */
3582*fcf3ce44SJohn Forte 		SET_UID_LCP(&lc, et, uu);
3583*fcf3ce44SJohn Forte 
3584*fcf3ce44SJohn Forte 		lc.data[2].ptr = (uchar_t *)vp;
3585*fcf3ce44SJohn Forte 
3586*fcf3ce44SJohn Forte 		ec = cache_lookup(&lc, NULL, cb_new_ref);
3587*fcf3ce44SJohn Forte 	}
3588*fcf3ce44SJohn Forte 
3589*fcf3ce44SJohn Forte 	return (ec);
3590*fcf3ce44SJohn Forte }
3591*fcf3ce44SJohn Forte 
3592*fcf3ce44SJohn Forte static int
3593*fcf3ce44SJohn Forte ref_new2new(
3594*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
3595*fcf3ce44SJohn Forte 	const isns_obj_t *p1,
3596*fcf3ce44SJohn Forte 	const isns_obj_t *p2
3597*fcf3ce44SJohn Forte )
3598*fcf3ce44SJohn Forte {
3599*fcf3ce44SJohn Forte 	int ec = 0;
3600*fcf3ce44SJohn Forte 
3601*fcf3ce44SJohn Forte 	if (is_obj_there(lcp) != 0) {
3602*fcf3ce44SJohn Forte 		return (0);
3603*fcf3ce44SJohn Forte 	}
3604*fcf3ce44SJohn Forte 
3605*fcf3ce44SJohn Forte 	ec = new_ref(p1, p2);
3606*fcf3ce44SJohn Forte 
3607*fcf3ce44SJohn Forte 	return (ec);
3608*fcf3ce44SJohn Forte }
3609*fcf3ce44SJohn Forte 
3610*fcf3ce44SJohn Forte static int
3611*fcf3ce44SJohn Forte new_ref(
3612*fcf3ce44SJohn Forte 	const isns_obj_t *p1,
3613*fcf3ce44SJohn Forte 	const isns_obj_t *p2
3614*fcf3ce44SJohn Forte )
3615*fcf3ce44SJohn Forte {
3616*fcf3ce44SJohn Forte 	int ec = 0;
3617*fcf3ce44SJohn Forte 
3618*fcf3ce44SJohn Forte 	isns_obj_t *obj;
3619*fcf3ce44SJohn Forte 
3620*fcf3ce44SJohn Forte 	obj = make_ref[p1->type](p1, p2);
3621*fcf3ce44SJohn Forte 	if (obj != NULL) {
3622*fcf3ce44SJohn Forte 		ec = register_object(obj, NULL, NULL);
3623*fcf3ce44SJohn Forte 	} else {
3624*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
3625*fcf3ce44SJohn Forte 	}
3626*fcf3ce44SJohn Forte 
3627*fcf3ce44SJohn Forte 	return (ec);
3628*fcf3ce44SJohn Forte }
3629*fcf3ce44SJohn Forte 
3630*fcf3ce44SJohn Forte /*
3631*fcf3ce44SJohn Forte  * ****************************************************************************
3632*fcf3ce44SJohn Forte  *
3633*fcf3ce44SJohn Forte  * do_dereg:
3634*fcf3ce44SJohn Forte  *	Physically remove an object along with the children objects,
3635*fcf3ce44SJohn Forte  *	the reference object and the parent object recursively.
3636*fcf3ce44SJohn Forte  *	Apporiate SCN is triggered.
3637*fcf3ce44SJohn Forte  *
3638*fcf3ce44SJohn Forte  * lcp	- the lookup control for the object being removed.
3639*fcf3ce44SJohn Forte  * parent_flag	- 1: the object being removed is the parent object;
3640*fcf3ce44SJohn Forte  *		  0: otherwise.
3641*fcf3ce44SJohn Forte  * child_flag	- 1: the object being removed is a child object;
3642*fcf3ce44SJohn Forte  *		  0: otherwise.
3643*fcf3ce44SJohn Forte  * pending	- 1: do not remove the ESI entry immediately;
3644*fcf3ce44SJohn Forte  *		  0: remove the ESI entry without any delay.
3645*fcf3ce44SJohn Forte  * return - error code.
3646*fcf3ce44SJohn Forte  *
3647*fcf3ce44SJohn Forte  * ****************************************************************************
3648*fcf3ce44SJohn Forte  */
3649*fcf3ce44SJohn Forte static int
3650*fcf3ce44SJohn Forte do_dereg(
3651*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
3652*fcf3ce44SJohn Forte 	int parent_flag,
3653*fcf3ce44SJohn Forte 	int child_flag,
3654*fcf3ce44SJohn Forte 	int pending
3655*fcf3ce44SJohn Forte )
3656*fcf3ce44SJohn Forte {
3657*fcf3ce44SJohn Forte 	int ec = 0;
3658*fcf3ce44SJohn Forte 
3659*fcf3ce44SJohn Forte 	isns_obj_t *obj;
3660*fcf3ce44SJohn Forte 	uint32_t *cuidp, num;
3661*fcf3ce44SJohn Forte 	isns_type_t type;
3662*fcf3ce44SJohn Forte 	uint32_t uid;
3663*fcf3ce44SJohn Forte 	int i;
3664*fcf3ce44SJohn Forte 
3665*fcf3ce44SJohn Forte 	/* remove the object from object container */
3666*fcf3ce44SJohn Forte 	obj = cache_remove(lcp, 0);
3667*fcf3ce44SJohn Forte 
3668*fcf3ce44SJohn Forte 	if (obj == NULL) {
3669*fcf3ce44SJohn Forte 		return (0);
3670*fcf3ce44SJohn Forte 	}
3671*fcf3ce44SJohn Forte 
3672*fcf3ce44SJohn Forte 	/* trigger a scn */
3673*fcf3ce44SJohn Forte 	if (scn_q != NULL) {
3674*fcf3ce44SJohn Forte 		(void) make_scn(ISNS_OBJECT_REMOVED, obj);
3675*fcf3ce44SJohn Forte 	}
3676*fcf3ce44SJohn Forte 
3677*fcf3ce44SJohn Forte 	/* dereg children */
3678*fcf3ce44SJohn Forte 	i = 0;
3679*fcf3ce44SJohn Forte 	while (ec == 0 && !parent_flag &&
3680*fcf3ce44SJohn Forte 	    i < NUM_OF_CHILD[obj->type]) {
3681*fcf3ce44SJohn Forte 		type = TYPE_OF_CHILD[obj->type][i];
3682*fcf3ce44SJohn Forte 		cuidp = get_child_n(obj, i);
3683*fcf3ce44SJohn Forte 		if (cuidp != NULL) {
3684*fcf3ce44SJohn Forte 			num = *cuidp;
3685*fcf3ce44SJohn Forte 		} else {
3686*fcf3ce44SJohn Forte 			num = 0;
3687*fcf3ce44SJohn Forte 		}
3688*fcf3ce44SJohn Forte 		while (ec == 0 && num > 0) {
3689*fcf3ce44SJohn Forte 			uid = cuidp[num];
3690*fcf3ce44SJohn Forte 			if (uid != 0) {
3691*fcf3ce44SJohn Forte 				SET_UID_LCP(lcp, type, uid);
3692*fcf3ce44SJohn Forte 				ec = do_dereg(lcp,
3693*fcf3ce44SJohn Forte 				    parent_flag,
3694*fcf3ce44SJohn Forte 				    1,
3695*fcf3ce44SJohn Forte 				    pending);
3696*fcf3ce44SJohn Forte 			}
3697*fcf3ce44SJohn Forte 			num --;
3698*fcf3ce44SJohn Forte 		}
3699*fcf3ce44SJohn Forte 		i ++;
3700*fcf3ce44SJohn Forte 	}
3701*fcf3ce44SJohn Forte 
3702*fcf3ce44SJohn Forte 	/* clear the ref bit on the ref'd object */
3703*fcf3ce44SJohn Forte 	if (ec == 0 && TYPE_OF_REF[obj->type][0] > 0) {
3704*fcf3ce44SJohn Forte 		uid = 0;
3705*fcf3ce44SJohn Forte 		do {
3706*fcf3ce44SJohn Forte 			(void) setup_ref_lcp(lcp, obj, NULL);
3707*fcf3ce44SJohn Forte 			lcp->curr_uid = uid;
3708*fcf3ce44SJohn Forte 			lcp->data[2].ui = obj->type;
3709*fcf3ce44SJohn Forte 			if (cache_lookup(lcp, &uid, cb_clear_ref) != 0) {
3710*fcf3ce44SJohn Forte 				UPDATE_LCP_UID(lcp, uid);
3711*fcf3ce44SJohn Forte 				ec = do_dereg(lcp,
3712*fcf3ce44SJohn Forte 				    parent_flag,
3713*fcf3ce44SJohn Forte 				    child_flag,
3714*fcf3ce44SJohn Forte 				    pending);
3715*fcf3ce44SJohn Forte 			}
3716*fcf3ce44SJohn Forte 		} while (uid != 0);
3717*fcf3ce44SJohn Forte 	}
3718*fcf3ce44SJohn Forte 
3719*fcf3ce44SJohn Forte 	/* remove it from the parent */
3720*fcf3ce44SJohn Forte 	if (ec == 0 && !child_flag &&
3721*fcf3ce44SJohn Forte 	    TYPE_OF_PARENT[obj->type] > 0 &&
3722*fcf3ce44SJohn Forte 	    (uid = setup_parent_lcp(lcp, obj)) != 0) {
3723*fcf3ce44SJohn Forte 		if (cache_lookup(lcp, NULL, cb_remove_child) != 0) {
3724*fcf3ce44SJohn Forte 			UPDATE_LCP_UID(lcp, uid);
3725*fcf3ce44SJohn Forte 			ec = do_dereg(lcp,
3726*fcf3ce44SJohn Forte 			    1,
3727*fcf3ce44SJohn Forte 			    child_flag,
3728*fcf3ce44SJohn Forte 			    0);
3729*fcf3ce44SJohn Forte 		}
3730*fcf3ce44SJohn Forte 	}
3731*fcf3ce44SJohn Forte 
3732*fcf3ce44SJohn Forte 	if (ec == 0 && !child_flag) {
3733*fcf3ce44SJohn Forte 		/* remove it from persistent data store */
3734*fcf3ce44SJohn Forte 		if (sys_q) {
3735*fcf3ce44SJohn Forte 			ec = write_data(DATA_DELETE, obj);
3736*fcf3ce44SJohn Forte 		}
3737*fcf3ce44SJohn Forte 		/* remove esi event entry */
3738*fcf3ce44SJohn Forte 		if (ec == 0) {
3739*fcf3ce44SJohn Forte 			(void) esi_remove_obj(obj, pending);
3740*fcf3ce44SJohn Forte 		}
3741*fcf3ce44SJohn Forte 
3742*fcf3ce44SJohn Forte 		/* save the parent uid for caller */
3743*fcf3ce44SJohn Forte 		if (TYPE_OF_PARENT[obj->type] != 0) {
3744*fcf3ce44SJohn Forte 			lcp->curr_uid = get_parent_uid(obj);
3745*fcf3ce44SJohn Forte 		} else {
3746*fcf3ce44SJohn Forte 			/* it's the parent itself */
3747*fcf3ce44SJohn Forte 			lcp->curr_uid = get_obj_uid(obj);
3748*fcf3ce44SJohn Forte 		}
3749*fcf3ce44SJohn Forte 	}
3750*fcf3ce44SJohn Forte 
3751*fcf3ce44SJohn Forte 	/* remove this portal from scn registry */
3752*fcf3ce44SJohn Forte 	if (ec == 0 &&
3753*fcf3ce44SJohn Forte 	    obj->type == OBJ_PORTAL) {
3754*fcf3ce44SJohn Forte 		(void) remove_scn_portal(get_obj_uid(obj));
3755*fcf3ce44SJohn Forte 	}
3756*fcf3ce44SJohn Forte 
3757*fcf3ce44SJohn Forte 	/* free the object */
3758*fcf3ce44SJohn Forte 	(void) free_object(obj);
3759*fcf3ce44SJohn Forte 
3760*fcf3ce44SJohn Forte 	return (ec);
3761*fcf3ce44SJohn Forte }
3762*fcf3ce44SJohn Forte 
3763*fcf3ce44SJohn Forte /*
3764*fcf3ce44SJohn Forte  * ****************************************************************************
3765*fcf3ce44SJohn Forte  *
3766*fcf3ce44SJohn Forte  * dereg_assoc:
3767*fcf3ce44SJohn Forte  *	Remove one association object from object container.
3768*fcf3ce44SJohn Forte  *
3769*fcf3ce44SJohn Forte  * lcp	- the lookup control for the object being removed.
3770*fcf3ce44SJohn Forte  * return - error code.
3771*fcf3ce44SJohn Forte  *
3772*fcf3ce44SJohn Forte  * ****************************************************************************
3773*fcf3ce44SJohn Forte  */
3774*fcf3ce44SJohn Forte int
3775*fcf3ce44SJohn Forte dereg_assoc(
3776*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp
3777*fcf3ce44SJohn Forte )
3778*fcf3ce44SJohn Forte {
3779*fcf3ce44SJohn Forte 	isns_obj_t *obj;
3780*fcf3ce44SJohn Forte 
3781*fcf3ce44SJohn Forte 	obj = cache_remove(lcp, 1);
3782*fcf3ce44SJohn Forte 
3783*fcf3ce44SJohn Forte 	/* free the object */
3784*fcf3ce44SJohn Forte 	if (obj != NULL) {
3785*fcf3ce44SJohn Forte 		free_object(obj);
3786*fcf3ce44SJohn Forte 	}
3787*fcf3ce44SJohn Forte 
3788*fcf3ce44SJohn Forte 	return (0);
3789*fcf3ce44SJohn Forte }
3790*fcf3ce44SJohn Forte 
3791*fcf3ce44SJohn Forte /*
3792*fcf3ce44SJohn Forte  * ****************************************************************************
3793*fcf3ce44SJohn Forte  *
3794*fcf3ce44SJohn Forte  * dereg_object:
3795*fcf3ce44SJohn Forte  *	Remove one object from object container.
3796*fcf3ce44SJohn Forte  *
3797*fcf3ce44SJohn Forte  * lcp	- the lookup control for the object being removed.
3798*fcf3ce44SJohn Forte  * return - error code.
3799*fcf3ce44SJohn Forte  *
3800*fcf3ce44SJohn Forte  * ****************************************************************************
3801*fcf3ce44SJohn Forte  */
3802*fcf3ce44SJohn Forte int
3803*fcf3ce44SJohn Forte dereg_object(
3804*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
3805*fcf3ce44SJohn Forte 	int pending
3806*fcf3ce44SJohn Forte )
3807*fcf3ce44SJohn Forte {
3808*fcf3ce44SJohn Forte 	return (do_dereg(lcp, 0, 0, pending));
3809*fcf3ce44SJohn Forte }
3810*fcf3ce44SJohn Forte 
3811*fcf3ce44SJohn Forte /*
3812*fcf3ce44SJohn Forte  * ****************************************************************************
3813*fcf3ce44SJohn Forte  *
3814*fcf3ce44SJohn Forte  * data_sync:
3815*fcf3ce44SJohn Forte  *	Synchronize the cache with persistent data store.
3816*fcf3ce44SJohn Forte  *	Flush the cache data to data store if the input ec is zero,
3817*fcf3ce44SJohn Forte  *	retreat the changes in cache and ignore data store update
3818*fcf3ce44SJohn Forte  *	if there is an error.
3819*fcf3ce44SJohn Forte  *
3820*fcf3ce44SJohn Forte  * ec	- error code.
3821*fcf3ce44SJohn Forte  * return - error code.
3822*fcf3ce44SJohn Forte  *
3823*fcf3ce44SJohn Forte  * ****************************************************************************
3824*fcf3ce44SJohn Forte  */
3825*fcf3ce44SJohn Forte int
3826*fcf3ce44SJohn Forte data_sync(
3827*fcf3ce44SJohn Forte 	int ec
3828*fcf3ce44SJohn Forte )
3829*fcf3ce44SJohn Forte {
3830*fcf3ce44SJohn Forte 	/* cache is updated successfully, commit the data to data store */
3831*fcf3ce44SJohn Forte 	if (IS_CACHE_UPDATED()) {
3832*fcf3ce44SJohn Forte 		if (ec == 0) {
3833*fcf3ce44SJohn Forte 			ec = write_data(DATA_COMMIT, NULL);
3834*fcf3ce44SJohn Forte 		}
3835*fcf3ce44SJohn Forte 		if (ec == 0) {
3836*fcf3ce44SJohn Forte 			/* successful, trigger the SCN */
3837*fcf3ce44SJohn Forte 			(void) queue_msg_set(scn_q, SCN_TRIGGER, (void *)NULL);
3838*fcf3ce44SJohn Forte 		} else {
3839*fcf3ce44SJohn Forte 			shutdown_server();
3840*fcf3ce44SJohn Forte 		}
3841*fcf3ce44SJohn Forte 	} else {
3842*fcf3ce44SJohn Forte 		/* ignore all SCNs which have been generated */
3843*fcf3ce44SJohn Forte 		(void) queue_msg_set(scn_q, SCN_IGNORE, (void *)NULL);
3844*fcf3ce44SJohn Forte 
3845*fcf3ce44SJohn Forte 		(void) write_data(DATA_RETREAT, NULL);
3846*fcf3ce44SJohn Forte 	}
3847*fcf3ce44SJohn Forte 
3848*fcf3ce44SJohn Forte 	return (ec);
3849*fcf3ce44SJohn Forte }
3850*fcf3ce44SJohn Forte 
3851*fcf3ce44SJohn Forte static pthread_mutex_t name_mtx[3] = {
3852*fcf3ce44SJohn Forte 	PTHREAD_MUTEX_INITIALIZER,
3853*fcf3ce44SJohn Forte 	PTHREAD_MUTEX_INITIALIZER,
3854*fcf3ce44SJohn Forte 	PTHREAD_MUTEX_INITIALIZER
3855*fcf3ce44SJohn Forte };
3856*fcf3ce44SJohn Forte static const char *name_pattern[3] = {
3857*fcf3ce44SJohn Forte 	"ENTITY_ID_%d",
3858*fcf3ce44SJohn Forte 	"DD_%d",
3859*fcf3ce44SJohn Forte 	"DD-Set_%d"
3860*fcf3ce44SJohn Forte };
3861*fcf3ce44SJohn Forte static uint32_t name_count[3] = {
3862*fcf3ce44SJohn Forte 	0,
3863*fcf3ce44SJohn Forte 	0,
3864*fcf3ce44SJohn Forte 	0
3865*fcf3ce44SJohn Forte };
3866*fcf3ce44SJohn Forte 
3867*fcf3ce44SJohn Forte /*
3868*fcf3ce44SJohn Forte  * ****************************************************************************
3869*fcf3ce44SJohn Forte  *
3870*fcf3ce44SJohn Forte  * make_unique_name:
3871*fcf3ce44SJohn Forte  *	make a default unique name for a newly registered network entity,
3872*fcf3ce44SJohn Forte  *	discovery domain or discovery domain set object.
3873*fcf3ce44SJohn Forte  *
3874*fcf3ce44SJohn Forte  * len	- pointer of the length of the new name for returning.
3875*fcf3ce44SJohn Forte  * tag	- which attribute of the new name is for.
3876*fcf3ce44SJohn Forte  * return - the name being made.
3877*fcf3ce44SJohn Forte  *
3878*fcf3ce44SJohn Forte  * ****************************************************************************
3879*fcf3ce44SJohn Forte  */
3880*fcf3ce44SJohn Forte static char *
3881*fcf3ce44SJohn Forte make_unique_name(
3882*fcf3ce44SJohn Forte 	int *len,
3883*fcf3ce44SJohn Forte 	uint32_t tag
3884*fcf3ce44SJohn Forte )
3885*fcf3ce44SJohn Forte {
3886*fcf3ce44SJohn Forte 	int i;
3887*fcf3ce44SJohn Forte 	int count;
3888*fcf3ce44SJohn Forte 	char name[32] = { 0 };
3889*fcf3ce44SJohn Forte 
3890*fcf3ce44SJohn Forte 	char *p;
3891*fcf3ce44SJohn Forte 
3892*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
3893*fcf3ce44SJohn Forte 
3894*fcf3ce44SJohn Forte 	lc.curr_uid = 0;
3895*fcf3ce44SJohn Forte 
3896*fcf3ce44SJohn Forte 	switch (tag) {
3897*fcf3ce44SJohn Forte 	case ISNS_EID_ATTR_ID:
3898*fcf3ce44SJohn Forte 		i = 0;
3899*fcf3ce44SJohn Forte 		lc.type = OBJ_ENTITY;
3900*fcf3ce44SJohn Forte 		lc.id[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID);
3901*fcf3ce44SJohn Forte 		break;
3902*fcf3ce44SJohn Forte 	case ISNS_DD_NAME_ATTR_ID:
3903*fcf3ce44SJohn Forte 		i = 1;
3904*fcf3ce44SJohn Forte 		lc.type = OBJ_DD;
3905*fcf3ce44SJohn Forte 		lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
3906*fcf3ce44SJohn Forte 		break;
3907*fcf3ce44SJohn Forte 	case ISNS_DD_SET_NAME_ATTR_ID:
3908*fcf3ce44SJohn Forte 		i = 2;
3909*fcf3ce44SJohn Forte 		lc.type = OBJ_DDS;
3910*fcf3ce44SJohn Forte 		lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
3911*fcf3ce44SJohn Forte 		break;
3912*fcf3ce44SJohn Forte 	default:
3913*fcf3ce44SJohn Forte 		ASSERT(0);
3914*fcf3ce44SJohn Forte 		break;
3915*fcf3ce44SJohn Forte 	}
3916*fcf3ce44SJohn Forte 
3917*fcf3ce44SJohn Forte 	lc.op[0] = OP_STRING;
3918*fcf3ce44SJohn Forte 	lc.op[1] = 0;
3919*fcf3ce44SJohn Forte 	do {
3920*fcf3ce44SJohn Forte 		(void) pthread_mutex_lock(&name_mtx[i]);
3921*fcf3ce44SJohn Forte 		count = ++ name_count[i];
3922*fcf3ce44SJohn Forte 		(void) pthread_mutex_unlock(&name_mtx[i]);
3923*fcf3ce44SJohn Forte 		/* no more space, failure */
3924*fcf3ce44SJohn Forte 		if (count == 0) {
3925*fcf3ce44SJohn Forte 			return (NULL);
3926*fcf3ce44SJohn Forte 		}
3927*fcf3ce44SJohn Forte 		(void) sprintf(name, name_pattern[i], count);
3928*fcf3ce44SJohn Forte 		lc.data[0].ptr = (uchar_t *)name;
3929*fcf3ce44SJohn Forte 	} while (is_obj_there(&lc) != 0);
3930*fcf3ce44SJohn Forte 
3931*fcf3ce44SJohn Forte 	/* 4-bytes aligned length */
3932*fcf3ce44SJohn Forte 	*len = strlen(name);
3933*fcf3ce44SJohn Forte 	*len = *len + (4 - *len % 4);
3934*fcf3ce44SJohn Forte 	p = (char *)malloc(*len);
3935*fcf3ce44SJohn Forte 	if (p != NULL) {
3936*fcf3ce44SJohn Forte 		(void) strcpy(p, name);
3937*fcf3ce44SJohn Forte 	}
3938*fcf3ce44SJohn Forte 	return (p);
3939*fcf3ce44SJohn Forte }
3940*fcf3ce44SJohn Forte 
3941*fcf3ce44SJohn Forte #ifdef DEBUG
3942*fcf3ce44SJohn Forte void
3943*fcf3ce44SJohn Forte obj_dump(
3944*fcf3ce44SJohn Forte 	void *p
3945*fcf3ce44SJohn Forte )
3946*fcf3ce44SJohn Forte {
3947*fcf3ce44SJohn Forte 	print_object(NULL, (isns_obj_t *)p);
3948*fcf3ce44SJohn Forte }
3949*fcf3ce44SJohn Forte #endif
3950