1*6fea88c2Smlelstv /* $NetBSD: iscsid_discover.c,v 1.5 2016/05/29 13:35:45 mlelstv Exp $ */
275a17f3cSagc
375a17f3cSagc /*-
475a17f3cSagc * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
575a17f3cSagc * All rights reserved.
675a17f3cSagc *
775a17f3cSagc * This code is derived from software contributed to The NetBSD Foundation
875a17f3cSagc * by Wasabi Systems, Inc.
975a17f3cSagc *
1075a17f3cSagc * Redistribution and use in source and binary forms, with or without
1175a17f3cSagc * modification, are permitted provided that the following conditions
1275a17f3cSagc * are met:
1375a17f3cSagc * 1. Redistributions of source code must retain the above copyright
1475a17f3cSagc * notice, this list of conditions and the following disclaimer.
1575a17f3cSagc * 2. Redistributions in binary form must reproduce the above copyright
1675a17f3cSagc * notice, this list of conditions and the following disclaimer in the
1775a17f3cSagc * documentation and/or other materials provided with the distribution.
1875a17f3cSagc *
1975a17f3cSagc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2075a17f3cSagc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2175a17f3cSagc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2275a17f3cSagc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2375a17f3cSagc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2475a17f3cSagc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2575a17f3cSagc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2675a17f3cSagc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2775a17f3cSagc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2875a17f3cSagc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2975a17f3cSagc * POSSIBILITY OF SUCH DAMAGE.
3075a17f3cSagc */
3175a17f3cSagc
3275a17f3cSagc #ifndef ISCSI_MINIMAL
3375a17f3cSagc
3475a17f3cSagc #include "iscsid_globals.h"
3575a17f3cSagc #include "isns.h"
3675a17f3cSagc #include "isns_defs.h"
3775a17f3cSagc
3875a17f3cSagc #include <sys/socket.h>
3975a17f3cSagc #include <netinet/in.h>
4075a17f3cSagc #include <netinet/tcp.h>
4175a17f3cSagc #include <netdb.h>
4275a17f3cSagc
4375a17f3cSagc #define MY_FLAGS ISNS_FLAG_REPLACE_REG
4475a17f3cSagc
4575a17f3cSagc
4675a17f3cSagc /**********************************************************************
4775a17f3cSagc **********************************************************************/
4875a17f3cSagc
4975a17f3cSagc uint32_t isns_id = 0; /* isns ID counter */
5075a17f3cSagc
5175a17f3cSagc ISNS_HANDLE isns_handle = ISNS_INVALID_HANDLE;
5275a17f3cSagc
5375a17f3cSagc /**********************************************************************
5475a17f3cSagc **********************************************************************/
5575a17f3cSagc
5675a17f3cSagc /*
5775a17f3cSagc * xlate_ip
5875a17f3cSagc * Support routine to translate binary IP into string form for storage in
5975a17f3cSagc * target object. Handles IPv6 and IPv4 formats.
6075a17f3cSagc *
6175a17f3cSagc * Parameters:
6275a17f3cSagc * dest the destination string
6375a17f3cSagc * data the source (from iSNS address field)
6475a17f3cSagc *
6575a17f3cSagc * Returns: status
6675a17f3cSagc */
6775a17f3cSagc
6838a27f5aSagc static void
xlate_ip(uint8_t * dest,size_t size,void * data)69f7720048Schristos xlate_ip(uint8_t *dest, size_t size, void *data)
7075a17f3cSagc {
7175a17f3cSagc uint16_t *wdt = (uint16_t *) data;
7275a17f3cSagc size_t cc;
7375a17f3cSagc int i;
74f7720048Schristos char *dst = (char *)dest;
75f7720048Schristos char *dt = data;
7675a17f3cSagc
7775a17f3cSagc for (i = 0; i < 5 && !wdt[i]; i++) {
7875a17f3cSagc }
7975a17f3cSagc if (i == 5 && wdt[5] == 0xffff) {
80f7720048Schristos snprintf(dst, size, "%d.%d.%d.%d",
81f7720048Schristos dt[12], dt[13], dt[14], dt[15]);
8275a17f3cSagc } else {
8375a17f3cSagc for (cc = 0, i = 0; i < 7; i++) {
84f7720048Schristos cc += snprintf(&dst[cc], size - cc, "%x:", wdt[i]);
8575a17f3cSagc }
86f7720048Schristos snprintf(&dst[cc], size - cc, "%x", wdt[7]);
8775a17f3cSagc }
8875a17f3cSagc }
8975a17f3cSagc
9075a17f3cSagc
9175a17f3cSagc /*
9275a17f3cSagc * get_isns_target_info
9375a17f3cSagc * Support routine to query the server for the attributes of the given target.
9475a17f3cSagc *
9575a17f3cSagc * Parameters:
9675a17f3cSagc * TargetName The target name to query.
9775a17f3cSagc *
9875a17f3cSagc * Returns: status
9975a17f3cSagc */
10075a17f3cSagc
10138a27f5aSagc static uint32_t
get_isns_target_info(isns_t * isns,uint8_t * TargetName)10275a17f3cSagc get_isns_target_info(isns_t * isns, uint8_t * TargetName)
10375a17f3cSagc {
10475a17f3cSagc int retval;
10575a17f3cSagc ISNS_TRANS t;
10675a17f3cSagc uint32_t tag;
107f7720048Schristos uint32_t data_len;
10875a17f3cSagc void *data_p;
10975a17f3cSagc uint32_t u32;
11075a17f3cSagc struct timespec tout = { 5, 0 };
11175a17f3cSagc uint32_t status;
11275a17f3cSagc target_t *targ;
11375a17f3cSagc char name[ISCSI_STRING_LENGTH];
11475a17f3cSagc char alias[ISCSI_STRING_LENGTH];
11575a17f3cSagc iscsi_portal_address_t addr;
11675a17f3cSagc
117f7720048Schristos t = isns_new_trans(isns_handle, isnsp_DevAttrQry, MY_FLAGS);
118f7720048Schristos if (ISNS_INVALID_TRANS == t) {
119*6fea88c2Smlelstv DEB(10,("%s: get_targets iscsi_new_trans failed", __func__));
12075a17f3cSagc return ISCSID_STATUS_NO_RESOURCES;
12175a17f3cSagc }
12275a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)isns->reg_iscsi_name);
12375a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)TargetName);
12475a17f3cSagc
12575a17f3cSagc isns_add_tlv(t, isnst_Delimiter, 0, NULL);
12675a17f3cSagc
12775a17f3cSagc isns_add_tlv(t, isnst_iSCSIName, 0, NULL); /* 32: name */
12875a17f3cSagc isns_add_tlv(t, isnst_iSCSINodeType, 0, NULL); /* 33: node type */
12975a17f3cSagc isns_add_tlv(t, isnst_iSCSIAlias, 0, NULL); /* 34: alias */
13075a17f3cSagc /* ToDo: get security attributes... */
13175a17f3cSagc /* isns_add_tlv (t, isnst_PortalSecBmap, 0, NULL); */
13275a17f3cSagc /*tag=27: security bitmap */
13375a17f3cSagc
13475a17f3cSagc retval = isns_send_trans(t, &tout, &status);
135*6fea88c2Smlelstv DEB(9, ("isns_send_trans called, returns %d, status %d", retval, status));
13675a17f3cSagc if (retval) {
137*6fea88c2Smlelstv DEB(10,("iSNS Attribute Query failed, rc = %d", retval));
13875a17f3cSagc isns_free_trans(t);
13975a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
14075a17f3cSagc }
14175a17f3cSagc /* First is target name (the one we put in), ignore */
14275a17f3cSagc if (isns_get_tlv(t, ISNS_TLV_FIRST, &tag, &data_len, &data_p)) {
143*6fea88c2Smlelstv DEB(10,("iSNS Attribute Query returned nothing"));
14475a17f3cSagc isns_free_trans(t);
14575a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
14675a17f3cSagc }
14775a17f3cSagc if (tag != isnst_iSCSIName) {
148*6fea88c2Smlelstv DEB(10,("iSNS Query returned bad type (tag = %d, length = %d)",
14975a17f3cSagc tag, data_len));
15075a17f3cSagc isns_free_trans(t);
15175a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
15275a17f3cSagc }
15375a17f3cSagc
15475a17f3cSagc isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p);
15575a17f3cSagc if (tag != isnst_Delimiter) {
156*6fea88c2Smlelstv DEB(10,("Attr Query Missing Delimiter (tag = %d, length = %d)",
15775a17f3cSagc tag, data_len));
15875a17f3cSagc isns_free_trans(t);
15975a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
16075a17f3cSagc }
16175a17f3cSagc
16275a17f3cSagc isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p);
16375a17f3cSagc if (tag != isnst_iSCSIName || !data_len || data_len >= ISCSI_STRING_LENGTH) {
164*6fea88c2Smlelstv DEB(10,("iSNS Query returned no or invalid name (tag = %d, "
165*6fea88c2Smlelstv "length = %d)", tag, data_len));
16675a17f3cSagc isns_free_trans(t);
16775a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
16875a17f3cSagc }
16975a17f3cSagc strlcpy(name, (char *) data_p, sizeof(name));
17075a17f3cSagc
17175a17f3cSagc isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p);
17275a17f3cSagc if (tag != isnst_iSCSINodeType || data_len != 4) {
173*6fea88c2Smlelstv DEB(10,("iSNS Query returned no or invalid node type (tag = %d, "
174*6fea88c2Smlelstv "length = %d)", tag, data_len));
17575a17f3cSagc isns_free_trans(t);
17675a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
17775a17f3cSagc }
17875a17f3cSagc u32 = ntohl(*((uint32_t *) data_p));
17975a17f3cSagc if (!(u32 & 1)) {
180*6fea88c2Smlelstv DEB(10,("iSNS Query returned bad type (type=%x, should be 1)", u32));
18175a17f3cSagc isns_free_trans(t);
18275a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
18375a17f3cSagc }
18475a17f3cSagc
18575a17f3cSagc isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p);
18675a17f3cSagc if (tag == isnst_iSCSIAlias) {
18775a17f3cSagc if (data_len >= ISCSI_STRING_LENGTH) {
188*6fea88c2Smlelstv DEB(10,("iSNS Query returned invalid alias (tag=%d, length=%d)",
18975a17f3cSagc tag, data_len));
19075a17f3cSagc isns_free_trans(t);
19175a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
19275a17f3cSagc }
19375a17f3cSagc strlcpy(alias, (char *) data_p, sizeof(alias));
19475a17f3cSagc isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p);
19575a17f3cSagc } else
19675a17f3cSagc alias[0] = 0;
19775a17f3cSagc
19875a17f3cSagc isns_free_trans(t);
19975a17f3cSagc
20075a17f3cSagc if (ISNS_INVALID_TRANS ==
20175a17f3cSagc (t = isns_new_trans(isns_handle, isnsp_DevAttrQry, MY_FLAGS))) {
202*6fea88c2Smlelstv DEB(10,("get_targets iscsi_new_trans failed"));
20375a17f3cSagc return ISCSID_STATUS_NO_RESOURCES;
20475a17f3cSagc }
20575a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)isns->reg_iscsi_name);
20675a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)TargetName);
20775a17f3cSagc
20875a17f3cSagc isns_add_tlv(t, isnst_Delimiter, 0, NULL);
20975a17f3cSagc
21075a17f3cSagc isns_add_tlv(t, isnst_PGiSCSIName, 0, NULL); /* 48: portal name */
21175a17f3cSagc isns_add_tlv(t, isnst_PGPortIPAddr, 0, NULL); /* 49: portal IP */
21275a17f3cSagc isns_add_tlv(t, isnst_PGPortIPPort, 0, NULL); /* 50: portal port */
21375a17f3cSagc isns_add_tlv(t, isnst_PGTag, 0, NULL); /* 51: group tag */
21475a17f3cSagc
21575a17f3cSagc retval = isns_send_trans(t, &tout, &status);
216*6fea88c2Smlelstv DEB(9, ("isns_send_trans called, returns %d, status %d", retval, status));
21775a17f3cSagc if (retval) {
218*6fea88c2Smlelstv DEB(10,("iSNS Attribute Query failed, rc = %d", retval));
21975a17f3cSagc isns_free_trans(t);
22075a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
22175a17f3cSagc }
22275a17f3cSagc /* First is target name (the one we put in), ignore */
22375a17f3cSagc if (isns_get_tlv(t, ISNS_TLV_FIRST, &tag, &data_len, &data_p)) {
224*6fea88c2Smlelstv DEB(10,("iSNS Attribute Query returned nothing"));
22575a17f3cSagc isns_free_trans(t);
22675a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
22775a17f3cSagc }
22875a17f3cSagc if (tag != isnst_iSCSIName) {
229*6fea88c2Smlelstv DEB(10,("iSNS Query2 returned bad name (tag = %d, length = %d)",
23075a17f3cSagc tag, data_len));
23175a17f3cSagc isns_free_trans(t);
23275a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
23375a17f3cSagc }
23475a17f3cSagc
23575a17f3cSagc isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p);
23675a17f3cSagc if (tag != isnst_Delimiter) {
237*6fea88c2Smlelstv DEB(10,("Attr Query2 Missing Delimiter (tag = %d, length = %d)",
23875a17f3cSagc tag, data_len));
23975a17f3cSagc isns_free_trans(t);
24075a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
24175a17f3cSagc }
24275a17f3cSagc
24375a17f3cSagc while (!isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p)) {
24475a17f3cSagc if (tag != isnst_PGiSCSIName || !data_len ||
24575a17f3cSagc data_len >= ISCSI_STRING_LENGTH) {
246*6fea88c2Smlelstv DEB(10,("iSNS Query2 returned no or invalid name (tag=%d, "
247*6fea88c2Smlelstv "length=%d)", tag, data_len));
24875a17f3cSagc isns_free_trans(t);
24975a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
25075a17f3cSagc }
25175a17f3cSagc strlcpy(name, (char *) data_p, sizeof(name));
25275a17f3cSagc
25375a17f3cSagc isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p);
25475a17f3cSagc if (tag != isnst_PGPortIPAddr || data_len != 16) {
255*6fea88c2Smlelstv DEB(10,("iSNS Query returned no or invalid address (tag=%d, "
256*6fea88c2Smlelstv "length=%d)", tag, data_len));
25775a17f3cSagc isns_free_trans(t);
25875a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
25975a17f3cSagc }
26075a17f3cSagc xlate_ip(addr.address, sizeof(addr.address), (uint8_t *) data_p);
26175a17f3cSagc
26275a17f3cSagc /* Now comes the port */
26375a17f3cSagc isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p);
26475a17f3cSagc if (tag != isnst_PGPortIPPort || data_len != 4) {
265*6fea88c2Smlelstv DEB(10,("iSNS Query returned no or invalid port (tag=%d, "
266*6fea88c2Smlelstv "length=%d)", tag, data_len));
26775a17f3cSagc isns_free_trans(t);
26875a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
26975a17f3cSagc }
27075a17f3cSagc u32 = ntohl(*((uint32_t *) data_p));
27175a17f3cSagc if (u32 & 0xffff0000) {
272*6fea88c2Smlelstv DEB(10,("iSNS Query returned invalid port (flags=%x, "
273*6fea88c2Smlelstv "should be 0)", u32 >> 16));
27475a17f3cSagc isns_free_trans(t);
27575a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
27675a17f3cSagc }
27775a17f3cSagc addr.port = (uint16_t) u32;
27875a17f3cSagc
27975a17f3cSagc /* And each target must have a group tag */
28075a17f3cSagc isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p);
28175a17f3cSagc if (tag != isnst_PGTag || (data_len && data_len != 4)) {
282*6fea88c2Smlelstv DEB(10,("iSNS Query returned no or invalid group tag (tag=%d, "
283*6fea88c2Smlelstv "length=%d)", tag, data_len));
28475a17f3cSagc isns_free_trans(t);
28575a17f3cSagc return ISCSID_STATUS_ISNS_SERVER_ERROR;
28675a17f3cSagc }
28775a17f3cSagc if (data_len) {
28875a17f3cSagc u32 = ntohl(*((uint32_t *) data_p));
28975a17f3cSagc addr.group_tag = (uint16_t) u32;
29075a17f3cSagc } else
29175a17f3cSagc addr.group_tag = 0;
29275a17f3cSagc
29375a17f3cSagc /* we have everything necessary to describe the target, add it. */
29475a17f3cSagc
295*6fea88c2Smlelstv DEB(2, ("Adding <%s>, IP <%s>, Port %d, Tag %d",
29675a17f3cSagc name, addr.address, addr.port, addr.group_tag));
29775a17f3cSagc
29875a17f3cSagc if ((targ = add_discovered_target((unsigned char *)name, &addr, PORTAL_TYPE_ISNS,
29975a17f3cSagc isns->entry.sid.id)) == NULL) {
30075a17f3cSagc isns_free_trans(t);
30175a17f3cSagc return ISCSID_STATUS_NO_RESOURCES;
30275a17f3cSagc }
30375a17f3cSagc
30475a17f3cSagc if (alias[0]) {
30575a17f3cSagc strlcpy((char *)targ->TargetAlias, alias,
30675a17f3cSagc sizeof(targ->TargetAlias));
30775a17f3cSagc }
30875a17f3cSagc }
30975a17f3cSagc isns_free_trans(t);
31075a17f3cSagc
31175a17f3cSagc return ISCSID_STATUS_SUCCESS;
31275a17f3cSagc }
31375a17f3cSagc
31475a17f3cSagc
31575a17f3cSagc /*
31675a17f3cSagc * deregister_isns_server
31775a17f3cSagc * Support routine to deregister the initiator from the iSNS server
31875a17f3cSagc *
31975a17f3cSagc * Parameters: The server descriptor
32075a17f3cSagc *
32175a17f3cSagc * Returns: status
32275a17f3cSagc */
32375a17f3cSagc
32475a17f3cSagc static uint32_t
deregister_isns_server(isns_t * isns)32575a17f3cSagc deregister_isns_server(isns_t * isns)
32675a17f3cSagc {
32775a17f3cSagc int retval;
32875a17f3cSagc ISNS_TRANS t;
32975a17f3cSagc struct timespec tout = { 5, 0 };
33075a17f3cSagc uint32_t status;
33175a17f3cSagc
33275a17f3cSagc /*
33375a17f3cSagc * Create transaction for deregistering with iSNS server
33475a17f3cSagc */
33575a17f3cSagc
33675a17f3cSagc if (ISNS_INVALID_TRANS == (t = isns_new_trans(isns_handle, isnsp_DevDereg,
33775a17f3cSagc MY_FLAGS))) {
338*6fea88c2Smlelstv DEB(10,("dereg_isns_server iscsi_new_trans failed"));
33975a17f3cSagc return ISCSID_STATUS_NO_RESOURCES;
34075a17f3cSagc }
34175a17f3cSagc
34275a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)isns->reg_iscsi_name);
34375a17f3cSagc isns_add_tlv(t, isnst_Delimiter, 0, NULL);
34475a17f3cSagc isns_add_string(t, isnst_EID, (char *)isns->reg_entity_id);
345f7720048Schristos isns_add_tlv(t, isnst_PortalIPAddr, (uint32_t)sizeof(isns->reg_ip_addr),
34675a17f3cSagc isns->reg_ip_addr);
347f7720048Schristos isns_add_tlv(t, isnst_PortalPort, (uint32_t)sizeof(isns->reg_ip_port),
34875a17f3cSagc &isns->reg_ip_port);
34975a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)isns->reg_iscsi_name);
35075a17f3cSagc
35175a17f3cSagc retval = isns_send_trans(t, &tout, &status);
352*6fea88c2Smlelstv DEB(9, ("DevAttrReg request returns %d, status %d", retval, status));
35375a17f3cSagc
35475a17f3cSagc isns_free_trans(t);
35575a17f3cSagc return ISCSID_STATUS_SUCCESS;
35675a17f3cSagc }
35775a17f3cSagc
35875a17f3cSagc /*
35975a17f3cSagc * register_isns_server
36075a17f3cSagc *
36175a17f3cSagc * Parameters: The server descriptor
36275a17f3cSagc *
36375a17f3cSagc * Returns: status
36475a17f3cSagc */
36575a17f3cSagc
36675a17f3cSagc
36775a17f3cSagc static uint32_t
register_isns_server(isns_t * isns)36875a17f3cSagc register_isns_server(isns_t * isns)
36975a17f3cSagc {
37075a17f3cSagc int retval;
37175a17f3cSagc ISNS_TRANS t;
37275a17f3cSagc uint32_t u32;
37375a17f3cSagc struct timespec tout = { 5, 0 };
37475a17f3cSagc uint32_t status;
37575a17f3cSagc
37675a17f3cSagc if (ISNS_INVALID_TRANS == (t = isns_new_trans(isns_handle, isnsp_DevAttrReg,
37775a17f3cSagc MY_FLAGS))) {
378*6fea88c2Smlelstv DEB(10,("iscsi_new_trans failed"));
37975a17f3cSagc return ISCSID_STATUS_NO_RESOURCES;
38075a17f3cSagc }
38175a17f3cSagc
38275a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)isns->reg_iscsi_name); /*tag=32 */
38375a17f3cSagc isns_add_tlv(t, isnst_Delimiter, 0, NULL);
38475a17f3cSagc isns_add_string(t, isnst_EID, (char *)isns->reg_entity_id);
38575a17f3cSagc u32 = htonl(2);
386f7720048Schristos isns_add_tlv(t, isnst_EntProtocol, (uint32_t)sizeof(u32), &u32);
387f7720048Schristos isns_add_tlv(t, isnst_PortalIPAddr, (uint32_t)sizeof(isns->reg_ip_addr),
38875a17f3cSagc isns->reg_ip_addr);
389f7720048Schristos isns_add_tlv(t, isnst_PortalPort, (uint32_t)sizeof(isns->reg_ip_port),
39075a17f3cSagc &isns->reg_ip_port);
39175a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)isns->reg_iscsi_name); /*tag=32 */
39275a17f3cSagc u32 = htonl(2);
393f7720048Schristos isns_add_tlv(t, isnst_iSCSINodeType, (uint32_t)sizeof(u32), &u32);
39475a17f3cSagc /*tag=33 (node type = intiator) */
39575a17f3cSagc
39675a17f3cSagc retval = isns_send_trans(t, &tout, &status);
397*6fea88c2Smlelstv DEB(9, ("DevAttrReg request returns %d, status %d", retval, status));
39875a17f3cSagc isns_free_trans(t);
39975a17f3cSagc
40075a17f3cSagc if (retval || status)
40175a17f3cSagc return ISCSID_STATUS_ISNS_ERROR;
40275a17f3cSagc
40375a17f3cSagc return ISCSID_STATUS_SUCCESS;
40475a17f3cSagc }
40575a17f3cSagc
40675a17f3cSagc
40775a17f3cSagc /*
40875a17f3cSagc * get_registration_info
40975a17f3cSagc *
41075a17f3cSagc * Parameters: The server descriptor
41175a17f3cSagc *
41275a17f3cSagc * Returns: status
41375a17f3cSagc */
41475a17f3cSagc
41575a17f3cSagc
41675a17f3cSagc static uint32_t
get_registration_info(isns_t * isns)41775a17f3cSagc get_registration_info(isns_t * isns)
41875a17f3cSagc {
41975a17f3cSagc struct sockaddr_storage sa;
42075a17f3cSagc unsigned n;
42175a17f3cSagc
42275a17f3cSagc strlcpy((char *)isns->reg_iscsi_name, (char *)node_name.InitiatorName,
42375a17f3cSagc sizeof(isns->reg_iscsi_name));
42475a17f3cSagc strlcpy((char *)isns->reg_entity_id, (char *)node_name.InitiatorAlias,
42575a17f3cSagc sizeof(isns->reg_entity_id));
42675a17f3cSagc
42775a17f3cSagc /*Get our source IP and port numbers */
42875a17f3cSagc n = sizeof(sa);
429f7720048Schristos if (getsockname(isns->sock, (struct sockaddr *)(void *)&sa, &n)) {
430*6fea88c2Smlelstv DEB(10,("Getsockname returned error %d", errno));
43175a17f3cSagc return ISCSID_STATUS_GENERAL_ERROR;
43275a17f3cSagc }
43375a17f3cSagc switch (sa.ss_family) {
43475a17f3cSagc case AF_INET:
43575a17f3cSagc {
436f7720048Schristos struct sockaddr_in *si =
437f7720048Schristos (struct sockaddr_in *)(void *)&sa;
438f7720048Schristos uint32_t *u32 = (uint32_t *)(void *)isns->reg_ip_addr;
43975a17f3cSagc
44075a17f3cSagc u32[0] = u32[1] = 0;
44175a17f3cSagc u32[2] = htonl(0xffff);
44275a17f3cSagc u32[3] = htonl(si->sin_addr.s_addr);
44375a17f3cSagc isns->reg_ip_port = htons(si->sin_port);
44475a17f3cSagc }
44575a17f3cSagc break;
44675a17f3cSagc
44775a17f3cSagc case AF_INET6:
44875a17f3cSagc {
449f7720048Schristos struct sockaddr_in6 *si =
450f7720048Schristos (struct sockaddr_in6 *)(void *) &sa;
45175a17f3cSagc
45275a17f3cSagc memcpy(isns->reg_ip_addr, &si->sin6_addr,
45375a17f3cSagc sizeof(isns->reg_ip_addr));
45475a17f3cSagc isns->reg_ip_port = htons(si->sin6_port);
45575a17f3cSagc }
45675a17f3cSagc break;
45775a17f3cSagc
45875a17f3cSagc default:
459*6fea88c2Smlelstv DEB(10,("Getsockname returned unknown address family: %d",
46075a17f3cSagc sa.ss_family));
46175a17f3cSagc return ISCSID_STATUS_GENERAL_ERROR;
46275a17f3cSagc }
46375a17f3cSagc return ISCSID_STATUS_SUCCESS;
46475a17f3cSagc }
46575a17f3cSagc
46675a17f3cSagc
46775a17f3cSagc /*
46875a17f3cSagc * iscsi_isns_serverconn - given a set of server address, try connecting
46975a17f3cSagc *
47075a17f3cSagc * Parameters: The descriptor for the iSNS server to query
47175a17f3cSagc *
47275a17f3cSagc * Returns: status
47375a17f3cSagc */
47475a17f3cSagc
47575a17f3cSagc static uint32_t
iscsi_isns_serverconn(isns_t * isns)47675a17f3cSagc iscsi_isns_serverconn(isns_t * isns)
47775a17f3cSagc {
47875a17f3cSagc int sock = -1;
47975a17f3cSagc char port[16];
48075a17f3cSagc struct addrinfo hints;
48175a17f3cSagc struct addrinfo *ai, *addr;
48275a17f3cSagc int retval;
48375a17f3cSagc
48475a17f3cSagc /*
48575a17f3cSagc * Initialize the iSNS library if it needs it
48675a17f3cSagc */
48775a17f3cSagc
48875a17f3cSagc if (isns_handle == ISNS_INVALID_HANDLE) {
48975a17f3cSagc if ((retval = isns_init(&isns_handle, 0)) != 0) {
49075a17f3cSagc /*Couldn't initialize the iSNS library */
491*6fea88c2Smlelstv DEB(10,("isns_init failed with code %d", retval));
49275a17f3cSagc isns_handle = ISNS_INVALID_HANDLE;
49375a17f3cSagc return ISCSID_STATUS_GENERAL_ERROR;
49475a17f3cSagc }
49575a17f3cSagc }
49675a17f3cSagc
49775a17f3cSagc /*
49875a17f3cSagc * Find the server address from the iSNS server list entry,
49975a17f3cSagc * and try to connect to the iSNS server
50075a17f3cSagc */
50175a17f3cSagc
50275a17f3cSagc snprintf(port, sizeof(port), "%d", (isns->port) ? isns->port : ISCSI_DEFAULT_ISNS_PORT);
50375a17f3cSagc memset(&hints, 0, sizeof(hints));
50475a17f3cSagc hints.ai_family = PF_UNSPEC;
50575a17f3cSagc hints.ai_socktype = SOCK_STREAM;
50675a17f3cSagc hints.ai_protocol = IPPROTO_TCP;
50775a17f3cSagc
50875a17f3cSagc retval = getaddrinfo((char *)isns->address, port, &hints, &ai);
50975a17f3cSagc if (retval) {
510*6fea88c2Smlelstv DEB(10,("getaddrinfo failed with code %d (%s)",
51175a17f3cSagc retval, gai_strerror(retval)));
51275a17f3cSagc return ISCSID_STATUS_GENERAL_ERROR;
51375a17f3cSagc }
51475a17f3cSagc
51575a17f3cSagc for (addr = ai; addr != NULL; addr = addr->ai_next) {
516f7720048Schristos sock = socket(addr->ai_family, addr->ai_socktype,
517f7720048Schristos addr->ai_protocol);
51875a17f3cSagc
519f7720048Schristos if (sock == -1) {
520*6fea88c2Smlelstv DEB(10,("%s: socket call FAILED!", __func__));
52175a17f3cSagc freeaddrinfo(ai);
522f7720048Schristos return (uint32_t)-1;
52375a17f3cSagc }
52475a17f3cSagc
525af909e15Smlelstv if (connect(sock, addr->ai_addr, addr->ai_addrlen) != -1)
52675a17f3cSagc break;
52775a17f3cSagc
528*6fea88c2Smlelstv DEB(1, ("%s: connect call FAILED!", __func__));
52975a17f3cSagc close(sock);
53075a17f3cSagc sock = -1;
53175a17f3cSagc }
53275a17f3cSagc
53375a17f3cSagc if (addr == NULL) {
534*6fea88c2Smlelstv DEB(10,("%s: couldn't connect!", __func__));
53575a17f3cSagc freeaddrinfo(ai);
53675a17f3cSagc return ISCSID_STATUS_GENERAL_ERROR;
53775a17f3cSagc }
53875a17f3cSagc
53975a17f3cSagc if (isns_add_servercon(isns_handle, sock, addr)) {
540*6fea88c2Smlelstv DEB(10,("%s: FAILED!", __func__));
54175a17f3cSagc close(sock);
54275a17f3cSagc freeaddrinfo(ai);
54375a17f3cSagc return ISCSID_STATUS_GENERAL_ERROR;
54475a17f3cSagc }
54575a17f3cSagc
54675a17f3cSagc freeaddrinfo(ai);
54775a17f3cSagc isns->sock = sock;
54875a17f3cSagc
54975a17f3cSagc if ((retval = get_registration_info(isns)) != 0) {
55075a17f3cSagc return retval;
55175a17f3cSagc }
55275a17f3cSagc
55375a17f3cSagc deregister_isns_server(isns);
55475a17f3cSagc
55575a17f3cSagc return register_isns_server(isns);
55675a17f3cSagc }
55775a17f3cSagc
55875a17f3cSagc
55975a17f3cSagc /*
56075a17f3cSagc * update_isns_server_info
56175a17f3cSagc * Support routine to query the specified iSNS server for all targets
56275a17f3cSagc * Called from add_isns_server and refresh_isns_server
56375a17f3cSagc *
56475a17f3cSagc * Parameters: The descriptor for the iSNS server to query
56575a17f3cSagc *
56675a17f3cSagc * Returns: status
56775a17f3cSagc */
56875a17f3cSagc
56975a17f3cSagc
57075a17f3cSagc static uint32_t
update_isns_server_info(isns_t * isns)57175a17f3cSagc update_isns_server_info(isns_t * isns)
57275a17f3cSagc {
57375a17f3cSagc int retval;
57475a17f3cSagc ISNS_TRANS t;
57575a17f3cSagc uint32_t tag;
576f7720048Schristos uint32_t data_len;
57775a17f3cSagc void *data_p;
57875a17f3cSagc uint32_t u32;
57975a17f3cSagc struct timespec tout = { 5, 0 };
58075a17f3cSagc uint32_t status;
58175a17f3cSagc uint8_t TargetName[ISCSI_STRING_LENGTH];
58275a17f3cSagc
58375a17f3cSagc
584*6fea88c2Smlelstv DEB(9, ("update_isns_server_info for iSNS %s", isns->address));
58575a17f3cSagc
58675a17f3cSagc if (isns->sock < 0) {
58775a17f3cSagc if ((status = iscsi_isns_serverconn(isns)) != 0) {
58875a17f3cSagc /*We couldn't connect to the iSNS server */
589*6fea88c2Smlelstv DEB(9, ("update_isns_server_info iscsi_isns_serverconn failed"));
59075a17f3cSagc return status;
59175a17f3cSagc }
59275a17f3cSagc }
59375a17f3cSagc
59475a17f3cSagc for (TargetName[0] = 0;;) {
59575a17f3cSagc if (ISNS_INVALID_TRANS == (t = isns_new_trans(isns_handle,
59675a17f3cSagc isnsp_DevGetNext, MY_FLAGS))) {
597*6fea88c2Smlelstv DEB(10,("update_isns_server_info iscsi_new_trans failed"));
59875a17f3cSagc return ISCSID_STATUS_NO_RESOURCES;
59975a17f3cSagc }
60075a17f3cSagc
60175a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)node_name.InitiatorName);
60275a17f3cSagc
60375a17f3cSagc if (TargetName[0])
60475a17f3cSagc isns_add_string(t, isnst_iSCSIName, (char *)TargetName);
60575a17f3cSagc else
60675a17f3cSagc isns_add_tlv(t, isnst_iSCSIName, 0, NULL);
60775a17f3cSagc
60875a17f3cSagc isns_add_tlv(t, isnst_Delimiter, 0, NULL);
60975a17f3cSagc isns_add_tlv(t, isnst_iSCSINodeType, 0, NULL);
61075a17f3cSagc
61175a17f3cSagc if ((retval = isns_send_trans(t, &tout, &status)) != 0) {
612*6fea88c2Smlelstv DEB(10,("isns_send_trans returns rc %d, status %d",
61375a17f3cSagc retval, status));
61475a17f3cSagc isns_free_trans(t);
61575a17f3cSagc break;
61675a17f3cSagc }
61775a17f3cSagc if (status) {
618*6fea88c2Smlelstv DEB(9, ("DevGetNext Status = %d", status));
61975a17f3cSagc break;
62075a17f3cSagc }
62175a17f3cSagc
62275a17f3cSagc if (isns_get_tlv(t, ISNS_TLV_FIRST, &tag, &data_len, &data_p)) {
623*6fea88c2Smlelstv DEB(10,("No TLV in DevGetNext response!"));
62475a17f3cSagc isns_free_trans(t);
62575a17f3cSagc break;
62675a17f3cSagc }
62775a17f3cSagc /* We need the name, or there's nothing left to do */
62875a17f3cSagc
62975a17f3cSagc if (tag != isnst_iSCSIName || !data_len ||
63075a17f3cSagc data_len >= ISCSI_STRING_LENGTH) {
631*6fea88c2Smlelstv DEB(10,("iSNS GetNextDev returned no or invalid name (tag=%d, "
632*6fea88c2Smlelstv "length=%d)", tag, data_len));
63375a17f3cSagc isns_free_trans(t);
63475a17f3cSagc break;
63575a17f3cSagc }
63675a17f3cSagc strlcpy((char *)TargetName, (char *) data_p, sizeof(TargetName));
63775a17f3cSagc
63875a17f3cSagc /* We must get at least the node type, and it must be a target */
63975a17f3cSagc if (isns_get_tlv(t, ISNS_TLV_NEXT, &tag, &data_len, &data_p)) {
640*6fea88c2Smlelstv DEB(10,("iSNS GetDevNext did not return node type"));
64175a17f3cSagc isns_free_trans(t);
64275a17f3cSagc break;
64375a17f3cSagc }
64475a17f3cSagc if (tag == isnst_Delimiter && isns_get_tlv(t, ISNS_TLV_NEXT, &tag,
64575a17f3cSagc &data_len, &data_p)) {
646*6fea88c2Smlelstv DEB(10,("iSNS GetDevNext did not return node type (past delim)"));
64775a17f3cSagc isns_free_trans(t);
64875a17f3cSagc break;
64975a17f3cSagc }
65075a17f3cSagc if (tag != isnst_iSCSINodeType || data_len != 4) {
651*6fea88c2Smlelstv DEB(10,("iSNS Query returned no or invalid node type (tag=%d, "
652*6fea88c2Smlelstv "length=%d)", tag, data_len));
65375a17f3cSagc isns_free_trans(t);
65475a17f3cSagc break;
65575a17f3cSagc }
65675a17f3cSagc u32 = ntohl(*((uint32_t *) data_p));
65775a17f3cSagc isns_free_trans(t);
65875a17f3cSagc
65975a17f3cSagc if (u32 & 1)
66075a17f3cSagc get_isns_target_info(isns, TargetName);
66175a17f3cSagc }
66275a17f3cSagc
663*6fea88c2Smlelstv DEB(9, ("update_isns_server_info returning SUCCESS!"));
66475a17f3cSagc return ISCSID_STATUS_SUCCESS;
66575a17f3cSagc }
66675a17f3cSagc
66775a17f3cSagc
66875a17f3cSagc /**********************************************************************
66975a17f3cSagc **********************************************************************/
67075a17f3cSagc
67175a17f3cSagc /*
67275a17f3cSagc * create_isns:
67375a17f3cSagc * Create an isns structure and initialize it.
67475a17f3cSagc *
67575a17f3cSagc * Parameter:
67675a17f3cSagc * name The iSNS server name
67775a17f3cSagc *
67875a17f3cSagc * Returns: Pointer to isns structure, NULL if allocation failed.
67975a17f3cSagc */
68075a17f3cSagc
68138a27f5aSagc static isns_t *
create_isns(iscsid_add_isns_server_req_t * req)68275a17f3cSagc create_isns(iscsid_add_isns_server_req_t * req)
68375a17f3cSagc {
68475a17f3cSagc isns_t *isns;
68575a17f3cSagc
686*6fea88c2Smlelstv DEB(9, ("Create iSNS %s", req->address));
68775a17f3cSagc
68875a17f3cSagc if ((isns = calloc(1, sizeof(*isns))) == NULL)
68975a17f3cSagc return NULL;
69075a17f3cSagc
69175a17f3cSagc for (isns_id++; !isns_id || find_isns_id(isns_id) != NULL;)
69275a17f3cSagc isns_id++;
69375a17f3cSagc
69475a17f3cSagc isns->entry.sid.id = isns_id;
69575a17f3cSagc strlcpy((char *)isns->entry.sid.name, (char *)req->name, sizeof(isns->entry.sid.name));
69675a17f3cSagc strlcpy((char *)isns->address, (char *)req->address, sizeof(isns->address));
69775a17f3cSagc isns->port = req->port;
69875a17f3cSagc isns->sock = -1;
69975a17f3cSagc
70075a17f3cSagc return isns;
70175a17f3cSagc }
70275a17f3cSagc
70375a17f3cSagc
70475a17f3cSagc /*
70575a17f3cSagc * add_isns_server
70675a17f3cSagc * Adds an iSNS server to the server list.
70775a17f3cSagc * This command will add the address of an iSNS server to the list
70875a17f3cSagc * of iSNS servers that the discovery daemon queries to discover targets.
70975a17f3cSagc * The daemon will then register itself with the iSNS server,
71075a17f3cSagc * and query the iSNS server for the list of targets.
71175a17f3cSagc * The discovered targets will be added to the list of target portals.
71275a17f3cSagc * The response contains the ID of the iSNS server.
71375a17f3cSagc *
71475a17f3cSagc * Parameter: The parameter contains the address of the server.
71575a17f3cSagc *
71675a17f3cSagc * Returns: Nothing
71775a17f3cSagc * The response parameter is an iscsid_add_isns_server_rsp_t
71875a17f3cSagc * containing:
71975a17f3cSagc * server_id = Unique ID for the iSNS server
72075a17f3cSagc */
72175a17f3cSagc
72275a17f3cSagc void
add_isns_server(iscsid_add_isns_server_req_t * req,iscsid_response_t ** prsp,int * prsp_temp)72375a17f3cSagc add_isns_server(iscsid_add_isns_server_req_t * req, iscsid_response_t ** prsp,
72475a17f3cSagc int *prsp_temp)
72575a17f3cSagc {
72675a17f3cSagc iscsid_response_t *rsp = *prsp;
72775a17f3cSagc iscsid_add_isns_server_rsp_t *res;
72875a17f3cSagc isns_t *isns;
72975a17f3cSagc
730*6fea88c2Smlelstv DEB(9, ("IN add_isns_server"));
73175a17f3cSagc
73275a17f3cSagc /*
73375a17f3cSagc * Make a response
73475a17f3cSagc */
73575a17f3cSagc
73675a17f3cSagc rsp = make_rsp(sizeof(iscsid_add_isns_server_rsp_t), prsp, prsp_temp);
73775a17f3cSagc if (rsp == NULL) {
738*6fea88c2Smlelstv DEB(9, ("OUT add_isns_server: make_rsp FAILED"));
73975a17f3cSagc return;
74075a17f3cSagc }
74175a17f3cSagc
742f7720048Schristos res = (iscsid_add_isns_server_rsp_t *)(void *)rsp->parameter;
74375a17f3cSagc
74475a17f3cSagc /*
74575a17f3cSagc * First, allocate the isns server structure to put on the list
74675a17f3cSagc */
74775a17f3cSagc
74875a17f3cSagc isns = create_isns(req);
74975a17f3cSagc if (isns == NULL) {
75075a17f3cSagc rsp->status = ISCSID_STATUS_NO_RESOURCES;
751*6fea88c2Smlelstv DEB(9, ("OUT add_isns_server: create_isns FAILED!"));
75275a17f3cSagc return;
75375a17f3cSagc }
75475a17f3cSagc
75575a17f3cSagc TAILQ_INSERT_TAIL(&list[ISNS_LIST].list, &isns->entry, link);
75675a17f3cSagc list[ISNS_LIST].num_entries++;
75775a17f3cSagc res->server_id = isns->entry.sid.id;
75875a17f3cSagc
759*6fea88c2Smlelstv DEB(9, ("OUT add_isns_server: server_id = %d, name = %s",
76075a17f3cSagc isns->entry.sid.id, isns->address));
76175a17f3cSagc
76275a17f3cSagc /*
76375a17f3cSagc * Now try to connect to the iSNS server...
76475a17f3cSagc */
76575a17f3cSagc
76675a17f3cSagc update_isns_server_info(isns);
76775a17f3cSagc }
76875a17f3cSagc
76975a17f3cSagc
77075a17f3cSagc /*
77175a17f3cSagc * get_isns_server
77275a17f3cSagc * Returns the address of the iSNS server with the specified ID
77375a17f3cSagc *
77475a17f3cSagc * Parameters: The unique ID of the server
77575a17f3cSagc *
77675a17f3cSagc * Returns: The status returned by the driver
77775a17f3cSagc * The response parameter contains the iSNS server address as a
77875a17f3cSagc * zero-terminated UTF-8 string
77975a17f3cSagc */
78075a17f3cSagc
78175a17f3cSagc void
get_isns_server(iscsid_sym_id_t * preq,iscsid_response_t ** prsp,int * prsp_temp)78275a17f3cSagc get_isns_server(iscsid_sym_id_t * preq, iscsid_response_t ** prsp,
78375a17f3cSagc int *prsp_temp)
78475a17f3cSagc {
78575a17f3cSagc iscsid_response_t *rsp = *prsp;
78675a17f3cSagc iscsid_get_isns_server_rsp_t *res;
78775a17f3cSagc isns_t *isns;
78875a17f3cSagc
789*6fea88c2Smlelstv DEB(9, ("IN get_isns_server"));
79075a17f3cSagc isns = find_isns(preq);
79175a17f3cSagc if (isns == NULL) {
79275a17f3cSagc rsp->status = ISCSID_STATUS_INVALID_ISNS_ID;
793*6fea88c2Smlelstv DEB(9, ("OUT get_isns_server: find_isns FAILED!"));
79475a17f3cSagc return;
79575a17f3cSagc }
79675a17f3cSagc
79775a17f3cSagc rsp = make_rsp(sizeof(iscsid_get_isns_server_rsp_t), prsp, prsp_temp);
79875a17f3cSagc if (rsp == NULL) {
799*6fea88c2Smlelstv DEB(9, ("OUT get_isns_server: make_rsp FAILED!"));
80075a17f3cSagc return;
80175a17f3cSagc }
802f7720048Schristos res = (iscsid_get_isns_server_rsp_t *)(void *)rsp->parameter;
80375a17f3cSagc
804f7720048Schristos strlcpy((char *)res->address, (char *)isns->address,
805f7720048Schristos sizeof(res->address));
80675a17f3cSagc res->port = isns->port;
80775a17f3cSagc res->server_id = isns->entry.sid;
808*6fea88c2Smlelstv DEB(9, ("OUT get_isns_server: id = %d, address = %s",
80975a17f3cSagc res->server_id.id, res->address));
81075a17f3cSagc }
81175a17f3cSagc
81275a17f3cSagc
81375a17f3cSagc /*
81475a17f3cSagc * slp_find_isns_servers
81575a17f3cSagc */
81675a17f3cSagc
81775a17f3cSagc /* More Here Later... */
81875a17f3cSagc
81975a17f3cSagc
82075a17f3cSagc /*
82175a17f3cSagc * refresh_isns_server
82275a17f3cSagc * Query the specified iSNS servers for the list of targets.
82375a17f3cSagc *
82475a17f3cSagc * Parameters:
82575a17f3cSagc * id Server ID
82675a17f3cSagc *
82775a17f3cSagc * Returns: Status
82875a17f3cSagc */
82975a17f3cSagc
83075a17f3cSagc uint32_t
refresh_isns_server(uint32_t id)83175a17f3cSagc refresh_isns_server(uint32_t id)
83275a17f3cSagc {
83375a17f3cSagc uint32_t rc;
83475a17f3cSagc isns_t *isns;
83575a17f3cSagc generic_entry_t *curr;
83675a17f3cSagc generic_entry_t *next;
83775a17f3cSagc
83875a17f3cSagc isns = find_isns_id(id);
83975a17f3cSagc if (isns == NULL)
84075a17f3cSagc return ISCSID_STATUS_INVALID_ISNS_ID;
84175a17f3cSagc
84275a17f3cSagc TAILQ_FOREACH(curr, &list[PORTAL_LIST].list, link) {
843f7720048Schristos portal_t *p = (portal_t *)(void *)curr;
844f7720048Schristos if (p->portaltype == PORTAL_TYPE_ISNS && p->discoveryid == id)
845f7720048Schristos p->portaltype = PORTAL_TYPE_REFRESHING;
84675a17f3cSagc }
84775a17f3cSagc
84875a17f3cSagc rc = update_isns_server_info(isns);
84975a17f3cSagc
85075a17f3cSagc /*
85175a17f3cSagc * Go through our list of portals and look for ones
85275a17f3cSagc * that are still marked for refreshing.
85375a17f3cSagc * These are ones that are no longer there and should be removed.
85475a17f3cSagc */
85575a17f3cSagc
85675a17f3cSagc for (curr = TAILQ_FIRST(&list[PORTAL_LIST].list); curr != NULL;
85775a17f3cSagc curr = next) {
858f7720048Schristos portal_t *p = (portal_t *)(void *)curr;
85975a17f3cSagc next = TAILQ_NEXT(curr, link);
860f7720048Schristos if (p->portaltype == PORTAL_TYPE_REFRESHING)
861f7720048Schristos delete_portal(p, TRUE);
86275a17f3cSagc }
86375a17f3cSagc
86475a17f3cSagc return rc;
86575a17f3cSagc }
86675a17f3cSagc
86775a17f3cSagc
86875a17f3cSagc /*
86975a17f3cSagc * remove_isns_server
87075a17f3cSagc * Removed an iSNS server.
87175a17f3cSagc * This does not remove the discovered targets from the list.
87275a17f3cSagc *
87375a17f3cSagc * Parameters: The iscid_remove_isns_req_t structure containing:
87475a17f3cSagc * server_id = unique ID of server to remove
87575a17f3cSagc *
87675a17f3cSagc * Returns: The status returned.
87775a17f3cSagc */
87875a17f3cSagc
87975a17f3cSagc uint32_t
remove_isns_server(iscsid_sym_id_t * preq)88075a17f3cSagc remove_isns_server(iscsid_sym_id_t * preq)
88175a17f3cSagc {
88275a17f3cSagc generic_entry_t *curr;
88375a17f3cSagc isns_t *isns;
88475a17f3cSagc uint32_t id;
88575a17f3cSagc
88675a17f3cSagc isns = find_isns(preq);
88775a17f3cSagc if (isns == NULL)
88875a17f3cSagc return ISCSID_STATUS_INVALID_ISNS_ID;
88975a17f3cSagc
89075a17f3cSagc /*Deregister with the iSNS server. */
89175a17f3cSagc /*Ignore any errors during deregistration... */
89275a17f3cSagc if (isns->sock >= 0) {
89375a17f3cSagc deregister_isns_server(isns);
89475a17f3cSagc close(isns->sock);
89575a17f3cSagc }
89675a17f3cSagc
89775a17f3cSagc TAILQ_REMOVE(&list[ISNS_LIST].list, &isns->entry, link);
89875a17f3cSagc list[ISNS_LIST].num_entries--;
89975a17f3cSagc
90075a17f3cSagc id = isns->entry.sid.id;
90175a17f3cSagc free(isns);
90275a17f3cSagc
90375a17f3cSagc TAILQ_FOREACH(curr, &list[PORTAL_LIST].list, link) {
904f7720048Schristos portal_t *p = (portal_t *)(void *)curr;
905f7720048Schristos if (p->portaltype == PORTAL_TYPE_ISNS && p->discoveryid == id)
906f7720048Schristos p->discoveryid = 0; /* mark deleted */
90775a17f3cSagc }
90875a17f3cSagc
90975a17f3cSagc return ISCSID_STATUS_SUCCESS;
91075a17f3cSagc }
91175a17f3cSagc
91275a17f3cSagc
91375a17f3cSagc /*
91475a17f3cSagc Deregister all isns servers on daemon termination
91575a17f3cSagc */
91675a17f3cSagc
91775a17f3cSagc void
dereg_all_isns_servers(void)91875a17f3cSagc dereg_all_isns_servers(void)
91975a17f3cSagc {
92075a17f3cSagc generic_list_t *plist;
92175a17f3cSagc generic_entry_t *curr;
92275a17f3cSagc
92375a17f3cSagc plist = &list[ISNS_LIST].list;
92475a17f3cSagc TAILQ_FOREACH(curr, plist, link)
925f7720048Schristos deregister_isns_server((isns_t *)(void *)curr);
92675a17f3cSagc }
92775a17f3cSagc
92875a17f3cSagc #endif
92975a17f3cSagc
930