4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
31 #include "isns_server.h"
32 #include "isns_func.h"
33 #include "isns_msgq.h"
34 #include "isns_htab.h"
35 #include "isns_cache.h"
44 extern const int NUM_OF_ATTRS
[MAX_OBJ_TYPE_FOR_SIZE
];
45 extern const int UID_ATTR_INDEX
[MAX_OBJ_TYPE_FOR_SIZE
];
46 extern const int NUM_OF_CHILD
[MAX_OBJ_TYPE
];
47 extern const int TYPE_OF_CHILD
[MAX_OBJ_TYPE
][MAX_CHILD_TYPE
];
52 const int TAG_RANGE
[MAX_OBJ_TYPE
][3] = {
54 { ENTITY_KEY
, LAST_TAG_ENTITY
, ENTITY_END
},
55 { ISCSI_KEY
, LAST_TAG_ISCSI
, ISCSI_END
},
56 { PORTAL_KEY1
, LAST_TAG_PORTAL
, PORTAL_END
},
57 { PG_KEY1
, LAST_TAG_PG
, PG_END
},
58 { DD_KEY
, LAST_TAG_DD
, DD_END
},
59 { DDS_KEY
, LAST_TAG_DDS
, DDS_END
}
65 typedef int (*qry_func_t
)(lookup_ctrl_t
*);
67 /* Edge functions of each adjacent object */
68 static int qry_c2e(lookup_ctrl_t
*);
69 static int qry_ds2m(lookup_ctrl_t
*);
70 static int qry_slf(lookup_ctrl_t
*);
71 static int qry_e2i(lookup_ctrl_t
*);
72 static int qry_e2p(lookup_ctrl_t
*);
73 static int qry_e2g(lookup_ctrl_t
*);
74 static int qry_i2g(lookup_ctrl_t
*);
75 static int qry_i2d(lookup_ctrl_t
*);
76 static int qry_p2g(lookup_ctrl_t
*);
77 static int qry_g2i(lookup_ctrl_t
*);
78 static int qry_g2p(lookup_ctrl_t
*);
79 static int qry_d2s(lookup_ctrl_t
*);
81 /* The directed cyclic graph of query procedure. */
82 /* __|____e_________i_________p_________g_________d_________s____ */
83 /* e | qry_slf...qry_e2i...qry_e2p...qry_e2g...NULL......NULL.... */
84 /* i | qry_c2e...qry_slf...NULL......qry_i2g...qry_i2d...NULL.... */
85 /* p | qry_c2e...NULL......qry_slf...qry_p2g...NULL......NULL.... */
86 /* g | qry_c2e...qry_g2i...qry_g2p...qry_slf...NULL......NULL.... */
87 /* d | NULL......qry_ds2m..NULL......NULL......qry_slf...qry_d2s. */
88 /* s | NULL......NULL......NULL......NULL......qry_ds2m..qry_slf. */
90 /* The type of spanning tree of query graph. */
91 typedef struct adjvex
{
94 struct adjvex
const *v
;
97 /* The solid edges in the spanning tree. */
98 static const adjvex_t v_slf
= { &qry_slf
, 0, NULL
};
99 static const adjvex_t v_c2e
= { &qry_c2e
, OBJ_ENTITY
, NULL
};
100 static const adjvex_t v_e2i
= { &qry_e2i
, OBJ_ISCSI
, NULL
};
101 static const adjvex_t v_e2p
= { &qry_e2p
, OBJ_PORTAL
, NULL
};
102 static const adjvex_t v_e2g
= { &qry_e2g
, OBJ_PG
, NULL
};
103 static const adjvex_t v_i2g
= { &qry_i2g
, OBJ_PG
, NULL
};
104 static const adjvex_t v_i2d
= { &qry_i2d
, OBJ_DD
, NULL
};
105 static const adjvex_t v_p2g
= { &qry_p2g
, OBJ_PG
, NULL
};
106 static const adjvex_t v_g2i
= { &qry_g2i
, OBJ_ISCSI
, NULL
};
107 static const adjvex_t v_g2p
= { &qry_g2p
, OBJ_PORTAL
, NULL
};
108 static const adjvex_t v_d2s
= { &qry_d2s
, OBJ_DDS
, NULL
};
109 static const adjvex_t v_d2i
= { &qry_ds2m
, OBJ_ISCSI
, NULL
};
110 static const adjvex_t v_s2d
= { &qry_ds2m
, OBJ_DD
, NULL
};
112 /* The virtual edges in the spanning tree. */
113 static const adjvex_t v_i2p
= { &qry_i2g
, OBJ_PG
, &v_g2p
};
114 static const adjvex_t v_i2s
= { &qry_i2d
, OBJ_DD
, &v_d2s
};
116 static const adjvex_t v_g2d
= { &qry_g2i
, OBJ_ISCSI
, &v_i2d
};
117 static const adjvex_t v_g2s
= { &qry_g2i
, OBJ_ISCSI
, &v_i2s
};
119 static const adjvex_t v_p2i
= { &qry_p2g
, OBJ_PG
, &v_g2i
};
120 static const adjvex_t v_p2d
= { &qry_p2g
, OBJ_PG
, &v_g2d
};
121 static const adjvex_t v_p2s
= { &qry_p2g
, OBJ_PG
, &v_g2s
};
123 static const adjvex_t v_e2d
= { &qry_e2i
, OBJ_ISCSI
, &v_i2d
};
124 static const adjvex_t v_e2s
= { &qry_e2i
, OBJ_ISCSI
, &v_i2s
};
126 static const adjvex_t v_d2e
= { &qry_ds2m
, OBJ_ISCSI
, &v_c2e
};
127 static const adjvex_t v_d2p
= { &qry_ds2m
, OBJ_ISCSI
, &v_i2p
};
128 static const adjvex_t v_d2g
= { &qry_ds2m
, OBJ_ISCSI
, &v_i2g
};
130 static const adjvex_t v_s2e
= { &qry_ds2m
, OBJ_DD
, &v_d2e
};
131 static const adjvex_t v_s2i
= { &qry_ds2m
, OBJ_DD
, &v_d2i
};
132 static const adjvex_t v_s2p
= { &qry_ds2m
, OBJ_DD
, &v_d2p
};
133 static const adjvex_t v_s2g
= { &qry_ds2m
, OBJ_DD
, &v_d2g
};
135 /* the vector of query graph */
136 static const adjvex_t
*qry_puzzle
[MAX_OBJ_TYPE
][MAX_OBJ_TYPE
] = {
138 { NULL
, &v_slf
, &v_e2i
, &v_e2p
, &v_e2g
, &v_e2d
, &v_e2s
},
139 { NULL
, &v_c2e
, &v_slf
, &v_i2p
, &v_i2g
, &v_i2d
, &v_i2s
},
140 { NULL
, &v_c2e
, &v_p2i
, &v_slf
, &v_p2g
, &v_p2d
, &v_p2s
},
141 { NULL
, &v_c2e
, &v_g2i
, &v_g2p
, &v_slf
, &v_g2d
, &v_g2s
},
142 { NULL
, &v_d2e
, &v_d2i
, &v_d2p
, &v_d2g
, &v_slf
, &v_d2s
},
143 { NULL
, &v_s2e
, &v_s2i
, &v_s2p
, &v_s2g
, &v_s2d
, &v_slf
}
149 /* LINTED E_FUNC_ARG_UNUSED */
153 uint32_t puid
= get_parent_uid((isns_obj_t
*)p1
);
163 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
164 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
165 isns_type_t type
= lcp
->data
[1].ui
;
166 uint32_t *uidp
= get_child_t(obj
, type
);
170 if (uidp
!= NULL
&& *uidp
> 0) {
172 p
= malloc(num
* sizeof (*p
));
175 (void) memcpy(p
, uidp
, num
* sizeof (*p
));
177 lcp
->data
[2].ptr
= (uchar_t
*)p
;
179 return (ISNS_RSP_INTERNAL_ERROR
);
194 uint32_t uid
= lcp
->curr_uid
; /* last child */
195 uint32_t num_of_child
;
198 uint32_t tmp_uid
= 0;
200 /* the first times of query */
202 lcp
->data
[1].ui
= type
;
203 ec
= cache_lookup(lcp
, NULL
, cb_qry_child_uids
);
206 num_of_child
= lcp
->id
[2];
207 uids
= (uint32_t *)lcp
->data
[2].ptr
;
209 while (num_of_child
> 0) {
220 /* no more child, clean up memory */
224 lcp
->data
[2].ptr
= NULL
;
226 /* free up the memory */
230 /* save it for returning and querying next uid */
243 /* child object has only one parent */
244 if (lcp
->curr_uid
== 0) {
245 uid
= (uint32_t)cache_lookup(lcp
, NULL
,
251 /* save the result for returnning */
264 uint32_t uid
= lcp
->curr_uid
; /* last member */
265 isns_type_t type
= lcp
->type
;
266 uint32_t ds_id
= lcp
->data
[0].ui
;
273 /* the first times of query */
275 ec
= (type
== OBJ_DD
) ?
276 get_dd_matrix(ds_id
, &p
, &n
) :
277 get_dds_matrix(ds_id
, &p
, &n
);
279 lcp
->data
[1].ptr
= (uchar_t
*)p
;
282 p
= (bmp_t
*)lcp
->data
[1].ptr
;
285 FOR_EACH_MEMBER(p
, n
, tmp_uid
, {
287 lcp
->curr_uid
= tmp_uid
;
292 /* no more member, clean up memory */
294 lcp
->data
[1].ptr
= NULL
;
296 /* free up the matrix */
311 if (lcp
->curr_uid
== 0) {
312 uid
= lcp
->data
[0].ui
;
327 return (e2c(lcp
, OBJ_ISCSI
));
335 return (e2c(lcp
, OBJ_PORTAL
));
343 uint32_t uid
= lcp
->curr_uid
; /* last pg */
345 htab_t
*htab
= cache_get_htab(OBJ_PG
);
350 SET_UID_LCP(&lc
, OBJ_PG
, 0);
352 /* this is a shortcut */
353 FOR_EACH_ITEM(htab
, uid
, {
355 puid
= (uint32_t)cache_lookup(&lc
, NULL
,
357 if (puid
== lcp
->data
[0].ui
) {
358 /* keep the current uid */
376 uint32_t uid
= lcp
->curr_uid
; /* last pg */
379 /* the first times of query */
381 lcp
->id
[1] = ISNS_ISCSI_NAME_ATTR_ID
;
382 ec
= cache_lookup(lcp
, NULL
, cb_clone_attrs
);
385 if (lcp
->data
[1].ptr
!= NULL
) {
389 lc
.id
[0] = ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID
);
390 lc
.op
[0] = OP_STRING
;
391 lc
.data
[0].ptr
= lcp
->data
[1].ptr
;
394 uid
= is_obj_there(&lc
);
399 /* no more pg, update lcp with pg object */
403 /* clean up the memory */
404 if (lcp
->data
[1].ptr
!= NULL
) {
405 free(lcp
->data
[1].ptr
);
407 lcp
->data
[1].ptr
= NULL
;
411 /* save it for returning and querying next pg */
422 uint32_t dd_id
= lcp
->curr_uid
; /* last dd_id */
423 uint32_t uid
= lcp
->data
[0].ui
;
425 dd_id
= get_dd_id(uid
, dd_id
);
427 /* save it for returning and getting next dd */
428 lcp
->curr_uid
= dd_id
;
440 uint32_t uid
= lcp
->curr_uid
; /* last pg */
443 /* the first time of query */
445 /* use 1&2 for the portal ip address & port */
446 lcp
->id
[1] = ISNS_PORTAL_IP_ADDR_ATTR_ID
;
447 lcp
->id
[2] = ISNS_PORTAL_PORT_ATTR_ID
;
448 ec
= cache_lookup(lcp
, NULL
, cb_clone_attrs
);
451 if (lcp
->data
[1].ip
!= NULL
) {
455 lc
.id
[0] = ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
);
456 lc
.op
[0] = OP_MEMORY_IP6
;
457 lc
.data
[0].ip
= lcp
->data
[1].ip
;
458 lc
.id
[1] = ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID
);
459 lc
.op
[1] = OP_INTEGER
;
460 lc
.data
[1].ui
= lcp
->data
[2].ui
;
463 uid
= is_obj_there(&lc
);
468 /* no more pg, clean up memory */
473 /* clean up the memory */
474 if (lcp
->data
[1].ip
!= NULL
) {
475 free(lcp
->data
[1].ip
);
477 lcp
->data
[1].ip
= NULL
;
482 /* save it for returning and next query */
495 uint32_t uid
= lcp
->curr_uid
; /* last node */
498 /* the first time of query */
500 /* use slot 1 for the storage node name */
501 lcp
->id
[1] = ISNS_PG_ISCSI_NAME_ATTR_ID
;
502 ec
= cache_lookup(lcp
, NULL
, cb_clone_attrs
);
504 if (lcp
->data
[1].ptr
!= NULL
) {
505 /* iscsi node lookup */
508 lc
.id
[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
);
509 lc
.op
[0] = OP_STRING
;
510 lc
.data
[0].ptr
= lcp
->data
[1].ptr
;
513 uid
= is_obj_there(&lc
);
515 /* no longer need it, clean it up */
516 free(lcp
->data
[1].ptr
);
517 lcp
->data
[1].ptr
= NULL
;
519 /* no longer need it, reset it */
522 /* one pg has maximum number of one storage node */
526 /* save it for returning and next query */
539 uint32_t uid
= lcp
->curr_uid
; /* last portal */
542 /* the first times of query */
544 /* use 1&2 for the portal ip addr and port */
545 lcp
->id
[1] = ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
;
546 lcp
->id
[2] = ISNS_PG_PORTAL_PORT_ATTR_ID
;
547 ec
= cache_lookup(lcp
, NULL
, cb_clone_attrs
);
549 if (lcp
->data
[1].ip
!= NULL
) {
552 lc
.type
= OBJ_PORTAL
;
553 lc
.id
[0] = ATTR_INDEX_PORTAL(
554 ISNS_PORTAL_IP_ADDR_ATTR_ID
);
555 lc
.op
[0] = OP_MEMORY_IP6
;
556 lc
.data
[0].ip
= lcp
->data
[1].ip
;
557 lc
.id
[1] = ATTR_INDEX_PORTAL(
558 ISNS_PORTAL_PORT_ATTR_ID
);
559 lc
.op
[1] = OP_INTEGER
;
560 lc
.data
[1].ui
= lcp
->data
[2].ui
;
563 uid
= is_obj_there(&lc
);
565 /* no longer need it, reset it */
566 free(lcp
->data
[1].ip
);
567 lcp
->data
[1].ip
= NULL
;
569 /* no longer need it, reset it */
574 /* one pg has maximum number of one portal */
578 /* save it for returning and next query */
589 uint32_t dds_id
= lcp
->curr_uid
; /* last dds */
590 uint32_t dd_id
= lcp
->data
[0].ui
;
592 dds_id
= get_dds_id(dd_id
, dds_id
);
594 /* save it for returning and for getting next dds */
595 lcp
->curr_uid
= dds_id
;
611 uint32_t min_tag
, max_tag
;
615 min_tag
= TAG_RANGE
[type
][0];
616 max_tag
= TAG_RANGE
[type
][2];
618 while (key_len
!= 0 && ec
== 0) {
620 if (tag
< min_tag
|| tag
> max_tag
) {
621 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
622 } else if (key
->attr_len
> 0 && attrs
!= NULL
) {
623 attr
= &attrs
[tag
- min_tag
]; /* ATTR_INDEX_xxx */
624 ec
= extract_attr(attr
, key
, 0);
625 if (ec
== ISNS_RSP_INVALID_REGIS
) {
626 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
629 NEXT_TLV(key
, key_len
);
635 static lookup_method_t
640 lookup_method_t method
= 0;
644 case ISNS_EID_ATTR_ID
:
645 case ISNS_PORTAL_NAME_ATTR_ID
:
646 case ISNS_ISCSI_ALIAS_ATTR_ID
:
647 case ISNS_DD_SET_NAME_ATTR_ID
:
648 case ISNS_DD_NAME_ATTR_ID
:
649 case ISNS_ISCSI_NAME_ATTR_ID
:
650 case ISNS_PG_ISCSI_NAME_ATTR_ID
:
651 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID
:
655 case ISNS_MGMT_IP_ADDR_ATTR_ID
:
656 case ISNS_PORTAL_IP_ADDR_ATTR_ID
:
657 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
:
658 method
= OP_MEMORY_IP6
;
661 case ISNS_ENTITY_PROTOCOL_ATTR_ID
:
662 case ISNS_VERSION_RANGE_ATTR_ID
:
663 case ISNS_ENTITY_REG_PERIOD_ATTR_ID
:
664 case ISNS_ENTITY_INDEX_ATTR_ID
:
665 case ISNS_PORTAL_PORT_ATTR_ID
:
666 case ISNS_ESI_INTERVAL_ATTR_ID
:
667 case ISNS_ESI_PORT_ATTR_ID
:
668 case ISNS_PORTAL_INDEX_ATTR_ID
:
669 case ISNS_SCN_PORT_ATTR_ID
:
670 case ISNS_ISCSI_NODE_TYPE_ATTR_ID
:
671 case ISNS_ISCSI_SCN_BITMAP_ATTR_ID
:
672 case ISNS_ISCSI_NODE_INDEX_ATTR_ID
:
673 case ISNS_PG_PORTAL_PORT_ATTR_ID
:
674 case ISNS_PG_TAG_ATTR_ID
:
675 case ISNS_PG_INDEX_ATTR_ID
:
676 case ISNS_DD_SET_ID_ATTR_ID
:
677 case ISNS_DD_SET_STATUS_ATTR_ID
:
678 case ISNS_DD_ID_ATTR_ID
:
679 /* all other attrs */
694 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
695 isns_attr_t
*attrs
= (isns_attr_t
*)
696 ((lookup_ctrl_t
*)p2
)->data
[1].ptr
;
699 int match
= 1; /* 0: not match, otherwise: match */
705 for (i
= 0; match
!= 0 && i
< NUM_OF_ATTRS
[obj
->type
]; i
++) {
706 if (attrs
->tag
!= 0 && attrs
->len
> 0) {
708 lc
.op
[0] = get_op_method(attrs
->tag
);
709 lc
.data
[0].ptr
= attrs
->value
.ptr
;
710 match
= key_cmp(&lc
, obj
) == 0 ? 1 : 0;
725 int match
; /* 0: not match, otherwise: match */
728 SET_UID_LCP(&lc
, type
, uid
);
730 lc
.data
[1].ptr
= (uchar_t
*)attrs
;
732 match
= cache_lookup(&lc
, NULL
, cb_attrs_match
);
754 /* check for duplication */
755 if (n
> 0 && uid
<= p
[n
- 1]) {
769 s
= (s
== 0) ? 8 : s
* 2;
770 t
= reallocarray(p
, s
, sizeof (uint32_t));
776 ec
= ISNS_RSP_INTERNAL_ERROR
;
791 uint32_t *num_of_objs
,
795 isns_type_t src_type
,
801 lookup_ctrl_t lc
= { 0 }; /* !!! need to be empty */
807 uint32_t *p
[2], n
[2], s
[2];
811 uint32_t *p2
, n2
, s2
;
814 /* initialize the circular list */
822 p
[j
] = malloc(8 * sizeof (uint32_t));
827 /* initial object type of being queried */
830 vex
= qry_puzzle
[src_type
][type
];
833 /* shift one on the circular list */
837 p1
= p
[i
]; n1
= n
[i
];
838 p2
= p
[j
]; n2
= n
[j
]; s2
= s
[j
];
840 /* prepare lookup control */
842 lc
.id
[0] = UID_ATTR_INDEX
[t
];
843 lc
.op
[0] = OP_INTEGER
;
845 /* result object type */
848 FOR_EACH_OBJS(p1
, n1
, uid
, {
853 while (ec
== 0 && uid
!= 0) {
855 attrs_match(type
, uid
, attrs
) != 0) {
856 ec
= insert_uid(&p2
, &n2
, &s2
, uid
);
862 n1
= n2
= 0; /* force break */
869 vex
= NULL
; /* force break */
872 p
[j
] = p2
; n
[j
] = n2
; s
[j
] = s2
;
873 /* reset the number of objects */
875 } while (vex
!= NULL
);
877 /* clean up the memory */
896 uint32_t num_of_nodes
,
901 uint32_t *num_of_objs
925 /* get the object type identified by the key */
926 *type
= TLV2TYPE(key
);
928 return (ISNS_RSP_INVALID_QRY
);
931 attrs
= &an_obj
.o
.attrs
[0];
932 /* validate the Message Key */
933 ec
= validate_qry_key(*type
, key
, key_len
, attrs
);
938 if (nodes_bmp
!= NULL
) {
939 FOR_EACH_MEMBER(nodes_bmp
, num_of_nodes
, node_uid
, {
941 obj_uids
, num_of_objs
, &size
, *type
,
942 node_uid
, OBJ_ISCSI
, attrs
);
949 htab
= cache_get_htab(OBJ_ISCSI
);
950 FOR_EACH_ITEM(htab
, node_uid
, {
952 obj_uids
, num_of_objs
, &size
, *type
,
953 node_uid
, OBJ_ISCSI
, attrs
);
966 isns_type_t src_type
,
969 uint32_t *num_of_ops
,
978 op_uids
, num_of_ops
, size
, op_type
,
979 uid
, src_type
, NULL
);
987 uint32_t num_of_nodes
,
990 uint32_t *num_of_ops
,
1002 if (nodes_bmp
!= NULL
) {
1003 FOR_EACH_MEMBER(nodes_bmp
, num_of_nodes
, node_uid
, {
1005 op_uids
, num_of_ops
, size
, op_type
,
1006 node_uid
, OBJ_ISCSI
, NULL
);
1013 htab
= cache_get_htab(OBJ_ISCSI
);
1014 FOR_EACH_ITEM(htab
, node_uid
, {
1016 op_uids
, num_of_ops
, size
, op_type
,
1017 node_uid
, OBJ_ISCSI
, NULL
);
1044 uint32_t pre_diff
= 0xFFFFFFFF;
1053 value
= tlv
->attr_value
;
1055 case ISNS_EID_ATTR_ID
:
1056 lc
.id
[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID
);
1057 lc
.op
[0] = OP_STRING
;
1058 lc
.data
[0].ptr
= (uchar_t
*)value
;
1060 case ISNS_ISCSI_NAME_ATTR_ID
:
1061 lc
.id
[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
);
1062 lc
.op
[0] = OP_STRING
;
1063 lc
.data
[0].ptr
= (uchar_t
*)value
;
1065 case ISNS_ISCSI_NODE_INDEX_ATTR_ID
:
1066 lc
.id
[0] = ATTR_INDEX_ISCSI(
1067 ISNS_ISCSI_NODE_INDEX_ATTR_ID
);
1068 lc
.op
[0] = OP_INTEGER
;
1069 lc
.data
[0].ui
= ntohl(*(uint32_t *)value
);
1071 case ISNS_PORTAL_IP_ADDR_ATTR_ID
:
1072 lc
.id
[0] = ATTR_INDEX_PORTAL(
1073 ISNS_PORTAL_IP_ADDR_ATTR_ID
);
1074 lc
.op
[0] = OP_MEMORY_IP6
;
1075 lc
.data
[0].ip
= (in6_addr_t
*)value
;
1076 NEXT_TLV(tlv
, tlv_len
);
1078 ((tag
= tlv
->attr_id
) ==
1079 ISNS_PORTAL_PORT_ATTR_ID
)) {
1080 value
= tlv
->attr_value
;
1081 lc
.id
[1] = ATTR_INDEX_PORTAL(
1082 ISNS_PORTAL_PORT_ATTR_ID
);
1083 lc
.op
[1] = OP_INTEGER
;
1084 lc
.data
[1].ui
= ntohl(*(uint32_t *)value
);
1089 case ISNS_PORTAL_INDEX_ATTR_ID
:
1090 lc
.id
[0] = ATTR_INDEX_PORTAL(ISNS_PORTAL_INDEX_ATTR_ID
);
1091 lc
.op
[0] = OP_INTEGER
;
1092 lc
.data
[0].ui
= ntohl(*(uint32_t *)value
);
1094 case ISNS_PG_INDEX_ATTR_ID
:
1095 lc
.id
[0] = ATTR_INDEX_PG(ISNS_PG_INDEX_ATTR_ID
);
1096 lc
.op
[0] = OP_INTEGER
;
1097 lc
.data
[0].ui
= ntohl(*(uint32_t *)value
);
1103 old
= is_obj_there(&lc
);
1113 if (diff
< pre_diff
) {
1131 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
1132 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
1134 uint16_t tlv_len
= lcp
->id
[1];
1135 isns_tlv_t
*tlv
= (isns_tlv_t
*)lcp
->data
[1].ptr
;
1136 conn_arg_t
*conn
= (conn_arg_t
*)lcp
->data
[2].ptr
;
1138 isns_type_t type
= obj
->type
;
1139 uint32_t min_tag
= TAG_RANGE
[type
][0];
1140 uint32_t mid_tag
= TAG_RANGE
[type
][1];
1141 uint32_t max_tag
= TAG_RANGE
[type
][2];
1149 isns_pdu_t
*rsp
= conn
->out_packet
.pdu
;
1150 size_t pl
= conn
->out_packet
.pl
;
1151 size_t sz
= conn
->out_packet
.sz
;
1154 if (tlv
->attr_len
== 0) {
1156 if (tag
<= mid_tag
) {
1157 id
= ATTR_INDEX(tag
, type
);
1158 attr
= &obj
->attrs
[id
];
1160 value
= (void *)attr
->value
.ptr
;
1161 ec
= pdu_add_tlv(&rsp
, &pl
, &sz
,
1162 tag
, len
, value
, 0);
1165 NEXT_TLV(tlv
, tlv_len
);
1168 tlv
->attr_id
>= min_tag
&&
1169 tlv
->attr_id
<= max_tag
);
1171 conn
->out_packet
.pdu
= rsp
;
1172 conn
->out_packet
.pl
= pl
;
1173 conn
->out_packet
.sz
= sz
;
1191 SET_UID_LCP(&lc
, type
, uid
);
1194 lc
.data
[1].ptr
= (uchar_t
*)tlv
;
1195 lc
.data
[2].ptr
= (uchar_t
*)conn
;
1197 ec
= cache_lookup(&lc
, NULL
, cb_qry_rsp
);
1211 isns_tlv_t
*tmp
= tlv
;
1212 uint32_t tmp_len
= tlv_len
;
1214 /* clear the length of all of tlv */
1215 while (tmp_len
> 8) {
1217 NEXT_TLV(tmp
, tmp_len
);
1220 return (get_qry_attrs(uid
, type
, tlv
, tlv_len
, conn
));