summaryrefslogtreecommitdiff
path: root/libopeniscsiusr
diff options
context:
space:
mode:
authorLee Duncan <lduncan@suse.com>2021-09-01 12:21:18 -0700
committerLee Duncan <lduncan@suse.com>2021-09-01 12:37:11 -0700
commit76350316de38abcd42afd3276249d577a0a66bec (patch)
treebb226ed2f58ad959113472c77e7680383f14af73 /libopeniscsiusr
parentcb39fb559a4046284925eb3a7457ed00b1e7b6fe (diff)
downloadopen-iscsi-76350316de38abcd42afd3276249d577a0a66bec.tar.gz
Handle IPv6 interfaces correctly.
For IPv6 interface files (in iscsi/ifaces), assume the interface uses IPv4 unless it has "ipv6" in the name. Also, when creating interface files, name them ending with "ipv6.N" or "ipv4.N", where "N" is the interface number (normally zero). This was being done in one place, and this commit makes sure all places that create interface files use this convention. Note that iscsiadm cannot determine if the interface file is IPv6 vs IPv4 from the contents because of the way it processes those files: it creates a template of "legal" values, then processes the file. But it needs to know IPv4 vs IPv6 when creating the template.
Diffstat (limited to 'libopeniscsiusr')
-rw-r--r--libopeniscsiusr/idbm.c18
-rw-r--r--libopeniscsiusr/iface.c29
2 files changed, 39 insertions, 8 deletions
diff --git a/libopeniscsiusr/idbm.c b/libopeniscsiusr/idbm.c
index 0910c63..b2524ed 100644
--- a/libopeniscsiusr/idbm.c
+++ b/libopeniscsiusr/idbm.c
@@ -303,7 +303,7 @@ struct idbm_rec {
enum modify_mode can_modify;
};
-static void _idbm_node_rec_link(struct iscsi_node *node, struct idbm_rec *recs);
+static void _idbm_node_rec_link(struct iscsi_node *node, struct idbm_rec *recs, const char *iface_name);
int _idbm_lock(struct iscsi_context *ctx)
{
@@ -394,6 +394,10 @@ static int _idbm_iface_rec_link(struct iscsi_iface *iface,
struct idbm_rec *recs, int num)
{
int init_num = num;
+
+ if (strstr(iface->name, "ipv6"))
+ iface->is_ipv6 = true;
+
if (init_num == 0)
_rec_str(IFACE_ISCSINAME, recs, iface, name, IDBM_SHOW, num,
_CANNOT_MODIFY);
@@ -587,7 +591,7 @@ void _idbm_node_print(struct iscsi_node *node, FILE *f, bool show_secret)
if (recs == NULL)
return;
- _idbm_node_rec_link(node, recs);
+ _idbm_node_rec_link(node, recs, NULL);
_idbm_recs_print(recs, f, show_secret ? IDBM_SHOW : IDBM_MASKED);
_idbm_recs_free(recs);
}
@@ -977,7 +981,7 @@ static struct int_list_tbl chap_algs[] = {
{ "SHA3-256", ISCSI_AUTH_CHAP_ALG_SHA3_256 },
};
-static void _idbm_node_rec_link(struct iscsi_node *node, struct idbm_rec *recs)
+static void _idbm_node_rec_link(struct iscsi_node *node, struct idbm_rec *recs, const char *iface_name)
{
int num = 0;
@@ -990,6 +994,10 @@ static void _idbm_node_rec_link(struct iscsi_node *node, struct idbm_rec *recs)
_rec_bool(NODE_LEADING_LOGIN, recs, node, leading_login, IDBM_SHOW,
num, _CAN_MODIFY);
+ /* use the interface name passed in, if any */
+ if (iface_name)
+ strncpy((*node).iface.name, iface_name, ISCSI_MAX_IFACE_LEN);
+
/*
* Note: because we do not add the iface.iscsi_ifacename to
* sysfs iscsiadm does some weird matching. We can change the iface
@@ -1153,7 +1161,7 @@ int _idbm_node_get(struct iscsi_context *ctx, const char *target_name,
recs = _idbm_recs_alloc();
_alloc_null_check(ctx, recs, rc, out);
- _idbm_node_rec_link(*node, recs);
+ _idbm_node_rec_link(*node, recs, iface_name);
_good(_idbm_recs_read(ctx, recs, conf_path), rc, out);
@@ -1180,8 +1188,6 @@ int _idbm_node_get(struct iscsi_context *ctx, const char *target_name,
(*node)->conn.port);
}
-
-
out:
if (rc != LIBISCSI_OK) {
iscsi_node_free(*node);
diff --git a/libopeniscsiusr/iface.c b/libopeniscsiusr/iface.c
index 4d573fb..63f9c61 100644
--- a/libopeniscsiusr/iface.c
+++ b/libopeniscsiusr/iface.c
@@ -86,6 +86,29 @@ _iscsi_getter_func_gen(iscsi_iface, port_state, const char *);
_iscsi_getter_func_gen(iscsi_iface, port_speed, const char *);
_iscsi_getter_func_gen(iscsi_iface, name, const char *);
+/*
+ * ipv6 address strings will have at least two colons
+ *
+ * NOTE: does NOT validate the IP address
+ */
+static bool lib_ipaddr_is_ipv6(struct iscsi_context *ctx, char *ipaddr)
+{
+ char *first_colon, *second_colon;
+ bool res = false;
+
+ if (ipaddr) {
+ first_colon = strchr(ipaddr, ':');
+ if (first_colon) {
+ second_colon = strchr(first_colon+1, ':');
+ if (second_colon &&
+ (second_colon != first_colon))
+ res = true;
+ }
+ }
+ _debug(ctx, "ipaddr=\"%s\" -> %u", ipaddr, res);
+ return res;
+}
+
int _iscsi_iface_get_from_sysfs(struct iscsi_context *ctx, uint32_t host_id,
uint32_t sid, char *iface_kern_id,
struct iscsi_iface **iface)
@@ -203,8 +226,10 @@ int _iscsi_iface_get_from_sysfs(struct iscsi_context *ctx, uint32_t host_id,
if (bound_by_hwaddr)
snprintf((*iface)->name,
sizeof((*iface)->name)/sizeof(char),
- "%s.%s", (*iface)->transport_name,
- (*iface)->hwaddress);
+ "%s.%s.%s.%u", (*iface)->transport_name,
+ (*iface)->hwaddress,
+ lib_ipaddr_is_ipv6(ctx, (*iface)->ipaddress) ? "ipv6" : "ipv4",
+ (*iface)->iface_num);
}
if (strcmp((*iface)->name, "") == 0) {