diff options
author | Lee Duncan <lduncan@suse.com> | 2021-09-01 12:21:18 -0700 |
---|---|---|
committer | Lee Duncan <lduncan@suse.com> | 2021-09-01 12:37:11 -0700 |
commit | 76350316de38abcd42afd3276249d577a0a66bec (patch) | |
tree | bb226ed2f58ad959113472c77e7680383f14af73 /libopeniscsiusr | |
parent | cb39fb559a4046284925eb3a7457ed00b1e7b6fe (diff) | |
download | open-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.c | 18 | ||||
-rw-r--r-- | libopeniscsiusr/iface.c | 29 |
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) { |