1a6d42e7dSPeter Dunlap /*
2a6d42e7dSPeter Dunlap * CDDL HEADER START
3a6d42e7dSPeter Dunlap *
4a6d42e7dSPeter Dunlap * The contents of this file are subject to the terms of the
5a6d42e7dSPeter Dunlap * Common Development and Distribution License (the "License").
6a6d42e7dSPeter Dunlap * You may not use this file except in compliance with the License.
7a6d42e7dSPeter Dunlap *
8a6d42e7dSPeter Dunlap * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a6d42e7dSPeter Dunlap * or http://www.opensolaris.org/os/licensing.
10a6d42e7dSPeter Dunlap * See the License for the specific language governing permissions
11a6d42e7dSPeter Dunlap * and limitations under the License.
12a6d42e7dSPeter Dunlap *
13a6d42e7dSPeter Dunlap * When distributing Covered Code, include this CDDL HEADER in each
14a6d42e7dSPeter Dunlap * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a6d42e7dSPeter Dunlap * If applicable, add the following below this CDDL HEADER, with the
16a6d42e7dSPeter Dunlap * fields enclosed by brackets "[]" replaced with your own identifying
17a6d42e7dSPeter Dunlap * information: Portions Copyright [yyyy] [name of copyright owner]
18a6d42e7dSPeter Dunlap *
19a6d42e7dSPeter Dunlap * CDDL HEADER END
20a6d42e7dSPeter Dunlap */
21*59927d31SYuri Pankov
22a6d42e7dSPeter Dunlap /*
2342bf653bSPeter Gill * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24*59927d31SYuri Pankov * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25a6d42e7dSPeter Dunlap */
26a6d42e7dSPeter Dunlap
27a6d42e7dSPeter Dunlap #include <sys/time.h>
28a6d42e7dSPeter Dunlap
29a6d42e7dSPeter Dunlap #if defined(_KERNEL)
30a6d42e7dSPeter Dunlap #include <sys/ddi.h>
31a6d42e7dSPeter Dunlap #include <sys/types.h>
32a6d42e7dSPeter Dunlap #include <sys/sunddi.h>
33a6d42e7dSPeter Dunlap #include <sys/socket.h>
34*59927d31SYuri Pankov #include <inet/ip.h>
35a6d42e7dSPeter Dunlap #include <inet/tcp.h>
36a6d42e7dSPeter Dunlap #else
37a6d42e7dSPeter Dunlap #include <stdio.h>
38a6d42e7dSPeter Dunlap #include <strings.h>
39a6d42e7dSPeter Dunlap #include <stdlib.h>
40a6d42e7dSPeter Dunlap #include <errno.h>
41a6d42e7dSPeter Dunlap #include <sys/types.h>
42a6d42e7dSPeter Dunlap #include <sys/socket.h>
43a6d42e7dSPeter Dunlap #include <netinet/in.h>
44a6d42e7dSPeter Dunlap #include <arpa/inet.h>
45a6d42e7dSPeter Dunlap #endif
46a6d42e7dSPeter Dunlap
47a6d42e7dSPeter Dunlap #include <sys/iscsit/iscsit_common.h>
48a6d42e7dSPeter Dunlap #include <sys/iscsi_protocol.h>
49a6d42e7dSPeter Dunlap #include <sys/iscsit/isns_protocol.h>
50a6d42e7dSPeter Dunlap
51a6d42e7dSPeter Dunlap void *
iscsit_zalloc(size_t size)52a6d42e7dSPeter Dunlap iscsit_zalloc(size_t size)
53a6d42e7dSPeter Dunlap {
54a6d42e7dSPeter Dunlap #if defined(_KERNEL)
55a6d42e7dSPeter Dunlap return (kmem_zalloc(size, KM_SLEEP));
56a6d42e7dSPeter Dunlap #else
57a6d42e7dSPeter Dunlap return (calloc(1, size));
58a6d42e7dSPeter Dunlap #endif
59a6d42e7dSPeter Dunlap }
60a6d42e7dSPeter Dunlap
61a6d42e7dSPeter Dunlap void
iscsit_free(void * buf,size_t size)62a6d42e7dSPeter Dunlap iscsit_free(void *buf, size_t size) /* ARGSUSED */
63a6d42e7dSPeter Dunlap {
64a6d42e7dSPeter Dunlap #if defined(_KERNEL)
65a6d42e7dSPeter Dunlap kmem_free(buf, size);
66a6d42e7dSPeter Dunlap #else
67a6d42e7dSPeter Dunlap free(buf);
68a6d42e7dSPeter Dunlap #endif
69a6d42e7dSPeter Dunlap }
70a6d42e7dSPeter Dunlap
71a6d42e7dSPeter Dunlap /*
72a6d42e7dSPeter Dunlap * default_port should be the port to be used, if not specified
73a6d42e7dSPeter Dunlap * as part of the supplied string 'arg'.
74a6d42e7dSPeter Dunlap */
75a6d42e7dSPeter Dunlap
76a6d42e7dSPeter Dunlap #define NI_MAXHOST 1025
77a6d42e7dSPeter Dunlap #define NI_MAXSERV 32
78a6d42e7dSPeter Dunlap
79a6d42e7dSPeter Dunlap
80a6d42e7dSPeter Dunlap struct sockaddr_storage *
it_common_convert_sa(char * arg,struct sockaddr_storage * buf,uint32_t default_port)81a6d42e7dSPeter Dunlap it_common_convert_sa(char *arg, struct sockaddr_storage *buf,
82a6d42e7dSPeter Dunlap uint32_t default_port)
83a6d42e7dSPeter Dunlap {
84a6d42e7dSPeter Dunlap /* Why does addrbuf need to be this big!??! XXX */
85a6d42e7dSPeter Dunlap char addrbuf[NI_MAXHOST + NI_MAXSERV + 1];
86a6d42e7dSPeter Dunlap char *addr_str;
87a6d42e7dSPeter Dunlap char *port_str;
88a6d42e7dSPeter Dunlap #ifndef _KERNEL
89a6d42e7dSPeter Dunlap char *errchr;
90a6d42e7dSPeter Dunlap #endif
91a6d42e7dSPeter Dunlap long tmp_port = 0;
92a6d42e7dSPeter Dunlap sa_family_t af;
93a6d42e7dSPeter Dunlap
94a6d42e7dSPeter Dunlap struct sockaddr_in *sin;
95a6d42e7dSPeter Dunlap struct sockaddr_in6 *sin6;
96a6d42e7dSPeter Dunlap struct sockaddr_storage *sa = buf;
97a6d42e7dSPeter Dunlap
98a6d42e7dSPeter Dunlap if (!arg || !buf) {
99a6d42e7dSPeter Dunlap return (NULL);
100a6d42e7dSPeter Dunlap }
101a6d42e7dSPeter Dunlap
102a6d42e7dSPeter Dunlap bzero(buf, sizeof (struct sockaddr_storage));
103a6d42e7dSPeter Dunlap
104a6d42e7dSPeter Dunlap /* don't modify the passed-in string */
105a6d42e7dSPeter Dunlap (void) strlcpy(addrbuf, arg, sizeof (addrbuf));
106a6d42e7dSPeter Dunlap
107a6d42e7dSPeter Dunlap addr_str = addrbuf;
108a6d42e7dSPeter Dunlap
109a6d42e7dSPeter Dunlap if (*addr_str == '[') {
110a6d42e7dSPeter Dunlap /*
111a6d42e7dSPeter Dunlap * An IPv6 address must be inside square brackets
112a6d42e7dSPeter Dunlap */
113a6d42e7dSPeter Dunlap port_str = strchr(addr_str, ']');
114a6d42e7dSPeter Dunlap if (!port_str) {
115a6d42e7dSPeter Dunlap /* No closing bracket */
116a6d42e7dSPeter Dunlap return (NULL);
117a6d42e7dSPeter Dunlap }
118a6d42e7dSPeter Dunlap
119a6d42e7dSPeter Dunlap /* strip off the square brackets so we can convert */
120a6d42e7dSPeter Dunlap addr_str++;
121a6d42e7dSPeter Dunlap *port_str = '\0';
122a6d42e7dSPeter Dunlap port_str++;
123a6d42e7dSPeter Dunlap
124a6d42e7dSPeter Dunlap if (*port_str == ':') {
125a6d42e7dSPeter Dunlap /* TCP port to follow */
126a6d42e7dSPeter Dunlap port_str++;
127a6d42e7dSPeter Dunlap } else if (*port_str == '\0') {
128a6d42e7dSPeter Dunlap /* No port specified */
129a6d42e7dSPeter Dunlap port_str = NULL;
130a6d42e7dSPeter Dunlap } else {
131a6d42e7dSPeter Dunlap /* malformed */
132a6d42e7dSPeter Dunlap return (NULL);
133a6d42e7dSPeter Dunlap }
134a6d42e7dSPeter Dunlap af = AF_INET6;
135a6d42e7dSPeter Dunlap } else {
136a6d42e7dSPeter Dunlap port_str = strchr(addr_str, ':');
137a6d42e7dSPeter Dunlap if (port_str) {
138a6d42e7dSPeter Dunlap *port_str = '\0';
139a6d42e7dSPeter Dunlap port_str++;
140a6d42e7dSPeter Dunlap }
141a6d42e7dSPeter Dunlap af = AF_INET;
142a6d42e7dSPeter Dunlap }
143a6d42e7dSPeter Dunlap
144a6d42e7dSPeter Dunlap if (port_str) {
145a6d42e7dSPeter Dunlap #if defined(_KERNEL)
146a6d42e7dSPeter Dunlap if (ddi_strtol(port_str, NULL, 10, &tmp_port) != 0) {
147a6d42e7dSPeter Dunlap return (NULL);
148a6d42e7dSPeter Dunlap }
149a6d42e7dSPeter Dunlap #else
150a6d42e7dSPeter Dunlap tmp_port = strtol(port_str, &errchr, 10);
151a6d42e7dSPeter Dunlap #endif
152a6d42e7dSPeter Dunlap if (tmp_port < 0 || tmp_port > 65535) {
153a6d42e7dSPeter Dunlap return (NULL);
154a6d42e7dSPeter Dunlap }
155a6d42e7dSPeter Dunlap } else {
156a6d42e7dSPeter Dunlap tmp_port = default_port;
157a6d42e7dSPeter Dunlap }
158a6d42e7dSPeter Dunlap
159a6d42e7dSPeter Dunlap sa->ss_family = af;
160a6d42e7dSPeter Dunlap
161a6d42e7dSPeter Dunlap sin = (struct sockaddr_in *)sa;
162a6d42e7dSPeter Dunlap if (af == AF_INET) {
163a6d42e7dSPeter Dunlap if (inet_pton(af, addr_str,
164a6d42e7dSPeter Dunlap (void *)&(sin->sin_addr.s_addr)) != 1) {
165a6d42e7dSPeter Dunlap return (NULL);
166a6d42e7dSPeter Dunlap }
167a6d42e7dSPeter Dunlap sin->sin_port = htons(tmp_port);
168a6d42e7dSPeter Dunlap } else {
169a6d42e7dSPeter Dunlap sin6 = (struct sockaddr_in6 *)sa;
170a6d42e7dSPeter Dunlap if (inet_pton(af, addr_str,
171a6d42e7dSPeter Dunlap (void *)&(sin6->sin6_addr.s6_addr)) != 1) {
172a6d42e7dSPeter Dunlap return (NULL);
173a6d42e7dSPeter Dunlap }
174a6d42e7dSPeter Dunlap sin6->sin6_port = htons(tmp_port);
175a6d42e7dSPeter Dunlap }
176a6d42e7dSPeter Dunlap
177a6d42e7dSPeter Dunlap /* successful */
178a6d42e7dSPeter Dunlap return (sa);
179a6d42e7dSPeter Dunlap }
180a6d42e7dSPeter Dunlap
181a6d42e7dSPeter Dunlap
182a6d42e7dSPeter Dunlap /* Functions to convert iSCSI target structures to/from nvlists. */
183a6d42e7dSPeter Dunlap
184a6d42e7dSPeter Dunlap #ifndef _KERNEL
185a6d42e7dSPeter Dunlap int
it_config_to_nv(it_config_t * cfg,nvlist_t ** nvl)186a6d42e7dSPeter Dunlap it_config_to_nv(it_config_t *cfg, nvlist_t **nvl)
187a6d42e7dSPeter Dunlap {
188a6d42e7dSPeter Dunlap int ret;
189a6d42e7dSPeter Dunlap nvlist_t *nv;
190a6d42e7dSPeter Dunlap nvlist_t *lnv = NULL;
191a6d42e7dSPeter Dunlap
192a6d42e7dSPeter Dunlap if (!nvl) {
193a6d42e7dSPeter Dunlap return (EINVAL);
194a6d42e7dSPeter Dunlap }
195a6d42e7dSPeter Dunlap
196a6d42e7dSPeter Dunlap *nvl = NULL;
197a6d42e7dSPeter Dunlap
198a6d42e7dSPeter Dunlap ret = nvlist_alloc(&nv, NV_UNIQUE_NAME_TYPE, 0);
199a6d42e7dSPeter Dunlap if (ret != 0) {
200a6d42e7dSPeter Dunlap return (ret);
201a6d42e7dSPeter Dunlap }
202a6d42e7dSPeter Dunlap
203a6d42e7dSPeter Dunlap /* if there's no config, store an empty list */
204a6d42e7dSPeter Dunlap if (!cfg) {
205a6d42e7dSPeter Dunlap *nvl = nv;
206a6d42e7dSPeter Dunlap return (0);
207a6d42e7dSPeter Dunlap }
208a6d42e7dSPeter Dunlap
209a6d42e7dSPeter Dunlap ret = nvlist_add_uint32(nv, "cfgVersion", cfg->config_version);
210a6d42e7dSPeter Dunlap if (ret == 0) {
211a6d42e7dSPeter Dunlap ret = it_tgtlist_to_nv(cfg->config_tgt_list, &lnv);
212a6d42e7dSPeter Dunlap }
213a6d42e7dSPeter Dunlap
214a6d42e7dSPeter Dunlap if ((ret == 0) && (lnv != NULL)) {
215a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(nv, "targetList", lnv);
216a6d42e7dSPeter Dunlap nvlist_free(lnv);
217a6d42e7dSPeter Dunlap lnv = NULL;
218a6d42e7dSPeter Dunlap }
219a6d42e7dSPeter Dunlap
220a6d42e7dSPeter Dunlap if (ret == 0) {
221a6d42e7dSPeter Dunlap ret = it_tpglist_to_nv(cfg->config_tpg_list, &lnv);
222a6d42e7dSPeter Dunlap }
223a6d42e7dSPeter Dunlap
224a6d42e7dSPeter Dunlap if ((ret == 0) && (lnv != NULL)) {
225a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(nv, "tpgList", lnv);
226a6d42e7dSPeter Dunlap nvlist_free(lnv);
227a6d42e7dSPeter Dunlap lnv = NULL;
228a6d42e7dSPeter Dunlap }
229a6d42e7dSPeter Dunlap
230a6d42e7dSPeter Dunlap if (ret == 0) {
231a6d42e7dSPeter Dunlap ret = it_inilist_to_nv(cfg->config_ini_list, &lnv);
232a6d42e7dSPeter Dunlap }
233a6d42e7dSPeter Dunlap
234a6d42e7dSPeter Dunlap if ((ret == 0) && (lnv != NULL)) {
235a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(nv, "iniList", lnv);
236a6d42e7dSPeter Dunlap nvlist_free(lnv);
237a6d42e7dSPeter Dunlap lnv = NULL;
238a6d42e7dSPeter Dunlap }
239a6d42e7dSPeter Dunlap
240a6d42e7dSPeter Dunlap if (ret == 0) {
241a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(nv, "globalProperties",
242a6d42e7dSPeter Dunlap cfg->config_global_properties);
243a6d42e7dSPeter Dunlap }
244a6d42e7dSPeter Dunlap
245a6d42e7dSPeter Dunlap if (ret == 0) {
246a6d42e7dSPeter Dunlap *nvl = nv;
247a6d42e7dSPeter Dunlap } else {
248a6d42e7dSPeter Dunlap nvlist_free(nv);
249a6d42e7dSPeter Dunlap }
250a6d42e7dSPeter Dunlap
251a6d42e7dSPeter Dunlap return (ret);
252a6d42e7dSPeter Dunlap }
253a6d42e7dSPeter Dunlap #endif /* !_KERNEL */
254a6d42e7dSPeter Dunlap
255a6d42e7dSPeter Dunlap /*
256a6d42e7dSPeter Dunlap * nvlist version of config is 3 list-of-list, + 1 proplist. arrays
257a6d42e7dSPeter Dunlap * are interesting, but lists-of-lists are more useful when doing
258a6d42e7dSPeter Dunlap * individual lookups when we later add support for it. Also, no
259a6d42e7dSPeter Dunlap * need to store name in individual struct representation.
260a6d42e7dSPeter Dunlap */
261a6d42e7dSPeter Dunlap int
it_nv_to_config(nvlist_t * nvl,it_config_t ** cfg)262a6d42e7dSPeter Dunlap it_nv_to_config(nvlist_t *nvl, it_config_t **cfg)
263a6d42e7dSPeter Dunlap {
264a6d42e7dSPeter Dunlap int ret;
265a6d42e7dSPeter Dunlap uint32_t intval;
266a6d42e7dSPeter Dunlap nvlist_t *listval;
267a6d42e7dSPeter Dunlap it_config_t *tmpcfg;
268a6d42e7dSPeter Dunlap
269a6d42e7dSPeter Dunlap if (!cfg) {
270a6d42e7dSPeter Dunlap return (EINVAL);
271a6d42e7dSPeter Dunlap }
272a6d42e7dSPeter Dunlap
273a6d42e7dSPeter Dunlap /* initialize output */
274a6d42e7dSPeter Dunlap *cfg = NULL;
275a6d42e7dSPeter Dunlap
276a6d42e7dSPeter Dunlap tmpcfg = iscsit_zalloc(sizeof (it_config_t));
277a6d42e7dSPeter Dunlap if (tmpcfg == NULL) {
278a6d42e7dSPeter Dunlap return (ENOMEM);
279a6d42e7dSPeter Dunlap }
280a6d42e7dSPeter Dunlap
281a6d42e7dSPeter Dunlap if (!nvl) {
282a6d42e7dSPeter Dunlap /* nothing to decode, but return the empty cfg struct */
283a6d42e7dSPeter Dunlap ret = nvlist_alloc(&tmpcfg->config_global_properties,
284a6d42e7dSPeter Dunlap NV_UNIQUE_NAME, 0);
285a6d42e7dSPeter Dunlap if (ret != 0) {
286a6d42e7dSPeter Dunlap iscsit_free(tmpcfg, sizeof (it_config_t));
287a6d42e7dSPeter Dunlap return (ret);
288a6d42e7dSPeter Dunlap }
289a6d42e7dSPeter Dunlap *cfg = tmpcfg;
290a6d42e7dSPeter Dunlap return (0);
291a6d42e7dSPeter Dunlap }
292a6d42e7dSPeter Dunlap
293a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint32(nvl, "cfgVersion", &intval);
294a6d42e7dSPeter Dunlap if (ret != 0) {
295a6d42e7dSPeter Dunlap iscsit_free(tmpcfg, sizeof (it_config_t));
296a6d42e7dSPeter Dunlap return (ret);
297a6d42e7dSPeter Dunlap }
298a6d42e7dSPeter Dunlap
299a6d42e7dSPeter Dunlap tmpcfg->config_version = intval;
300a6d42e7dSPeter Dunlap
301a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "targetList", &listval);
302a6d42e7dSPeter Dunlap if (ret == 0) {
303a6d42e7dSPeter Dunlap /* decode list of it_tgt_t */
304a6d42e7dSPeter Dunlap ret = it_nv_to_tgtlist(listval, &(tmpcfg->config_tgt_count),
305a6d42e7dSPeter Dunlap &(tmpcfg->config_tgt_list));
306a6d42e7dSPeter Dunlap }
307a6d42e7dSPeter Dunlap
308a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "tpgList", &listval);
309a6d42e7dSPeter Dunlap if (ret == 0) {
310a6d42e7dSPeter Dunlap /* decode list of it_tpg_t */
311a6d42e7dSPeter Dunlap ret = it_nv_to_tpglist(listval, &(tmpcfg->config_tpg_count),
312a6d42e7dSPeter Dunlap &(tmpcfg->config_tpg_list));
313a6d42e7dSPeter Dunlap }
314a6d42e7dSPeter Dunlap
315a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "iniList", &listval);
316a6d42e7dSPeter Dunlap if (ret == 0) {
317a6d42e7dSPeter Dunlap /* decode list of initiators */
318a6d42e7dSPeter Dunlap ret = it_nv_to_inilist(listval, &(tmpcfg->config_ini_count),
319a6d42e7dSPeter Dunlap &(tmpcfg->config_ini_list));
320a6d42e7dSPeter Dunlap }
321a6d42e7dSPeter Dunlap
322a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "globalProperties", &listval);
323a6d42e7dSPeter Dunlap if (ret == 0) {
324a6d42e7dSPeter Dunlap /*
325a6d42e7dSPeter Dunlap * don't depend on the original nvlist staying in-scope,
326a6d42e7dSPeter Dunlap * duplicate the nvlist
327a6d42e7dSPeter Dunlap */
328a6d42e7dSPeter Dunlap ret = nvlist_dup(listval, &(tmpcfg->config_global_properties),
329a6d42e7dSPeter Dunlap 0);
330a6d42e7dSPeter Dunlap } else if (ret == ENOENT) {
331a6d42e7dSPeter Dunlap /*
332a6d42e7dSPeter Dunlap * No global properties defined, make an empty list
333a6d42e7dSPeter Dunlap */
334a6d42e7dSPeter Dunlap ret = nvlist_alloc(&tmpcfg->config_global_properties,
335a6d42e7dSPeter Dunlap NV_UNIQUE_NAME, 0);
336a6d42e7dSPeter Dunlap }
337a6d42e7dSPeter Dunlap
338a6d42e7dSPeter Dunlap if (ret == 0) {
339a6d42e7dSPeter Dunlap char **isnsArray = NULL;
340a6d42e7dSPeter Dunlap uint32_t numisns = 0;
341a6d42e7dSPeter Dunlap
342a6d42e7dSPeter Dunlap /*
343a6d42e7dSPeter Dunlap * decode the list of iSNS server information to make
344a6d42e7dSPeter Dunlap * references from the kernel simpler.
345a6d42e7dSPeter Dunlap */
346a6d42e7dSPeter Dunlap if (tmpcfg->config_global_properties) {
347a6d42e7dSPeter Dunlap ret = nvlist_lookup_string_array(
348a6d42e7dSPeter Dunlap tmpcfg->config_global_properties,
349a6d42e7dSPeter Dunlap PROP_ISNS_SERVER,
350a6d42e7dSPeter Dunlap &isnsArray, &numisns);
351a6d42e7dSPeter Dunlap if (ret == 0) {
352a6d42e7dSPeter Dunlap ret = it_array_to_portallist(isnsArray,
353a6d42e7dSPeter Dunlap numisns, ISNS_DEFAULT_SERVER_PORT,
354a6d42e7dSPeter Dunlap &tmpcfg->config_isns_svr_list,
355a6d42e7dSPeter Dunlap &tmpcfg->config_isns_svr_count);
356a6d42e7dSPeter Dunlap } else if (ret == ENOENT) {
357a6d42e7dSPeter Dunlap /* It's OK if we don't have any iSNS servers */
358a6d42e7dSPeter Dunlap ret = 0;
359a6d42e7dSPeter Dunlap }
360a6d42e7dSPeter Dunlap }
361a6d42e7dSPeter Dunlap }
362a6d42e7dSPeter Dunlap
363a6d42e7dSPeter Dunlap if (ret == 0) {
364a6d42e7dSPeter Dunlap *cfg = tmpcfg;
365a6d42e7dSPeter Dunlap } else {
366a6d42e7dSPeter Dunlap it_config_free_cmn(tmpcfg);
367a6d42e7dSPeter Dunlap }
368a6d42e7dSPeter Dunlap
369a6d42e7dSPeter Dunlap return (ret);
370a6d42e7dSPeter Dunlap }
371a6d42e7dSPeter Dunlap
372a6d42e7dSPeter Dunlap it_tgt_t *
it_tgt_lookup(it_config_t * cfg,char * tgt_name)373a6d42e7dSPeter Dunlap it_tgt_lookup(it_config_t *cfg, char *tgt_name)
374a6d42e7dSPeter Dunlap {
375a6d42e7dSPeter Dunlap it_tgt_t *cfg_tgt = NULL;
376a6d42e7dSPeter Dunlap
377a6d42e7dSPeter Dunlap for (cfg_tgt = cfg->config_tgt_list;
378a6d42e7dSPeter Dunlap cfg_tgt != NULL;
379a6d42e7dSPeter Dunlap cfg_tgt = cfg_tgt->tgt_next) {
380a6d42e7dSPeter Dunlap if (strncmp(cfg_tgt->tgt_name, tgt_name,
381a6d42e7dSPeter Dunlap MAX_ISCSI_NODENAMELEN) == 0) {
382a6d42e7dSPeter Dunlap return (cfg_tgt);
383a6d42e7dSPeter Dunlap }
384a6d42e7dSPeter Dunlap }
385a6d42e7dSPeter Dunlap
386a6d42e7dSPeter Dunlap return (NULL);
387a6d42e7dSPeter Dunlap }
388a6d42e7dSPeter Dunlap
389a6d42e7dSPeter Dunlap int
it_nv_to_tgtlist(nvlist_t * nvl,uint32_t * count,it_tgt_t ** tgtlist)390a6d42e7dSPeter Dunlap it_nv_to_tgtlist(nvlist_t *nvl, uint32_t *count, it_tgt_t **tgtlist)
391a6d42e7dSPeter Dunlap {
392a6d42e7dSPeter Dunlap int ret = 0;
393a6d42e7dSPeter Dunlap it_tgt_t *tgt;
394a6d42e7dSPeter Dunlap it_tgt_t *prev = NULL;
395a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL;
396a6d42e7dSPeter Dunlap nvlist_t *nvt;
397a6d42e7dSPeter Dunlap char *name;
398a6d42e7dSPeter Dunlap
399a6d42e7dSPeter Dunlap if (!tgtlist || !count) {
400a6d42e7dSPeter Dunlap return (EINVAL);
401a6d42e7dSPeter Dunlap }
402a6d42e7dSPeter Dunlap
403a6d42e7dSPeter Dunlap *tgtlist = NULL;
404a6d42e7dSPeter Dunlap *count = 0;
405a6d42e7dSPeter Dunlap
406a6d42e7dSPeter Dunlap if (!nvl) {
407a6d42e7dSPeter Dunlap /* nothing to do */
408a6d42e7dSPeter Dunlap return (0);
409a6d42e7dSPeter Dunlap }
410a6d42e7dSPeter Dunlap
411a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
412a6d42e7dSPeter Dunlap name = nvpair_name(nvp);
413a6d42e7dSPeter Dunlap
414a6d42e7dSPeter Dunlap ret = nvpair_value_nvlist(nvp, &nvt);
415a6d42e7dSPeter Dunlap if (ret != 0) {
416a6d42e7dSPeter Dunlap /* invalid entry? */
417a6d42e7dSPeter Dunlap continue;
418a6d42e7dSPeter Dunlap }
419a6d42e7dSPeter Dunlap
420a6d42e7dSPeter Dunlap ret = it_nv_to_tgt(nvt, name, &tgt);
421a6d42e7dSPeter Dunlap if (ret != 0) {
422a6d42e7dSPeter Dunlap break;
423a6d42e7dSPeter Dunlap }
424a6d42e7dSPeter Dunlap
425a6d42e7dSPeter Dunlap (*count)++;
426a6d42e7dSPeter Dunlap
427a6d42e7dSPeter Dunlap if (*tgtlist == NULL) {
428a6d42e7dSPeter Dunlap *tgtlist = tgt;
429a6d42e7dSPeter Dunlap } else {
430a6d42e7dSPeter Dunlap prev->tgt_next = tgt;
431a6d42e7dSPeter Dunlap }
432a6d42e7dSPeter Dunlap prev = tgt;
433a6d42e7dSPeter Dunlap }
434a6d42e7dSPeter Dunlap
435a6d42e7dSPeter Dunlap if (ret != 0) {
436a6d42e7dSPeter Dunlap it_tgt_free_cmn(*tgtlist);
437a6d42e7dSPeter Dunlap *tgtlist = NULL;
438a6d42e7dSPeter Dunlap }
439a6d42e7dSPeter Dunlap
440a6d42e7dSPeter Dunlap return (ret);
441a6d42e7dSPeter Dunlap }
442a6d42e7dSPeter Dunlap
443a6d42e7dSPeter Dunlap int
it_tgtlist_to_nv(it_tgt_t * tgtlist,nvlist_t ** nvl)444a6d42e7dSPeter Dunlap it_tgtlist_to_nv(it_tgt_t *tgtlist, nvlist_t **nvl)
445a6d42e7dSPeter Dunlap {
446a6d42e7dSPeter Dunlap int ret;
447a6d42e7dSPeter Dunlap it_tgt_t *tgtp = tgtlist;
448a6d42e7dSPeter Dunlap nvlist_t *pnv = NULL;
449a6d42e7dSPeter Dunlap nvlist_t *tnv;
450a6d42e7dSPeter Dunlap
451a6d42e7dSPeter Dunlap if (!nvl) {
452a6d42e7dSPeter Dunlap return (EINVAL);
453a6d42e7dSPeter Dunlap }
454a6d42e7dSPeter Dunlap
455a6d42e7dSPeter Dunlap if (!tgtlist) {
456a6d42e7dSPeter Dunlap /* nothing to do */
457a6d42e7dSPeter Dunlap return (0);
458a6d42e7dSPeter Dunlap }
459a6d42e7dSPeter Dunlap
460a6d42e7dSPeter Dunlap /* create the target list if required */
461a6d42e7dSPeter Dunlap if (*nvl == NULL) {
462a6d42e7dSPeter Dunlap ret = nvlist_alloc(&pnv, NV_UNIQUE_NAME, 0);
463a6d42e7dSPeter Dunlap if (ret != 0) {
464a6d42e7dSPeter Dunlap return (ret);
465a6d42e7dSPeter Dunlap }
466a6d42e7dSPeter Dunlap *nvl = pnv;
467a6d42e7dSPeter Dunlap }
468a6d42e7dSPeter Dunlap
469a6d42e7dSPeter Dunlap while (tgtp) {
470a6d42e7dSPeter Dunlap ret = it_tgt_to_nv(tgtp, &tnv);
471a6d42e7dSPeter Dunlap
472a6d42e7dSPeter Dunlap if (ret != 0) {
473a6d42e7dSPeter Dunlap break;
474a6d42e7dSPeter Dunlap }
475a6d42e7dSPeter Dunlap
476a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, tgtp->tgt_name, tnv);
477a6d42e7dSPeter Dunlap
478a6d42e7dSPeter Dunlap if (ret != 0) {
479a6d42e7dSPeter Dunlap break;
480a6d42e7dSPeter Dunlap }
481a6d42e7dSPeter Dunlap
482a6d42e7dSPeter Dunlap nvlist_free(tnv);
483a6d42e7dSPeter Dunlap
484a6d42e7dSPeter Dunlap tgtp = tgtp->tgt_next;
485a6d42e7dSPeter Dunlap }
486a6d42e7dSPeter Dunlap
487a6d42e7dSPeter Dunlap if (ret != 0) {
488a6d42e7dSPeter Dunlap if (pnv) {
489a6d42e7dSPeter Dunlap nvlist_free(pnv);
490a6d42e7dSPeter Dunlap *nvl = NULL;
491a6d42e7dSPeter Dunlap }
492a6d42e7dSPeter Dunlap }
493a6d42e7dSPeter Dunlap
494a6d42e7dSPeter Dunlap return (ret);
495a6d42e7dSPeter Dunlap }
496a6d42e7dSPeter Dunlap
497a6d42e7dSPeter Dunlap int
it_tgt_to_nv(it_tgt_t * tgt,nvlist_t ** nvl)498a6d42e7dSPeter Dunlap it_tgt_to_nv(it_tgt_t *tgt, nvlist_t **nvl)
499a6d42e7dSPeter Dunlap {
500a6d42e7dSPeter Dunlap int ret;
501a6d42e7dSPeter Dunlap nvlist_t *tnv = NULL;
502a6d42e7dSPeter Dunlap
503a6d42e7dSPeter Dunlap if (!nvl) {
504a6d42e7dSPeter Dunlap return (EINVAL);
505a6d42e7dSPeter Dunlap }
506a6d42e7dSPeter Dunlap
507a6d42e7dSPeter Dunlap if (!tgt) {
508a6d42e7dSPeter Dunlap /* nothing to do */
509a6d42e7dSPeter Dunlap return (0);
510a6d42e7dSPeter Dunlap }
511a6d42e7dSPeter Dunlap
512a6d42e7dSPeter Dunlap ret = nvlist_alloc(nvl, NV_UNIQUE_NAME, 0);
513a6d42e7dSPeter Dunlap if (ret != 0) {
514a6d42e7dSPeter Dunlap return (ret);
515a6d42e7dSPeter Dunlap }
516a6d42e7dSPeter Dunlap
517a6d42e7dSPeter Dunlap if (tgt->tgt_properties) {
518a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, "properties",
519a6d42e7dSPeter Dunlap tgt->tgt_properties);
520a6d42e7dSPeter Dunlap }
521a6d42e7dSPeter Dunlap
522a6d42e7dSPeter Dunlap if (ret == 0) {
523a6d42e7dSPeter Dunlap ret = nvlist_add_uint64(*nvl, "generation",
524a6d42e7dSPeter Dunlap tgt->tgt_generation);
525a6d42e7dSPeter Dunlap }
526a6d42e7dSPeter Dunlap
527a6d42e7dSPeter Dunlap if (ret == 0) {
528a6d42e7dSPeter Dunlap ret = it_tpgtlist_to_nv(tgt->tgt_tpgt_list, &tnv);
529a6d42e7dSPeter Dunlap }
530a6d42e7dSPeter Dunlap
531a6d42e7dSPeter Dunlap if ((ret == 0) && tnv) {
532a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, "tpgtList", tnv);
533a6d42e7dSPeter Dunlap nvlist_free(tnv);
534a6d42e7dSPeter Dunlap }
535a6d42e7dSPeter Dunlap
536a6d42e7dSPeter Dunlap if (ret != 0) {
537a6d42e7dSPeter Dunlap nvlist_free(*nvl);
538a6d42e7dSPeter Dunlap *nvl = NULL;
539a6d42e7dSPeter Dunlap }
540a6d42e7dSPeter Dunlap
541a6d42e7dSPeter Dunlap return (ret);
542a6d42e7dSPeter Dunlap }
543a6d42e7dSPeter Dunlap
544a6d42e7dSPeter Dunlap int
it_nv_to_tgt(nvlist_t * nvl,char * name,it_tgt_t ** tgt)545a6d42e7dSPeter Dunlap it_nv_to_tgt(nvlist_t *nvl, char *name, it_tgt_t **tgt)
546a6d42e7dSPeter Dunlap {
547a6d42e7dSPeter Dunlap int ret;
548a6d42e7dSPeter Dunlap it_tgt_t *ttgt;
549a6d42e7dSPeter Dunlap nvlist_t *listval;
550a6d42e7dSPeter Dunlap uint32_t intval;
551a6d42e7dSPeter Dunlap
552a6d42e7dSPeter Dunlap if (!nvl || !tgt || !name) {
553a6d42e7dSPeter Dunlap return (EINVAL);
554a6d42e7dSPeter Dunlap }
555a6d42e7dSPeter Dunlap
556a6d42e7dSPeter Dunlap *tgt = NULL;
557a6d42e7dSPeter Dunlap
558a6d42e7dSPeter Dunlap ttgt = iscsit_zalloc(sizeof (it_tgt_t));
559a6d42e7dSPeter Dunlap if (!ttgt) {
560a6d42e7dSPeter Dunlap return (ENOMEM);
561a6d42e7dSPeter Dunlap }
562a6d42e7dSPeter Dunlap
563a6d42e7dSPeter Dunlap (void) strlcpy(ttgt->tgt_name, name, sizeof (ttgt->tgt_name));
564a6d42e7dSPeter Dunlap
565a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "properties", &listval);
566a6d42e7dSPeter Dunlap if (ret == 0) {
567a6d42e7dSPeter Dunlap /* duplicate list so it does not go out of context */
568a6d42e7dSPeter Dunlap ret = nvlist_dup(listval, &(ttgt->tgt_properties), 0);
569a6d42e7dSPeter Dunlap } else if (ret == ENOENT) {
570a6d42e7dSPeter Dunlap ret = 0;
571a6d42e7dSPeter Dunlap }
572a6d42e7dSPeter Dunlap
573a6d42e7dSPeter Dunlap if (ret == 0) {
574a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint64(nvl, "generation",
575a6d42e7dSPeter Dunlap &(ttgt->tgt_generation));
576a6d42e7dSPeter Dunlap } else if (ret == ENOENT) {
577a6d42e7dSPeter Dunlap ret = 0;
578a6d42e7dSPeter Dunlap }
579a6d42e7dSPeter Dunlap
580a6d42e7dSPeter Dunlap if (ret == 0) {
581a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "tpgtList", &listval);
582a6d42e7dSPeter Dunlap }
583a6d42e7dSPeter Dunlap
584a6d42e7dSPeter Dunlap if (ret == 0) {
585a6d42e7dSPeter Dunlap ret = it_nv_to_tpgtlist(listval, &intval,
586a6d42e7dSPeter Dunlap &(ttgt->tgt_tpgt_list));
587a6d42e7dSPeter Dunlap ttgt->tgt_tpgt_count = intval;
588a6d42e7dSPeter Dunlap } else if (ret == ENOENT) {
589a6d42e7dSPeter Dunlap ret = 0;
590a6d42e7dSPeter Dunlap }
591a6d42e7dSPeter Dunlap
592a6d42e7dSPeter Dunlap if (ret == 0) {
593a6d42e7dSPeter Dunlap *tgt = ttgt;
594a6d42e7dSPeter Dunlap } else {
595a6d42e7dSPeter Dunlap it_tgt_free_cmn(ttgt);
596a6d42e7dSPeter Dunlap }
597a6d42e7dSPeter Dunlap
598a6d42e7dSPeter Dunlap return (ret);
599a6d42e7dSPeter Dunlap }
600a6d42e7dSPeter Dunlap
601a6d42e7dSPeter Dunlap int
it_tpgt_to_nv(it_tpgt_t * tpgt,nvlist_t ** nvl)602a6d42e7dSPeter Dunlap it_tpgt_to_nv(it_tpgt_t *tpgt, nvlist_t **nvl)
603a6d42e7dSPeter Dunlap {
604a6d42e7dSPeter Dunlap int ret;
605a6d42e7dSPeter Dunlap
606a6d42e7dSPeter Dunlap if (!nvl) {
607a6d42e7dSPeter Dunlap return (EINVAL);
608a6d42e7dSPeter Dunlap }
609a6d42e7dSPeter Dunlap
610a6d42e7dSPeter Dunlap if (!tpgt) {
611a6d42e7dSPeter Dunlap /* nothing to do */
612a6d42e7dSPeter Dunlap return (0);
613a6d42e7dSPeter Dunlap }
614a6d42e7dSPeter Dunlap
615a6d42e7dSPeter Dunlap ret = nvlist_alloc(nvl, NV_UNIQUE_NAME, 0);
616a6d42e7dSPeter Dunlap if (ret != 0) {
617a6d42e7dSPeter Dunlap return (ret);
618a6d42e7dSPeter Dunlap }
619a6d42e7dSPeter Dunlap
620a6d42e7dSPeter Dunlap ret = nvlist_add_uint16(*nvl, "tag", tpgt->tpgt_tag);
621a6d42e7dSPeter Dunlap if (ret == 0) {
622a6d42e7dSPeter Dunlap ret = nvlist_add_uint64(*nvl, "generation",
623a6d42e7dSPeter Dunlap tpgt->tpgt_generation);
624a6d42e7dSPeter Dunlap }
625a6d42e7dSPeter Dunlap
626a6d42e7dSPeter Dunlap if (ret != 0) {
627a6d42e7dSPeter Dunlap nvlist_free(*nvl);
628a6d42e7dSPeter Dunlap *nvl = NULL;
629a6d42e7dSPeter Dunlap }
630a6d42e7dSPeter Dunlap
631a6d42e7dSPeter Dunlap return (ret);
632a6d42e7dSPeter Dunlap }
633a6d42e7dSPeter Dunlap
634a6d42e7dSPeter Dunlap int
it_nv_to_tpgt(nvlist_t * nvl,char * name,it_tpgt_t ** tpgt)635a6d42e7dSPeter Dunlap it_nv_to_tpgt(nvlist_t *nvl, char *name, it_tpgt_t **tpgt)
636a6d42e7dSPeter Dunlap {
637a6d42e7dSPeter Dunlap int ret;
638a6d42e7dSPeter Dunlap it_tpgt_t *ptr;
639a6d42e7dSPeter Dunlap
640a6d42e7dSPeter Dunlap if (!tpgt || !name) {
641a6d42e7dSPeter Dunlap return (EINVAL);
642a6d42e7dSPeter Dunlap }
643a6d42e7dSPeter Dunlap
644a6d42e7dSPeter Dunlap *tpgt = NULL;
645a6d42e7dSPeter Dunlap
646a6d42e7dSPeter Dunlap if (!nvl) {
647a6d42e7dSPeter Dunlap return (0);
648a6d42e7dSPeter Dunlap }
649a6d42e7dSPeter Dunlap
650a6d42e7dSPeter Dunlap ptr = iscsit_zalloc(sizeof (it_tpgt_t));
651a6d42e7dSPeter Dunlap if (!ptr) {
652a6d42e7dSPeter Dunlap return (ENOMEM);
653a6d42e7dSPeter Dunlap }
654a6d42e7dSPeter Dunlap
655a6d42e7dSPeter Dunlap (void) strlcpy(ptr->tpgt_tpg_name, name, sizeof (ptr->tpgt_tpg_name));
656a6d42e7dSPeter Dunlap
657a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint16(nvl, "tag", &(ptr->tpgt_tag));
658a6d42e7dSPeter Dunlap if (ret == 0) {
659a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint64(nvl, "generation",
660a6d42e7dSPeter Dunlap &(ptr->tpgt_generation));
661a6d42e7dSPeter Dunlap }
662a6d42e7dSPeter Dunlap
663a6d42e7dSPeter Dunlap if (ret == 0) {
664a6d42e7dSPeter Dunlap *tpgt = ptr;
665a6d42e7dSPeter Dunlap } else {
666a6d42e7dSPeter Dunlap iscsit_free(ptr, sizeof (it_tpgt_t));
667a6d42e7dSPeter Dunlap }
668a6d42e7dSPeter Dunlap
669a6d42e7dSPeter Dunlap return (ret);
670a6d42e7dSPeter Dunlap }
671a6d42e7dSPeter Dunlap
672a6d42e7dSPeter Dunlap int
it_tpgtlist_to_nv(it_tpgt_t * tpgtlist,nvlist_t ** nvl)673a6d42e7dSPeter Dunlap it_tpgtlist_to_nv(it_tpgt_t *tpgtlist, nvlist_t **nvl)
674a6d42e7dSPeter Dunlap {
675a6d42e7dSPeter Dunlap int ret;
676a6d42e7dSPeter Dunlap nvlist_t *pnv = NULL;
677a6d42e7dSPeter Dunlap nvlist_t *tnv;
678a6d42e7dSPeter Dunlap it_tpgt_t *ptr = tpgtlist;
679a6d42e7dSPeter Dunlap
680a6d42e7dSPeter Dunlap if (!nvl) {
681a6d42e7dSPeter Dunlap return (EINVAL);
682a6d42e7dSPeter Dunlap }
683a6d42e7dSPeter Dunlap
684a6d42e7dSPeter Dunlap if (!tpgtlist) {
685a6d42e7dSPeter Dunlap /* nothing to do */
686a6d42e7dSPeter Dunlap return (0);
687a6d42e7dSPeter Dunlap }
688a6d42e7dSPeter Dunlap
689a6d42e7dSPeter Dunlap /* create the target list if required */
690a6d42e7dSPeter Dunlap if (*nvl == NULL) {
691a6d42e7dSPeter Dunlap ret = nvlist_alloc(&pnv, NV_UNIQUE_NAME, 0);
692a6d42e7dSPeter Dunlap if (ret != 0) {
693a6d42e7dSPeter Dunlap return (ret);
694a6d42e7dSPeter Dunlap }
695a6d42e7dSPeter Dunlap *nvl = pnv;
696a6d42e7dSPeter Dunlap }
697a6d42e7dSPeter Dunlap
698a6d42e7dSPeter Dunlap while (ptr) {
699a6d42e7dSPeter Dunlap ret = it_tpgt_to_nv(ptr, &tnv);
700a6d42e7dSPeter Dunlap
701a6d42e7dSPeter Dunlap if (ret != 0) {
702a6d42e7dSPeter Dunlap break;
703a6d42e7dSPeter Dunlap }
704a6d42e7dSPeter Dunlap
705a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, ptr->tpgt_tpg_name, tnv);
706a6d42e7dSPeter Dunlap
707a6d42e7dSPeter Dunlap if (ret != 0) {
708a6d42e7dSPeter Dunlap break;
709a6d42e7dSPeter Dunlap }
710a6d42e7dSPeter Dunlap
711a6d42e7dSPeter Dunlap nvlist_free(tnv);
712a6d42e7dSPeter Dunlap
713a6d42e7dSPeter Dunlap ptr = ptr->tpgt_next;
714a6d42e7dSPeter Dunlap }
715a6d42e7dSPeter Dunlap
716a6d42e7dSPeter Dunlap if (ret != 0) {
717a6d42e7dSPeter Dunlap if (pnv) {
718a6d42e7dSPeter Dunlap nvlist_free(pnv);
719a6d42e7dSPeter Dunlap *nvl = NULL;
720a6d42e7dSPeter Dunlap }
721a6d42e7dSPeter Dunlap }
722a6d42e7dSPeter Dunlap
723a6d42e7dSPeter Dunlap return (ret);
724a6d42e7dSPeter Dunlap }
725a6d42e7dSPeter Dunlap
726a6d42e7dSPeter Dunlap int
it_nv_to_tpgtlist(nvlist_t * nvl,uint32_t * count,it_tpgt_t ** tpgtlist)727a6d42e7dSPeter Dunlap it_nv_to_tpgtlist(nvlist_t *nvl, uint32_t *count, it_tpgt_t **tpgtlist)
728a6d42e7dSPeter Dunlap {
729a6d42e7dSPeter Dunlap int ret = 0;
730a6d42e7dSPeter Dunlap it_tpgt_t *tpgt;
731a6d42e7dSPeter Dunlap it_tpgt_t *prev = NULL;
732a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL;
733a6d42e7dSPeter Dunlap nvlist_t *nvt;
734a6d42e7dSPeter Dunlap char *name;
735a6d42e7dSPeter Dunlap
736a6d42e7dSPeter Dunlap if (!tpgtlist || !count) {
737a6d42e7dSPeter Dunlap return (EINVAL);
738a6d42e7dSPeter Dunlap }
739a6d42e7dSPeter Dunlap
740a6d42e7dSPeter Dunlap *tpgtlist = NULL;
741a6d42e7dSPeter Dunlap *count = 0;
742a6d42e7dSPeter Dunlap
743a6d42e7dSPeter Dunlap if (!nvl) {
744a6d42e7dSPeter Dunlap /* nothing to do */
745a6d42e7dSPeter Dunlap return (0);
746a6d42e7dSPeter Dunlap }
747a6d42e7dSPeter Dunlap
748a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
749a6d42e7dSPeter Dunlap name = nvpair_name(nvp);
750a6d42e7dSPeter Dunlap
751a6d42e7dSPeter Dunlap ret = nvpair_value_nvlist(nvp, &nvt);
752a6d42e7dSPeter Dunlap if (ret != 0) {
753a6d42e7dSPeter Dunlap /* invalid entry? */
754a6d42e7dSPeter Dunlap continue;
755a6d42e7dSPeter Dunlap }
756a6d42e7dSPeter Dunlap
757a6d42e7dSPeter Dunlap ret = it_nv_to_tpgt(nvt, name, &tpgt);
758a6d42e7dSPeter Dunlap if (ret != 0) {
759a6d42e7dSPeter Dunlap break;
760a6d42e7dSPeter Dunlap }
761a6d42e7dSPeter Dunlap
762a6d42e7dSPeter Dunlap (*count)++;
763a6d42e7dSPeter Dunlap
764a6d42e7dSPeter Dunlap if (*tpgtlist == NULL) {
765a6d42e7dSPeter Dunlap *tpgtlist = tpgt;
766a6d42e7dSPeter Dunlap } else {
767a6d42e7dSPeter Dunlap prev->tpgt_next = tpgt;
768a6d42e7dSPeter Dunlap }
769a6d42e7dSPeter Dunlap
770a6d42e7dSPeter Dunlap prev = tpgt;
771a6d42e7dSPeter Dunlap }
772a6d42e7dSPeter Dunlap
773a6d42e7dSPeter Dunlap if (ret != 0) {
774a6d42e7dSPeter Dunlap it_tpgt_free_cmn(*tpgtlist);
775a6d42e7dSPeter Dunlap *tpgtlist = NULL;
776a6d42e7dSPeter Dunlap }
777a6d42e7dSPeter Dunlap
778a6d42e7dSPeter Dunlap return (ret);
779a6d42e7dSPeter Dunlap }
780a6d42e7dSPeter Dunlap
781a6d42e7dSPeter Dunlap #ifndef _KERNEL
782a6d42e7dSPeter Dunlap int
it_tpg_to_nv(it_tpg_t * tpg,nvlist_t ** nvl)783a6d42e7dSPeter Dunlap it_tpg_to_nv(it_tpg_t *tpg, nvlist_t **nvl)
784a6d42e7dSPeter Dunlap {
785a6d42e7dSPeter Dunlap int ret;
786a6d42e7dSPeter Dunlap char **portalArray = NULL;
787a6d42e7dSPeter Dunlap int i;
788a6d42e7dSPeter Dunlap it_portal_t *ptr;
789a6d42e7dSPeter Dunlap
790a6d42e7dSPeter Dunlap if (!nvl) {
791a6d42e7dSPeter Dunlap return (EINVAL);
792a6d42e7dSPeter Dunlap }
793a6d42e7dSPeter Dunlap
794a6d42e7dSPeter Dunlap if (!tpg) {
795a6d42e7dSPeter Dunlap /* nothing to do */
796a6d42e7dSPeter Dunlap return (0);
797a6d42e7dSPeter Dunlap }
798a6d42e7dSPeter Dunlap
799a6d42e7dSPeter Dunlap ret = nvlist_alloc(nvl, NV_UNIQUE_NAME, 0);
800a6d42e7dSPeter Dunlap if (ret != 0) {
801a6d42e7dSPeter Dunlap return (ret);
802a6d42e7dSPeter Dunlap }
803a6d42e7dSPeter Dunlap
804a6d42e7dSPeter Dunlap ret = nvlist_add_uint64(*nvl, "generation", tpg->tpg_generation);
805a6d42e7dSPeter Dunlap
806a6d42e7dSPeter Dunlap if ((ret == 0) && tpg->tpg_portal_list) {
807a6d42e7dSPeter Dunlap /* add the portals */
808a6d42e7dSPeter Dunlap portalArray = iscsit_zalloc(tpg->tpg_portal_count *
809a6d42e7dSPeter Dunlap sizeof (it_portal_t));
810a6d42e7dSPeter Dunlap if (portalArray == NULL) {
811a6d42e7dSPeter Dunlap nvlist_free(*nvl);
812a6d42e7dSPeter Dunlap *nvl = NULL;
813a6d42e7dSPeter Dunlap return (ENOMEM);
814a6d42e7dSPeter Dunlap }
815a6d42e7dSPeter Dunlap
816a6d42e7dSPeter Dunlap i = 0;
817a6d42e7dSPeter Dunlap ptr = tpg->tpg_portal_list;
818a6d42e7dSPeter Dunlap
819a6d42e7dSPeter Dunlap while (ptr && (i < tpg->tpg_portal_count)) {
820a6d42e7dSPeter Dunlap ret = sockaddr_to_str(&(ptr->portal_addr),
821a6d42e7dSPeter Dunlap &(portalArray[i]));
822a6d42e7dSPeter Dunlap if (ret != 0) {
823a6d42e7dSPeter Dunlap break;
824a6d42e7dSPeter Dunlap }
82542bf653bSPeter Gill ptr = ptr->portal_next;
826a6d42e7dSPeter Dunlap i++;
827a6d42e7dSPeter Dunlap }
828a6d42e7dSPeter Dunlap }
829a6d42e7dSPeter Dunlap
830a6d42e7dSPeter Dunlap if ((ret == 0) && portalArray) {
831a6d42e7dSPeter Dunlap ret = nvlist_add_string_array(*nvl, "portalList",
832a6d42e7dSPeter Dunlap portalArray, i);
833a6d42e7dSPeter Dunlap }
834a6d42e7dSPeter Dunlap
835a6d42e7dSPeter Dunlap
836a6d42e7dSPeter Dunlap if (portalArray) {
8374f1fc35dSsrivijitha dugganapalli while (--i >= 0) {
838a6d42e7dSPeter Dunlap if (portalArray[i]) {
839a6d42e7dSPeter Dunlap iscsit_free(portalArray[i],
840a6d42e7dSPeter Dunlap strlen(portalArray[i] + 1));
841a6d42e7dSPeter Dunlap }
842a6d42e7dSPeter Dunlap }
843a6d42e7dSPeter Dunlap iscsit_free(portalArray,
844a6d42e7dSPeter Dunlap tpg->tpg_portal_count * sizeof (it_portal_t));
845a6d42e7dSPeter Dunlap }
846a6d42e7dSPeter Dunlap
847a6d42e7dSPeter Dunlap if (ret != 0) {
848a6d42e7dSPeter Dunlap nvlist_free(*nvl);
849a6d42e7dSPeter Dunlap *nvl = NULL;
850a6d42e7dSPeter Dunlap }
851a6d42e7dSPeter Dunlap
852a6d42e7dSPeter Dunlap return (ret);
853a6d42e7dSPeter Dunlap }
854a6d42e7dSPeter Dunlap #endif /* !_KERNEL */
855a6d42e7dSPeter Dunlap
856a6d42e7dSPeter Dunlap int
it_nv_to_tpg(nvlist_t * nvl,char * name,it_tpg_t ** tpg)857a6d42e7dSPeter Dunlap it_nv_to_tpg(nvlist_t *nvl, char *name, it_tpg_t **tpg)
858a6d42e7dSPeter Dunlap {
859a6d42e7dSPeter Dunlap int ret;
860a6d42e7dSPeter Dunlap it_tpg_t *ptpg;
861a6d42e7dSPeter Dunlap char **portalArray = NULL;
862a6d42e7dSPeter Dunlap uint32_t count = 0;
863a6d42e7dSPeter Dunlap
864a6d42e7dSPeter Dunlap if (!name || !tpg) {
865a6d42e7dSPeter Dunlap return (EINVAL);
866a6d42e7dSPeter Dunlap }
867a6d42e7dSPeter Dunlap
868a6d42e7dSPeter Dunlap *tpg = NULL;
869a6d42e7dSPeter Dunlap
870a6d42e7dSPeter Dunlap ptpg = iscsit_zalloc(sizeof (it_tpg_t));
871a6d42e7dSPeter Dunlap if (ptpg == NULL) {
872a6d42e7dSPeter Dunlap return (ENOMEM);
873a6d42e7dSPeter Dunlap }
874a6d42e7dSPeter Dunlap
875a6d42e7dSPeter Dunlap (void) strlcpy(ptpg->tpg_name, name, sizeof (ptpg->tpg_name));
876a6d42e7dSPeter Dunlap
877a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint64(nvl, "generation",
878a6d42e7dSPeter Dunlap &(ptpg->tpg_generation));
879a6d42e7dSPeter Dunlap
880a6d42e7dSPeter Dunlap if (ret == 0) {
881a6d42e7dSPeter Dunlap ret = nvlist_lookup_string_array(nvl, "portalList",
882a6d42e7dSPeter Dunlap &portalArray, &count);
883a6d42e7dSPeter Dunlap }
884a6d42e7dSPeter Dunlap
885a6d42e7dSPeter Dunlap if (ret == 0) {
886a6d42e7dSPeter Dunlap /* set the portals */
887a6d42e7dSPeter Dunlap ret = it_array_to_portallist(portalArray, count,
888a6d42e7dSPeter Dunlap ISCSI_LISTEN_PORT, &ptpg->tpg_portal_list,
889a6d42e7dSPeter Dunlap &ptpg->tpg_portal_count);
890a6d42e7dSPeter Dunlap } else if (ret == ENOENT) {
891a6d42e7dSPeter Dunlap ret = 0;
892a6d42e7dSPeter Dunlap }
893a6d42e7dSPeter Dunlap
894a6d42e7dSPeter Dunlap if (ret == 0) {
895a6d42e7dSPeter Dunlap *tpg = ptpg;
896a6d42e7dSPeter Dunlap } else {
897a6d42e7dSPeter Dunlap it_tpg_free_cmn(ptpg);
898a6d42e7dSPeter Dunlap }
899a6d42e7dSPeter Dunlap
900a6d42e7dSPeter Dunlap return (ret);
901a6d42e7dSPeter Dunlap }
902a6d42e7dSPeter Dunlap
903a6d42e7dSPeter Dunlap
904a6d42e7dSPeter Dunlap
905a6d42e7dSPeter Dunlap
906a6d42e7dSPeter Dunlap #ifndef _KERNEL
907a6d42e7dSPeter Dunlap int
it_tpglist_to_nv(it_tpg_t * tpglist,nvlist_t ** nvl)908a6d42e7dSPeter Dunlap it_tpglist_to_nv(it_tpg_t *tpglist, nvlist_t **nvl)
909a6d42e7dSPeter Dunlap {
910a6d42e7dSPeter Dunlap int ret;
911a6d42e7dSPeter Dunlap nvlist_t *pnv = NULL;
912a6d42e7dSPeter Dunlap nvlist_t *tnv;
913a6d42e7dSPeter Dunlap it_tpg_t *ptr = tpglist;
914a6d42e7dSPeter Dunlap
915a6d42e7dSPeter Dunlap if (!nvl) {
916a6d42e7dSPeter Dunlap return (EINVAL);
917a6d42e7dSPeter Dunlap }
918a6d42e7dSPeter Dunlap
919a6d42e7dSPeter Dunlap if (!tpglist) {
920a6d42e7dSPeter Dunlap /* nothing to do */
921a6d42e7dSPeter Dunlap return (0);
922a6d42e7dSPeter Dunlap }
923a6d42e7dSPeter Dunlap
924a6d42e7dSPeter Dunlap /* create the target portal group list if required */
925a6d42e7dSPeter Dunlap if (*nvl == NULL) {
926a6d42e7dSPeter Dunlap ret = nvlist_alloc(&pnv, NV_UNIQUE_NAME, 0);
927a6d42e7dSPeter Dunlap if (ret != 0) {
928a6d42e7dSPeter Dunlap return (ret);
929a6d42e7dSPeter Dunlap }
930a6d42e7dSPeter Dunlap *nvl = pnv;
931a6d42e7dSPeter Dunlap }
932a6d42e7dSPeter Dunlap
933a6d42e7dSPeter Dunlap while (ptr) {
934a6d42e7dSPeter Dunlap ret = it_tpg_to_nv(ptr, &tnv);
935a6d42e7dSPeter Dunlap
936a6d42e7dSPeter Dunlap if (ret != 0) {
937a6d42e7dSPeter Dunlap break;
938a6d42e7dSPeter Dunlap }
939a6d42e7dSPeter Dunlap
940a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, ptr->tpg_name, tnv);
941a6d42e7dSPeter Dunlap
942a6d42e7dSPeter Dunlap if (ret != 0) {
943a6d42e7dSPeter Dunlap break;
944a6d42e7dSPeter Dunlap }
945a6d42e7dSPeter Dunlap
946a6d42e7dSPeter Dunlap nvlist_free(tnv);
947a6d42e7dSPeter Dunlap
948a6d42e7dSPeter Dunlap ptr = ptr->tpg_next;
949a6d42e7dSPeter Dunlap }
950a6d42e7dSPeter Dunlap
951a6d42e7dSPeter Dunlap if (ret != 0) {
952a6d42e7dSPeter Dunlap if (pnv) {
953a6d42e7dSPeter Dunlap nvlist_free(pnv);
954a6d42e7dSPeter Dunlap *nvl = NULL;
955a6d42e7dSPeter Dunlap }
956a6d42e7dSPeter Dunlap }
957a6d42e7dSPeter Dunlap
958a6d42e7dSPeter Dunlap return (ret);
959a6d42e7dSPeter Dunlap }
960a6d42e7dSPeter Dunlap #endif /* !_KERNEL */
961a6d42e7dSPeter Dunlap
962a6d42e7dSPeter Dunlap it_tpg_t *
it_tpg_lookup(it_config_t * cfg,char * tpg_name)963a6d42e7dSPeter Dunlap it_tpg_lookup(it_config_t *cfg, char *tpg_name)
964a6d42e7dSPeter Dunlap {
965a6d42e7dSPeter Dunlap it_tpg_t *cfg_tpg = NULL;
966a6d42e7dSPeter Dunlap
967a6d42e7dSPeter Dunlap for (cfg_tpg = cfg->config_tpg_list;
968a6d42e7dSPeter Dunlap cfg_tpg != NULL;
969a6d42e7dSPeter Dunlap cfg_tpg = cfg_tpg->tpg_next) {
970a6d42e7dSPeter Dunlap if (strncmp(&cfg_tpg->tpg_name[0], tpg_name,
971a6d42e7dSPeter Dunlap MAX_TPG_NAMELEN) == 0) {
972a6d42e7dSPeter Dunlap return (cfg_tpg);
973a6d42e7dSPeter Dunlap }
974a6d42e7dSPeter Dunlap }
975a6d42e7dSPeter Dunlap
976a6d42e7dSPeter Dunlap return (NULL);
977a6d42e7dSPeter Dunlap }
978a6d42e7dSPeter Dunlap
979a6d42e7dSPeter Dunlap int
it_sa_compare(struct sockaddr_storage * sa1,struct sockaddr_storage * sa2)980a6d42e7dSPeter Dunlap it_sa_compare(struct sockaddr_storage *sa1, struct sockaddr_storage *sa2)
981a6d42e7dSPeter Dunlap {
982a6d42e7dSPeter Dunlap struct sockaddr_in *sin1, *sin2;
983a6d42e7dSPeter Dunlap struct sockaddr_in6 *sin6_1, *sin6_2;
984a6d42e7dSPeter Dunlap
985a6d42e7dSPeter Dunlap /*
986a6d42e7dSPeter Dunlap * XXX - should we check here for IPv4 addrs mapped to v6?
987a6d42e7dSPeter Dunlap * see also iscsit_is_v4_mapped in iscsit_login.c
988a6d42e7dSPeter Dunlap */
989a6d42e7dSPeter Dunlap
990a6d42e7dSPeter Dunlap if (sa1->ss_family != sa2->ss_family) {
991a6d42e7dSPeter Dunlap return (1);
992a6d42e7dSPeter Dunlap }
993a6d42e7dSPeter Dunlap
994a6d42e7dSPeter Dunlap /*
995a6d42e7dSPeter Dunlap * sockaddr_in has padding which may not be initialized.
996a6d42e7dSPeter Dunlap * be more specific in the comparison, and don't trust the
997a6d42e7dSPeter Dunlap * caller has fully initialized the structure.
998a6d42e7dSPeter Dunlap */
999a6d42e7dSPeter Dunlap if (sa1->ss_family == AF_INET) {
1000a6d42e7dSPeter Dunlap sin1 = (struct sockaddr_in *)sa1;
1001a6d42e7dSPeter Dunlap sin2 = (struct sockaddr_in *)sa2;
1002a6d42e7dSPeter Dunlap if ((bcmp(&sin1->sin_addr, &sin2->sin_addr,
1003a6d42e7dSPeter Dunlap sizeof (struct in_addr)) == 0) &&
1004a6d42e7dSPeter Dunlap (sin1->sin_port == sin2->sin_port)) {
1005a6d42e7dSPeter Dunlap return (0);
1006a6d42e7dSPeter Dunlap }
1007a6d42e7dSPeter Dunlap } else if (sa1->ss_family == AF_INET6) {
1008a6d42e7dSPeter Dunlap sin6_1 = (struct sockaddr_in6 *)sa1;
1009a6d42e7dSPeter Dunlap sin6_2 = (struct sockaddr_in6 *)sa2;
1010a6d42e7dSPeter Dunlap if (bcmp(sin6_1, sin6_2, sizeof (struct sockaddr_in6)) == 0) {
1011a6d42e7dSPeter Dunlap return (0);
1012a6d42e7dSPeter Dunlap }
1013a6d42e7dSPeter Dunlap }
1014a6d42e7dSPeter Dunlap
1015a6d42e7dSPeter Dunlap return (1);
1016a6d42e7dSPeter Dunlap }
1017a6d42e7dSPeter Dunlap
1018a6d42e7dSPeter Dunlap it_portal_t *
it_portal_lookup(it_tpg_t * tpg,struct sockaddr_storage * sa)1019a6d42e7dSPeter Dunlap it_portal_lookup(it_tpg_t *tpg, struct sockaddr_storage *sa)
1020a6d42e7dSPeter Dunlap {
1021a6d42e7dSPeter Dunlap it_portal_t *cfg_portal;
1022a6d42e7dSPeter Dunlap
1023a6d42e7dSPeter Dunlap for (cfg_portal = tpg->tpg_portal_list;
1024a6d42e7dSPeter Dunlap cfg_portal != NULL;
102542bf653bSPeter Gill cfg_portal = cfg_portal->portal_next) {
1026a6d42e7dSPeter Dunlap if (it_sa_compare(sa, &cfg_portal->portal_addr) == 0)
1027a6d42e7dSPeter Dunlap return (cfg_portal);
1028a6d42e7dSPeter Dunlap }
1029a6d42e7dSPeter Dunlap
1030a6d42e7dSPeter Dunlap return (NULL);
1031a6d42e7dSPeter Dunlap }
1032a6d42e7dSPeter Dunlap
1033a6d42e7dSPeter Dunlap it_portal_t *
it_sns_svr_lookup(it_config_t * cfg,struct sockaddr_storage * sa)1034a6d42e7dSPeter Dunlap it_sns_svr_lookup(it_config_t *cfg, struct sockaddr_storage *sa)
1035a6d42e7dSPeter Dunlap {
1036a6d42e7dSPeter Dunlap it_portal_t *cfg_portal;
1037a6d42e7dSPeter Dunlap
1038a6d42e7dSPeter Dunlap for (cfg_portal = cfg->config_isns_svr_list;
1039a6d42e7dSPeter Dunlap cfg_portal != NULL;
104042bf653bSPeter Gill cfg_portal = cfg_portal->portal_next) {
1041a6d42e7dSPeter Dunlap if (it_sa_compare(sa, &cfg_portal->portal_addr) == 0)
1042a6d42e7dSPeter Dunlap return (cfg_portal);
1043a6d42e7dSPeter Dunlap }
1044a6d42e7dSPeter Dunlap
1045a6d42e7dSPeter Dunlap return (NULL);
1046a6d42e7dSPeter Dunlap }
1047a6d42e7dSPeter Dunlap
1048a6d42e7dSPeter Dunlap int
it_nv_to_tpglist(nvlist_t * nvl,uint32_t * count,it_tpg_t ** tpglist)1049a6d42e7dSPeter Dunlap it_nv_to_tpglist(nvlist_t *nvl, uint32_t *count, it_tpg_t **tpglist)
1050a6d42e7dSPeter Dunlap {
1051a6d42e7dSPeter Dunlap int ret = 0;
1052a6d42e7dSPeter Dunlap it_tpg_t *tpg;
1053a6d42e7dSPeter Dunlap it_tpg_t *prev = NULL;
1054a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL;
1055a6d42e7dSPeter Dunlap nvlist_t *nvt;
1056a6d42e7dSPeter Dunlap char *name;
1057a6d42e7dSPeter Dunlap
1058a6d42e7dSPeter Dunlap if (!tpglist || !count) {
1059a6d42e7dSPeter Dunlap return (EINVAL);
1060a6d42e7dSPeter Dunlap }
1061a6d42e7dSPeter Dunlap
1062a6d42e7dSPeter Dunlap *tpglist = NULL;
1063a6d42e7dSPeter Dunlap *count = 0;
1064a6d42e7dSPeter Dunlap
1065a6d42e7dSPeter Dunlap if (!nvl) {
1066a6d42e7dSPeter Dunlap /* nothing to do */
1067a6d42e7dSPeter Dunlap return (0);
1068a6d42e7dSPeter Dunlap }
1069a6d42e7dSPeter Dunlap
1070a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
1071a6d42e7dSPeter Dunlap name = nvpair_name(nvp);
1072a6d42e7dSPeter Dunlap
1073a6d42e7dSPeter Dunlap ret = nvpair_value_nvlist(nvp, &nvt);
1074a6d42e7dSPeter Dunlap if (ret != 0) {
1075a6d42e7dSPeter Dunlap /* invalid entry? */
1076a6d42e7dSPeter Dunlap continue;
1077a6d42e7dSPeter Dunlap }
1078a6d42e7dSPeter Dunlap
1079a6d42e7dSPeter Dunlap ret = it_nv_to_tpg(nvt, name, &tpg);
1080a6d42e7dSPeter Dunlap if (ret != 0) {
1081a6d42e7dSPeter Dunlap break;
1082a6d42e7dSPeter Dunlap }
1083a6d42e7dSPeter Dunlap
1084a6d42e7dSPeter Dunlap (*count)++;
1085a6d42e7dSPeter Dunlap
1086a6d42e7dSPeter Dunlap if (*tpglist == NULL) {
1087a6d42e7dSPeter Dunlap *tpglist = tpg;
1088a6d42e7dSPeter Dunlap } else {
1089a6d42e7dSPeter Dunlap prev->tpg_next = tpg;
1090a6d42e7dSPeter Dunlap }
1091a6d42e7dSPeter Dunlap prev = tpg;
1092a6d42e7dSPeter Dunlap }
1093a6d42e7dSPeter Dunlap
1094a6d42e7dSPeter Dunlap if (ret != 0) {
1095a6d42e7dSPeter Dunlap it_tpg_free_cmn(*tpglist);
1096a6d42e7dSPeter Dunlap *tpglist = NULL;
1097a6d42e7dSPeter Dunlap }
1098a6d42e7dSPeter Dunlap
1099a6d42e7dSPeter Dunlap return (ret);
1100a6d42e7dSPeter Dunlap }
1101a6d42e7dSPeter Dunlap
1102a6d42e7dSPeter Dunlap int
it_ini_to_nv(it_ini_t * ini,nvlist_t ** nvl)1103a6d42e7dSPeter Dunlap it_ini_to_nv(it_ini_t *ini, nvlist_t **nvl)
1104a6d42e7dSPeter Dunlap {
1105a6d42e7dSPeter Dunlap int ret;
1106a6d42e7dSPeter Dunlap
1107a6d42e7dSPeter Dunlap if (!nvl) {
1108a6d42e7dSPeter Dunlap return (EINVAL);
1109a6d42e7dSPeter Dunlap }
1110a6d42e7dSPeter Dunlap
1111a6d42e7dSPeter Dunlap if (!ini) {
1112a6d42e7dSPeter Dunlap return (0);
1113a6d42e7dSPeter Dunlap }
1114a6d42e7dSPeter Dunlap
1115a6d42e7dSPeter Dunlap ret = nvlist_alloc(nvl, NV_UNIQUE_NAME, 0);
1116a6d42e7dSPeter Dunlap if (ret != 0) {
1117a6d42e7dSPeter Dunlap return (ret);
1118a6d42e7dSPeter Dunlap }
1119a6d42e7dSPeter Dunlap
1120a6d42e7dSPeter Dunlap if (ini->ini_properties) {
1121a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, "properties",
1122a6d42e7dSPeter Dunlap ini->ini_properties);
1123a6d42e7dSPeter Dunlap }
1124a6d42e7dSPeter Dunlap
1125a6d42e7dSPeter Dunlap if (ret == 0) {
1126a6d42e7dSPeter Dunlap ret = nvlist_add_uint64(*nvl, "generation",
1127a6d42e7dSPeter Dunlap ini->ini_generation);
1128a6d42e7dSPeter Dunlap } else if (ret == ENOENT) {
1129a6d42e7dSPeter Dunlap ret = 0;
1130a6d42e7dSPeter Dunlap }
1131a6d42e7dSPeter Dunlap
1132a6d42e7dSPeter Dunlap if (ret != 0) {
1133a6d42e7dSPeter Dunlap nvlist_free(*nvl);
1134a6d42e7dSPeter Dunlap *nvl = NULL;
1135a6d42e7dSPeter Dunlap }
1136a6d42e7dSPeter Dunlap
1137a6d42e7dSPeter Dunlap return (ret);
1138a6d42e7dSPeter Dunlap }
1139a6d42e7dSPeter Dunlap
1140a6d42e7dSPeter Dunlap int
it_nv_to_ini(nvlist_t * nvl,char * name,it_ini_t ** ini)1141a6d42e7dSPeter Dunlap it_nv_to_ini(nvlist_t *nvl, char *name, it_ini_t **ini)
1142a6d42e7dSPeter Dunlap {
1143a6d42e7dSPeter Dunlap int ret;
1144a6d42e7dSPeter Dunlap it_ini_t *inip;
1145a6d42e7dSPeter Dunlap nvlist_t *listval;
1146a6d42e7dSPeter Dunlap
1147a6d42e7dSPeter Dunlap if (!name || !ini) {
1148a6d42e7dSPeter Dunlap return (EINVAL);
1149a6d42e7dSPeter Dunlap }
1150a6d42e7dSPeter Dunlap
1151a6d42e7dSPeter Dunlap *ini = NULL;
1152a6d42e7dSPeter Dunlap
1153a6d42e7dSPeter Dunlap if (!nvl) {
1154a6d42e7dSPeter Dunlap return (0);
1155a6d42e7dSPeter Dunlap }
1156a6d42e7dSPeter Dunlap
1157a6d42e7dSPeter Dunlap inip = iscsit_zalloc(sizeof (it_ini_t));
1158a6d42e7dSPeter Dunlap if (!inip) {
1159a6d42e7dSPeter Dunlap return (ENOMEM);
1160a6d42e7dSPeter Dunlap }
1161a6d42e7dSPeter Dunlap
1162a6d42e7dSPeter Dunlap (void) strlcpy(inip->ini_name, name, sizeof (inip->ini_name));
1163a6d42e7dSPeter Dunlap
1164a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "properties", &listval);
1165a6d42e7dSPeter Dunlap if (ret == 0) {
1166a6d42e7dSPeter Dunlap ret = nvlist_dup(listval, &(inip->ini_properties), 0);
1167a6d42e7dSPeter Dunlap } else if (ret == ENOENT) {
1168a6d42e7dSPeter Dunlap ret = 0;
1169a6d42e7dSPeter Dunlap }
1170a6d42e7dSPeter Dunlap
1171a6d42e7dSPeter Dunlap if (ret == 0) {
1172a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint64(nvl, "generation",
1173a6d42e7dSPeter Dunlap &(inip->ini_generation));
1174a6d42e7dSPeter Dunlap }
1175a6d42e7dSPeter Dunlap
1176a6d42e7dSPeter Dunlap if (ret == 0) {
1177a6d42e7dSPeter Dunlap *ini = inip;
1178a6d42e7dSPeter Dunlap } else {
1179a6d42e7dSPeter Dunlap it_ini_free_cmn(inip);
1180a6d42e7dSPeter Dunlap }
1181a6d42e7dSPeter Dunlap
1182a6d42e7dSPeter Dunlap return (ret);
1183a6d42e7dSPeter Dunlap }
1184a6d42e7dSPeter Dunlap
1185a6d42e7dSPeter Dunlap int
it_inilist_to_nv(it_ini_t * inilist,nvlist_t ** nvl)1186a6d42e7dSPeter Dunlap it_inilist_to_nv(it_ini_t *inilist, nvlist_t **nvl)
1187a6d42e7dSPeter Dunlap {
1188a6d42e7dSPeter Dunlap int ret;
1189a6d42e7dSPeter Dunlap nvlist_t *pnv = NULL;
1190a6d42e7dSPeter Dunlap nvlist_t *tnv;
1191a6d42e7dSPeter Dunlap it_ini_t *ptr = inilist;
1192a6d42e7dSPeter Dunlap
1193a6d42e7dSPeter Dunlap if (!nvl) {
1194a6d42e7dSPeter Dunlap return (EINVAL);
1195a6d42e7dSPeter Dunlap }
1196a6d42e7dSPeter Dunlap
1197a6d42e7dSPeter Dunlap if (!inilist) {
1198a6d42e7dSPeter Dunlap return (0);
1199a6d42e7dSPeter Dunlap }
1200a6d42e7dSPeter Dunlap
1201a6d42e7dSPeter Dunlap /* create the target list if required */
1202a6d42e7dSPeter Dunlap if (*nvl == NULL) {
1203a6d42e7dSPeter Dunlap ret = nvlist_alloc(&pnv, NV_UNIQUE_NAME, 0);
1204a6d42e7dSPeter Dunlap if (ret != 0) {
1205a6d42e7dSPeter Dunlap return (ret);
1206a6d42e7dSPeter Dunlap }
1207a6d42e7dSPeter Dunlap *nvl = pnv;
1208a6d42e7dSPeter Dunlap }
1209a6d42e7dSPeter Dunlap
1210a6d42e7dSPeter Dunlap while (ptr) {
1211a6d42e7dSPeter Dunlap ret = it_ini_to_nv(ptr, &tnv);
1212a6d42e7dSPeter Dunlap
1213a6d42e7dSPeter Dunlap if (ret != 0) {
1214a6d42e7dSPeter Dunlap break;
1215a6d42e7dSPeter Dunlap }
1216a6d42e7dSPeter Dunlap
1217a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, ptr->ini_name, tnv);
1218a6d42e7dSPeter Dunlap
1219a6d42e7dSPeter Dunlap if (ret != 0) {
1220a6d42e7dSPeter Dunlap break;
1221a6d42e7dSPeter Dunlap }
1222a6d42e7dSPeter Dunlap
1223a6d42e7dSPeter Dunlap nvlist_free(tnv);
1224a6d42e7dSPeter Dunlap
1225a6d42e7dSPeter Dunlap ptr = ptr->ini_next;
1226a6d42e7dSPeter Dunlap }
1227a6d42e7dSPeter Dunlap
1228a6d42e7dSPeter Dunlap if (ret != 0) {
1229a6d42e7dSPeter Dunlap if (pnv) {
1230a6d42e7dSPeter Dunlap nvlist_free(pnv);
1231a6d42e7dSPeter Dunlap *nvl = NULL;
1232a6d42e7dSPeter Dunlap }
1233a6d42e7dSPeter Dunlap }
1234a6d42e7dSPeter Dunlap
1235a6d42e7dSPeter Dunlap return (ret);
1236a6d42e7dSPeter Dunlap }
1237a6d42e7dSPeter Dunlap
1238a6d42e7dSPeter Dunlap int
it_nv_to_inilist(nvlist_t * nvl,uint32_t * count,it_ini_t ** inilist)1239a6d42e7dSPeter Dunlap it_nv_to_inilist(nvlist_t *nvl, uint32_t *count, it_ini_t **inilist)
1240a6d42e7dSPeter Dunlap {
1241a6d42e7dSPeter Dunlap int ret = 0;
1242a6d42e7dSPeter Dunlap it_ini_t *inip;
1243a6d42e7dSPeter Dunlap it_ini_t *prev = NULL;
1244a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL;
1245a6d42e7dSPeter Dunlap nvlist_t *nvt;
1246a6d42e7dSPeter Dunlap char *name;
1247a6d42e7dSPeter Dunlap
1248a6d42e7dSPeter Dunlap if (!inilist || !count) {
1249a6d42e7dSPeter Dunlap return (EINVAL);
1250a6d42e7dSPeter Dunlap }
1251a6d42e7dSPeter Dunlap
1252a6d42e7dSPeter Dunlap *inilist = NULL;
1253a6d42e7dSPeter Dunlap *count = 0;
1254a6d42e7dSPeter Dunlap
1255a6d42e7dSPeter Dunlap if (!nvl) {
1256a6d42e7dSPeter Dunlap /* nothing to do */
1257a6d42e7dSPeter Dunlap return (0);
1258a6d42e7dSPeter Dunlap }
1259a6d42e7dSPeter Dunlap
1260a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
1261a6d42e7dSPeter Dunlap name = nvpair_name(nvp);
1262a6d42e7dSPeter Dunlap
1263a6d42e7dSPeter Dunlap ret = nvpair_value_nvlist(nvp, &nvt);
1264a6d42e7dSPeter Dunlap if (ret != 0) {
1265a6d42e7dSPeter Dunlap /* invalid entry? */
1266a6d42e7dSPeter Dunlap continue;
1267a6d42e7dSPeter Dunlap }
1268a6d42e7dSPeter Dunlap
1269a6d42e7dSPeter Dunlap ret = it_nv_to_ini(nvt, name, &inip);
1270a6d42e7dSPeter Dunlap if (ret != 0) {
1271a6d42e7dSPeter Dunlap break;
1272a6d42e7dSPeter Dunlap }
1273a6d42e7dSPeter Dunlap
1274a6d42e7dSPeter Dunlap (*count)++;
1275a6d42e7dSPeter Dunlap
1276a6d42e7dSPeter Dunlap if (*inilist == NULL) {
1277a6d42e7dSPeter Dunlap *inilist = inip;
1278a6d42e7dSPeter Dunlap } else {
1279a6d42e7dSPeter Dunlap prev->ini_next = inip;
1280a6d42e7dSPeter Dunlap }
1281a6d42e7dSPeter Dunlap prev = inip;
1282a6d42e7dSPeter Dunlap }
1283a6d42e7dSPeter Dunlap
1284a6d42e7dSPeter Dunlap if (ret != 0) {
1285a6d42e7dSPeter Dunlap it_ini_free_cmn(*inilist);
1286a6d42e7dSPeter Dunlap *inilist = NULL;
1287a6d42e7dSPeter Dunlap }
1288a6d42e7dSPeter Dunlap
1289a6d42e7dSPeter Dunlap return (ret);
1290a6d42e7dSPeter Dunlap }
1291a6d42e7dSPeter Dunlap
1292a6d42e7dSPeter Dunlap /*
1293a6d42e7dSPeter Dunlap * Convert a sockaddr to the string representation, suitable for
1294a6d42e7dSPeter Dunlap * storing in an nvlist or printing out in a list.
1295a6d42e7dSPeter Dunlap */
1296a6d42e7dSPeter Dunlap #ifndef _KERNEL
1297a6d42e7dSPeter Dunlap int
sockaddr_to_str(struct sockaddr_storage * sa,char ** addr)1298a6d42e7dSPeter Dunlap sockaddr_to_str(struct sockaddr_storage *sa, char **addr)
1299a6d42e7dSPeter Dunlap {
1300a6d42e7dSPeter Dunlap int ret;
1301a6d42e7dSPeter Dunlap char buf[INET6_ADDRSTRLEN + 7]; /* addr : port */
1302a6d42e7dSPeter Dunlap char pbuf[7];
1303a6d42e7dSPeter Dunlap const char *bufp;
1304a6d42e7dSPeter Dunlap struct sockaddr_in *sin;
1305a6d42e7dSPeter Dunlap struct sockaddr_in6 *sin6;
1306a6d42e7dSPeter Dunlap uint16_t port;
1307a6d42e7dSPeter Dunlap
1308a6d42e7dSPeter Dunlap if (!sa || !addr) {
1309a6d42e7dSPeter Dunlap return (EINVAL);
1310a6d42e7dSPeter Dunlap }
1311a6d42e7dSPeter Dunlap
1312a6d42e7dSPeter Dunlap buf[0] = '\0';
1313a6d42e7dSPeter Dunlap
1314a6d42e7dSPeter Dunlap if (sa->ss_family == AF_INET) {
1315a6d42e7dSPeter Dunlap sin = (struct sockaddr_in *)sa;
1316a6d42e7dSPeter Dunlap bufp = inet_ntop(AF_INET,
1317a6d42e7dSPeter Dunlap (const void *)&(sin->sin_addr.s_addr),
1318a6d42e7dSPeter Dunlap buf, sizeof (buf));
1319a6d42e7dSPeter Dunlap if (bufp == NULL) {
1320a6d42e7dSPeter Dunlap ret = errno;
1321a6d42e7dSPeter Dunlap return (ret);
1322a6d42e7dSPeter Dunlap }
1323a6d42e7dSPeter Dunlap port = ntohs(sin->sin_port);
1324a6d42e7dSPeter Dunlap } else if (sa->ss_family == AF_INET6) {
1325a6d42e7dSPeter Dunlap (void) strlcat(buf, "[", sizeof (buf));
1326a6d42e7dSPeter Dunlap sin6 = (struct sockaddr_in6 *)sa;
1327a6d42e7dSPeter Dunlap bufp = inet_ntop(AF_INET6,
1328a6d42e7dSPeter Dunlap (const void *)&sin6->sin6_addr.s6_addr,
1329a6d42e7dSPeter Dunlap &buf[1], (sizeof (buf) - 1));
1330a6d42e7dSPeter Dunlap if (bufp == NULL) {
1331a6d42e7dSPeter Dunlap ret = errno;
1332a6d42e7dSPeter Dunlap return (ret);
1333a6d42e7dSPeter Dunlap }
1334a6d42e7dSPeter Dunlap (void) strlcat(buf, "]", sizeof (buf));
1335a6d42e7dSPeter Dunlap port = ntohs(sin6->sin6_port);
1336a6d42e7dSPeter Dunlap } else {
1337a6d42e7dSPeter Dunlap return (EINVAL);
1338a6d42e7dSPeter Dunlap }
1339a6d42e7dSPeter Dunlap
1340a6d42e7dSPeter Dunlap
1341a6d42e7dSPeter Dunlap (void) snprintf(pbuf, sizeof (pbuf), ":%u", port);
1342a6d42e7dSPeter Dunlap (void) strlcat(buf, pbuf, sizeof (buf));
1343a6d42e7dSPeter Dunlap
1344a6d42e7dSPeter Dunlap *addr = strdup(buf);
1345a6d42e7dSPeter Dunlap if (*addr == NULL) {
1346a6d42e7dSPeter Dunlap return (ENOMEM);
1347a6d42e7dSPeter Dunlap }
1348a6d42e7dSPeter Dunlap
1349a6d42e7dSPeter Dunlap return (0);
1350a6d42e7dSPeter Dunlap }
1351a6d42e7dSPeter Dunlap #endif /* !_KERNEL */
1352a6d42e7dSPeter Dunlap
1353a6d42e7dSPeter Dunlap int
it_array_to_portallist(char ** arr,uint32_t count,uint32_t default_port,it_portal_t ** portallist,uint32_t * list_count)1354a6d42e7dSPeter Dunlap it_array_to_portallist(char **arr, uint32_t count, uint32_t default_port,
1355a6d42e7dSPeter Dunlap it_portal_t **portallist, uint32_t *list_count)
1356a6d42e7dSPeter Dunlap {
1357a6d42e7dSPeter Dunlap int ret = 0;
1358a6d42e7dSPeter Dunlap int i;
1359a6d42e7dSPeter Dunlap it_portal_t *portal;
1360a6d42e7dSPeter Dunlap it_portal_t *prev = NULL;
1361a6d42e7dSPeter Dunlap it_portal_t *tmp;
1362a6d42e7dSPeter Dunlap
1363a6d42e7dSPeter Dunlap if (!arr || !portallist || !list_count) {
1364a6d42e7dSPeter Dunlap return (EINVAL);
1365a6d42e7dSPeter Dunlap }
1366a6d42e7dSPeter Dunlap
1367a6d42e7dSPeter Dunlap *list_count = 0;
1368a6d42e7dSPeter Dunlap *portallist = NULL;
1369a6d42e7dSPeter Dunlap
1370a6d42e7dSPeter Dunlap for (i = 0; i < count; i++) {
1371a6d42e7dSPeter Dunlap if (!arr[i]) {
1372a6d42e7dSPeter Dunlap /* should never happen */
1373a6d42e7dSPeter Dunlap continue;
1374a6d42e7dSPeter Dunlap }
1375a6d42e7dSPeter Dunlap portal = iscsit_zalloc(sizeof (it_portal_t));
1376a6d42e7dSPeter Dunlap if (!portal) {
1377a6d42e7dSPeter Dunlap ret = ENOMEM;
1378a6d42e7dSPeter Dunlap break;
1379a6d42e7dSPeter Dunlap }
1380a6d42e7dSPeter Dunlap if (it_common_convert_sa(arr[i],
1381a6d42e7dSPeter Dunlap &(portal->portal_addr), default_port) == NULL) {
1382a6d42e7dSPeter Dunlap iscsit_free(portal, sizeof (it_portal_t));
1383a6d42e7dSPeter Dunlap ret = EINVAL;
1384a6d42e7dSPeter Dunlap break;
1385a6d42e7dSPeter Dunlap }
1386a6d42e7dSPeter Dunlap
1387a6d42e7dSPeter Dunlap /* make sure no duplicates */
1388a6d42e7dSPeter Dunlap tmp = *portallist;
1389a6d42e7dSPeter Dunlap while (tmp) {
1390a6d42e7dSPeter Dunlap if (it_sa_compare(&(tmp->portal_addr),
1391a6d42e7dSPeter Dunlap &(portal->portal_addr)) == 0) {
1392a6d42e7dSPeter Dunlap iscsit_free(portal, sizeof (it_portal_t));
1393a6d42e7dSPeter Dunlap portal = NULL;
1394a6d42e7dSPeter Dunlap break;
1395a6d42e7dSPeter Dunlap }
139642bf653bSPeter Gill tmp = tmp->portal_next;
1397a6d42e7dSPeter Dunlap }
1398a6d42e7dSPeter Dunlap
1399a6d42e7dSPeter Dunlap if (!portal) {
1400a6d42e7dSPeter Dunlap continue;
1401a6d42e7dSPeter Dunlap }
1402a6d42e7dSPeter Dunlap
1403a6d42e7dSPeter Dunlap /*
1404a6d42e7dSPeter Dunlap * The first time through the loop, *portallist == NULL
1405a6d42e7dSPeter Dunlap * because we assigned it to NULL above. Subsequently
1406a6d42e7dSPeter Dunlap * prev will have been set. Therefor it's OK to put
140742bf653bSPeter Gill * lint override before prev->portal_next assignment.
1408a6d42e7dSPeter Dunlap */
1409a6d42e7dSPeter Dunlap if (*portallist == NULL) {
1410a6d42e7dSPeter Dunlap *portallist = portal;
1411a6d42e7dSPeter Dunlap } else {
141242bf653bSPeter Gill prev->portal_next = portal;
1413a6d42e7dSPeter Dunlap }
1414a6d42e7dSPeter Dunlap
1415a6d42e7dSPeter Dunlap prev = portal;
1416a6d42e7dSPeter Dunlap (*list_count)++;
1417a6d42e7dSPeter Dunlap }
1418a6d42e7dSPeter Dunlap
1419a6d42e7dSPeter Dunlap return (ret);
1420a6d42e7dSPeter Dunlap }
1421a6d42e7dSPeter Dunlap
1422a6d42e7dSPeter Dunlap /*
1423a6d42e7dSPeter Dunlap * Function: it_config_free_cmn()
1424a6d42e7dSPeter Dunlap *
1425a6d42e7dSPeter Dunlap * Free any resources associated with the it_config_t structure.
1426a6d42e7dSPeter Dunlap *
1427a6d42e7dSPeter Dunlap * Parameters:
1428a6d42e7dSPeter Dunlap * cfg A C representation of the current iSCSI configuration
1429a6d42e7dSPeter Dunlap */
1430a6d42e7dSPeter Dunlap void
it_config_free_cmn(it_config_t * cfg)1431a6d42e7dSPeter Dunlap it_config_free_cmn(it_config_t *cfg)
1432a6d42e7dSPeter Dunlap {
1433a6d42e7dSPeter Dunlap if (!cfg) {
1434a6d42e7dSPeter Dunlap return;
1435a6d42e7dSPeter Dunlap }
1436a6d42e7dSPeter Dunlap
1437a6d42e7dSPeter Dunlap if (cfg->config_tgt_list) {
1438a6d42e7dSPeter Dunlap it_tgt_free_cmn(cfg->config_tgt_list);
1439a6d42e7dSPeter Dunlap }
1440a6d42e7dSPeter Dunlap
1441a6d42e7dSPeter Dunlap if (cfg->config_tpg_list) {
1442a6d42e7dSPeter Dunlap it_tpg_free_cmn(cfg->config_tpg_list);
1443a6d42e7dSPeter Dunlap }
1444a6d42e7dSPeter Dunlap
1445a6d42e7dSPeter Dunlap if (cfg->config_ini_list) {
1446a6d42e7dSPeter Dunlap it_ini_free_cmn(cfg->config_ini_list);
1447a6d42e7dSPeter Dunlap }
1448a6d42e7dSPeter Dunlap
1449a6d42e7dSPeter Dunlap if (cfg->config_global_properties) {
1450a6d42e7dSPeter Dunlap nvlist_free(cfg->config_global_properties);
1451a6d42e7dSPeter Dunlap }
1452a6d42e7dSPeter Dunlap
1453a6d42e7dSPeter Dunlap if (cfg->config_isns_svr_list) {
1454a6d42e7dSPeter Dunlap it_portal_t *pp = cfg->config_isns_svr_list;
1455a6d42e7dSPeter Dunlap it_portal_t *pp_next;
1456a6d42e7dSPeter Dunlap
1457a6d42e7dSPeter Dunlap while (pp) {
145842bf653bSPeter Gill pp_next = pp->portal_next;
1459a6d42e7dSPeter Dunlap iscsit_free(pp, sizeof (it_portal_t));
1460a6d42e7dSPeter Dunlap pp = pp_next;
1461a6d42e7dSPeter Dunlap }
1462a6d42e7dSPeter Dunlap }
1463a6d42e7dSPeter Dunlap
1464a6d42e7dSPeter Dunlap iscsit_free(cfg, sizeof (it_config_t));
1465a6d42e7dSPeter Dunlap }
1466a6d42e7dSPeter Dunlap
1467a6d42e7dSPeter Dunlap /*
1468a6d42e7dSPeter Dunlap * Function: it_tgt_free_cmn()
1469a6d42e7dSPeter Dunlap *
1470a6d42e7dSPeter Dunlap * Frees an it_tgt_t structure. If tgt_next is not NULL, frees
1471a6d42e7dSPeter Dunlap * all structures in the list.
1472a6d42e7dSPeter Dunlap */
1473a6d42e7dSPeter Dunlap void
it_tgt_free_cmn(it_tgt_t * tgt)1474a6d42e7dSPeter Dunlap it_tgt_free_cmn(it_tgt_t *tgt)
1475a6d42e7dSPeter Dunlap {
1476a6d42e7dSPeter Dunlap it_tgt_t *tgtp = tgt;
1477a6d42e7dSPeter Dunlap it_tgt_t *next;
1478a6d42e7dSPeter Dunlap
1479a6d42e7dSPeter Dunlap if (!tgt) {
1480a6d42e7dSPeter Dunlap return;
1481a6d42e7dSPeter Dunlap }
1482a6d42e7dSPeter Dunlap
1483a6d42e7dSPeter Dunlap while (tgtp) {
1484a6d42e7dSPeter Dunlap next = tgtp->tgt_next;
1485a6d42e7dSPeter Dunlap
1486a6d42e7dSPeter Dunlap if (tgtp->tgt_tpgt_list) {
1487a6d42e7dSPeter Dunlap it_tpgt_free_cmn(tgtp->tgt_tpgt_list);
1488a6d42e7dSPeter Dunlap }
1489a6d42e7dSPeter Dunlap
1490a6d42e7dSPeter Dunlap if (tgtp->tgt_properties) {
1491a6d42e7dSPeter Dunlap nvlist_free(tgtp->tgt_properties);
1492a6d42e7dSPeter Dunlap }
1493a6d42e7dSPeter Dunlap
1494a6d42e7dSPeter Dunlap iscsit_free(tgtp, sizeof (it_tgt_t));
1495a6d42e7dSPeter Dunlap
1496a6d42e7dSPeter Dunlap tgtp = next;
1497a6d42e7dSPeter Dunlap }
1498a6d42e7dSPeter Dunlap }
1499a6d42e7dSPeter Dunlap
1500a6d42e7dSPeter Dunlap /*
1501a6d42e7dSPeter Dunlap * Function: it_tpgt_free_cmn()
1502a6d42e7dSPeter Dunlap *
1503a6d42e7dSPeter Dunlap * Deallocates resources of an it_tpgt_t structure. If tpgt->next
1504a6d42e7dSPeter Dunlap * is not NULL, frees all members of the list.
1505a6d42e7dSPeter Dunlap */
1506a6d42e7dSPeter Dunlap void
it_tpgt_free_cmn(it_tpgt_t * tpgt)1507a6d42e7dSPeter Dunlap it_tpgt_free_cmn(it_tpgt_t *tpgt)
1508a6d42e7dSPeter Dunlap {
1509a6d42e7dSPeter Dunlap it_tpgt_t *tpgtp = tpgt;
1510a6d42e7dSPeter Dunlap it_tpgt_t *next;
1511a6d42e7dSPeter Dunlap
1512a6d42e7dSPeter Dunlap if (!tpgt) {
1513a6d42e7dSPeter Dunlap return;
1514a6d42e7dSPeter Dunlap }
1515a6d42e7dSPeter Dunlap
1516a6d42e7dSPeter Dunlap while (tpgtp) {
1517a6d42e7dSPeter Dunlap next = tpgtp->tpgt_next;
1518a6d42e7dSPeter Dunlap
1519a6d42e7dSPeter Dunlap iscsit_free(tpgtp, sizeof (it_tpgt_t));
1520a6d42e7dSPeter Dunlap
1521a6d42e7dSPeter Dunlap tpgtp = next;
1522a6d42e7dSPeter Dunlap }
1523a6d42e7dSPeter Dunlap }
1524a6d42e7dSPeter Dunlap
1525a6d42e7dSPeter Dunlap /*
1526a6d42e7dSPeter Dunlap * Function: it_tpg_free_cmn()
1527a6d42e7dSPeter Dunlap *
1528a6d42e7dSPeter Dunlap * Deallocates resources associated with an it_tpg_t structure.
1529a6d42e7dSPeter Dunlap * If tpg->next is not NULL, frees all members of the list.
1530a6d42e7dSPeter Dunlap */
1531a6d42e7dSPeter Dunlap void
it_tpg_free_cmn(it_tpg_t * tpg)1532a6d42e7dSPeter Dunlap it_tpg_free_cmn(it_tpg_t *tpg)
1533a6d42e7dSPeter Dunlap {
1534a6d42e7dSPeter Dunlap it_tpg_t *tpgp = tpg;
1535a6d42e7dSPeter Dunlap it_tpg_t *next;
1536a6d42e7dSPeter Dunlap it_portal_t *portalp;
1537a6d42e7dSPeter Dunlap it_portal_t *pnext;
1538a6d42e7dSPeter Dunlap
1539a6d42e7dSPeter Dunlap while (tpgp) {
1540a6d42e7dSPeter Dunlap next = tpgp->tpg_next;
1541a6d42e7dSPeter Dunlap
1542a6d42e7dSPeter Dunlap portalp = tpgp->tpg_portal_list;
1543a6d42e7dSPeter Dunlap
1544a6d42e7dSPeter Dunlap while (portalp) {
154542bf653bSPeter Gill pnext = portalp->portal_next;
1546a6d42e7dSPeter Dunlap iscsit_free(portalp, sizeof (it_portal_t));
1547a6d42e7dSPeter Dunlap portalp = pnext;
1548a6d42e7dSPeter Dunlap }
1549a6d42e7dSPeter Dunlap
1550a6d42e7dSPeter Dunlap iscsit_free(tpgp, sizeof (it_tpg_t));
1551a6d42e7dSPeter Dunlap
1552a6d42e7dSPeter Dunlap tpgp = next;
1553a6d42e7dSPeter Dunlap }
1554a6d42e7dSPeter Dunlap }
1555a6d42e7dSPeter Dunlap
1556a6d42e7dSPeter Dunlap /*
1557a6d42e7dSPeter Dunlap * Function: it_ini_free_cmn()
1558a6d42e7dSPeter Dunlap *
1559a6d42e7dSPeter Dunlap * Deallocates resources of an it_ini_t structure. If ini->next is
1560a6d42e7dSPeter Dunlap * not NULL, frees all members of the list.
1561a6d42e7dSPeter Dunlap */
1562a6d42e7dSPeter Dunlap void
it_ini_free_cmn(it_ini_t * ini)1563a6d42e7dSPeter Dunlap it_ini_free_cmn(it_ini_t *ini)
1564a6d42e7dSPeter Dunlap {
1565a6d42e7dSPeter Dunlap it_ini_t *inip = ini;
1566a6d42e7dSPeter Dunlap it_ini_t *next;
1567a6d42e7dSPeter Dunlap
1568a6d42e7dSPeter Dunlap if (!ini) {
1569a6d42e7dSPeter Dunlap return;
1570a6d42e7dSPeter Dunlap }
1571a6d42e7dSPeter Dunlap
1572a6d42e7dSPeter Dunlap while (inip) {
1573a6d42e7dSPeter Dunlap next = inip->ini_next;
1574a6d42e7dSPeter Dunlap
1575a6d42e7dSPeter Dunlap if (inip->ini_properties) {
1576a6d42e7dSPeter Dunlap nvlist_free(inip->ini_properties);
1577a6d42e7dSPeter Dunlap }
1578a6d42e7dSPeter Dunlap
1579a6d42e7dSPeter Dunlap iscsit_free(inip, sizeof (it_ini_t));
1580a6d42e7dSPeter Dunlap
1581a6d42e7dSPeter Dunlap inip = next;
1582a6d42e7dSPeter Dunlap }
1583a6d42e7dSPeter Dunlap }
1584