* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2012, 2016, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
*/
#define DEBUG_SUBSYSTEM S_LNET
+
+#include <linux/ctype.h>
+#include <linux/inetdevice.h>
#include <linux/nsproxy.h>
#include <net/net_namespace.h>
#include <lnet/lib-lnet.h>
list_for_each(tmp, nilist) {
ni = list_entry(tmp, struct lnet_ni, ni_netlist);
- if (ni->ni_interfaces[0] != NULL &&
- strncmp(ni->ni_interfaces[0], iface, strlen(iface)) == 0)
+ if (ni->ni_interface != NULL &&
+ strncmp(ni->ni_interface, iface, strlen(iface)) == 0)
return false;
}
return true;
}
-
-/* check that the NI is unique to the interfaces with in the same NI.
- * This is only a consideration if use_tcp_bonding is set */
-static bool
-lnet_ni_unique_ni(char *iface_list[LNET_INTERFACES_NUM], char *iface)
-{
- int i;
- for (i = 0; i < LNET_INTERFACES_NUM; i++) {
- if (iface_list[i] != NULL &&
- strncmp(iface_list[i], iface, strlen(iface)) == 0)
- return false;
- }
-
- return true;
-}
-
static bool
in_array(__u32 *array, __u32 size, __u32 value)
{
if (cpts == NULL) {
/* there is an NI which will exist on all CPTs */
if (net->net_cpts != NULL)
- LIBCFS_FREE(net->net_cpts, sizeof(*net->net_cpts) *
- net->net_ncpts);
+ CFS_FREE_PTR_ARRAY(net->net_cpts, net->net_ncpts);
net->net_cpts = NULL;
net->net_ncpts = LNET_CPT_NUMBER;
return 0;
}
if (net->net_cpts == NULL) {
- LIBCFS_ALLOC(net->net_cpts, sizeof(*net->net_cpts) * ncpts);
+ CFS_ALLOC_PTR_ARRAY(net->net_cpts, ncpts);
if (net->net_cpts == NULL)
return -ENOMEM;
- memcpy(net->net_cpts, cpts, ncpts);
+ memcpy(net->net_cpts, cpts, ncpts * sizeof(*net->net_cpts));
net->net_ncpts = ncpts;
return 0;
}
- LIBCFS_ALLOC(added_cpts, sizeof(*added_cpts) * LNET_CPT_NUMBER);
+ CFS_ALLOC_PTR_ARRAY(added_cpts, LNET_CPT_NUMBER);
if (added_cpts == NULL)
return -ENOMEM;
__u32 *array = NULL, *loc;
__u32 total_entries = j + net->net_ncpts;
- LIBCFS_ALLOC(array, sizeof(*net->net_cpts) * total_entries);
+ CFS_ALLOC_PTR_ARRAY(array, total_entries);
if (array == NULL) {
rc = -ENOMEM;
goto failed;
}
- memcpy(array, net->net_cpts, net->net_ncpts);
+ memcpy(array, net->net_cpts,
+ net->net_ncpts * sizeof(*net->net_cpts));
loc = array + net->net_ncpts;
- memcpy(loc, added_cpts, j);
+ memcpy(loc, added_cpts, j * sizeof(*net->net_cpts));
- LIBCFS_FREE(net->net_cpts, sizeof(*net->net_cpts) *
- net->net_ncpts);
+ CFS_FREE_PTR_ARRAY(net->net_cpts, net->net_ncpts);
net->net_ncpts = total_entries;
net->net_cpts = array;
}
failed:
- LIBCFS_FREE(added_cpts, sizeof(*added_cpts) * LNET_CPT_NUMBER);
+ CFS_FREE_PTR_ARRAY(added_cpts, LNET_CPT_NUMBER);
return rc;
}
* CPTs which the remaining NIs are associated with.
*/
if (net->net_cpts != NULL) {
- LIBCFS_FREE(net->net_cpts,
- sizeof(*net->net_cpts) * net->net_ncpts);
+ CFS_FREE_PTR_ARRAY(net->net_cpts, net->net_ncpts);
net->net_cpts = NULL;
}
* accross CPT lines.
*/
if (net->net_cpts != NULL) {
- LIBCFS_FREE(net->net_cpts,
- sizeof(*net->net_cpts) *
- net->net_ncpts);
+ CFS_FREE_PTR_ARRAY(net->net_cpts,
+ net->net_ncpts);
net->net_cpts = NULL;
net->net_ncpts = LNET_CPT_NUMBER;
}
void
lnet_ni_free(struct lnet_ni *ni)
{
- int i;
-
lnet_net_remove_cpts(ni->ni_cpts, ni->ni_ncpts, ni->ni_net);
if (ni->ni_refs != NULL)
if (ni->ni_cpts != NULL)
cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts);
- for (i = 0; i < LNET_INTERFACES_NUM &&
- ni->ni_interfaces[i] != NULL; i++) {
- LIBCFS_FREE(ni->ni_interfaces[i],
- strlen(ni->ni_interfaces[i]) + 1);
+ if (ni->ni_interface != NULL) {
+ LIBCFS_FREE(ni->ni_interface,
+ strlen(ni->ni_interface) + 1);
}
/* release reference to net namespace */
}
if (net->net_cpts != NULL)
- LIBCFS_FREE(net->net_cpts,
- sizeof(*net->net_cpts) * net->net_ncpts);
+ CFS_FREE_PTR_ARRAY(net->net_cpts, net->net_ncpts);
LIBCFS_FREE(net, sizeof(*net));
}
{
struct lnet_net *net;
- if (!lnet_net_unique(net_id, net_list, NULL)) {
- CERROR("Duplicate net %s. Ignore\n",
- libcfs_net2str(net_id));
- return NULL;
+ if (!lnet_net_unique(net_id, net_list, &net)) {
+ CDEBUG(D_NET, "Returning duplicate net %p %s\n", net,
+ libcfs_net2str(net->net_id));
+ return net;
}
LIBCFS_ALLOC(net, sizeof(*net));
INIT_LIST_HEAD(&net->net_ni_list);
INIT_LIST_HEAD(&net->net_ni_added);
INIT_LIST_HEAD(&net->net_ni_zombie);
+ INIT_LIST_HEAD(&net->net_rtr_pref_nids);
+ spin_lock_init(&net->net_lock);
net->net_id = net_id;
- net->net_state = LNET_NET_STATE_INIT;
+ net->net_last_alive = ktime_get_real_seconds();
+
+ net->net_sel_priority = LNET_MAX_SELECTION_PRIORITY;
/* initialize global paramters to undefiend */
net->net_tunables.lct_peer_timeout = -1;
static int
lnet_ni_add_interface(struct lnet_ni *ni, char *iface)
{
- int niface = 0;
+ size_t iface_len = strlen(iface) + 1;
if (ni == NULL)
return -ENOMEM;
- if (!lnet_ni_unique_ni(ni->ni_interfaces, iface))
- return -EINVAL;
-
- /* Allocate a separate piece of memory and copy
- * into it the string, so we don't have
- * a depencency on the tokens string. This way we
- * can free the tokens at the end of the function.
- * The newly allocated ni_interfaces[] can be
- * freed when freeing the NI */
- while (niface < LNET_INTERFACES_NUM &&
- ni->ni_interfaces[niface] != NULL)
- niface++;
-
- if (niface >= LNET_INTERFACES_NUM) {
- LCONSOLE_ERROR_MSG(0x115, "Too many interfaces "
- "for net %s\n",
- libcfs_net2str(LNET_NIDNET(ni->ni_nid)));
+ if (ni->ni_interface != NULL) {
+ LCONSOLE_ERROR_MSG(0x115, "%s: interface %s already set for net %s: rc = %d\n",
+ iface, ni->ni_interface,
+ libcfs_net2str(LNET_NIDNET(ni->ni_nid)),
+ -EINVAL);
return -EINVAL;
}
- LIBCFS_ALLOC(ni->ni_interfaces[niface],
- strlen(iface) + 1);
+ /* Allocate memory for the interface, so the code parsing input into
+ * tokens and adding interfaces can free the input safely.
+ * ni->ni_interface is freed in lnet_ni_free().
+ */
+ LIBCFS_ALLOC(ni->ni_interface, iface_len);
- if (ni->ni_interfaces[niface] == NULL) {
- CERROR("Can't allocate net interface name\n");
+ if (ni->ni_interface == NULL) {
+ CERROR("%s: cannot allocate net interface name: rc = %d\n",
+ iface, -ENOMEM);
return -ENOMEM;
}
- strncpy(ni->ni_interfaces[niface], iface,
- strlen(iface) + 1);
+ strscpy(ni->ni_interface, iface, iface_len);
return 0;
}
}
spin_lock_init(&ni->ni_lock);
- INIT_LIST_HEAD(&ni->ni_cptlist);
INIT_LIST_HEAD(&ni->ni_netlist);
+ INIT_LIST_HEAD(&ni->ni_recovery);
+ LNetInvalidateMDHandle(&ni->ni_ping_mdh);
ni->ni_refs = cfs_percpt_alloc(lnet_cpt_table(),
sizeof(*ni->ni_refs[0]));
if (ni->ni_refs == NULL)
ni->ni_nid = LNET_MKNID(net->net_id, 0);
/* Store net namespace in which current ni is being created */
- if (current->nsproxy->net_ns != NULL)
+ if (current->nsproxy && current->nsproxy->net_ns)
ni->ni_net_ns = get_net(current->nsproxy->net_ns);
else
- ni->ni_net_ns = NULL;
+ ni->ni_net_ns = get_net(&init_net);
- ni->ni_last_alive = ktime_get_real_seconds();
ni->ni_state = LNET_NI_STATE_INIT;
+ ni->ni_sel_priority = LNET_MAX_SELECTION_PRIORITY;
list_add_tail(&ni->ni_netlist, &net->net_ni_added);
/*
LASSERT(rc <= LNET_CPT_NUMBER);
if (rc == LNET_CPT_NUMBER) {
- LIBCFS_FREE(ni->ni_cpts, rc * sizeof(ni->ni_cpts[0]));
+ CFS_FREE_PTR_ARRAY(ni->ni_cpts, rc);
ni->ni_cpts = NULL;
}
ni->ni_ncpts = LNET_CPT_NUMBER;
} else {
size_t array_size = ncpts * sizeof(ni->ni_cpts[0]);
- LIBCFS_ALLOC(ni->ni_cpts, array_size);
+
+ CFS_ALLOC_PTR_ARRAY(ni->ni_cpts, ncpts);
if (ni->ni_cpts == NULL)
goto failed;
memcpy(ni->ni_cpts, cpts, array_size);
* nilist.
*/
int
-lnet_parse_networks(struct list_head *netlist, char *networks,
- bool use_tcp_bonding)
+lnet_parse_networks(struct list_head *netlist, const char *networks)
{
struct cfs_expr_list *net_el = NULL;
struct cfs_expr_list *ni_el = NULL;
* At this point the name is properly terminated.
*/
net_id = libcfs_str2net(name);
- if (net_id == LNET_NIDNET(LNET_NID_ANY)) {
+ if (net_id == LNET_NET_ANY) {
LCONSOLE_ERROR_MSG(0x113,
"Unrecognised network type\n");
str = name;
if (IS_ERR_OR_NULL(net))
goto failed;
- if (!nistr ||
- (use_tcp_bonding && LNET_NETTYP(net_id) == SOCKLND)) {
+ if (!nistr) {
/*
* No interface list was specified, allocate a
* ni using the defaults.
goto failed_syntax;
}
- if (use_tcp_bonding &&
- LNET_NETTYP(net->net_id) == SOCKLND) {
- rc = lnet_ni_add_interface(ni, name);
- if (rc != 0)
- goto failed;
- } else {
- ni = lnet_ni_alloc(net, ni_el, name);
- if (IS_ERR_OR_NULL(ni))
- goto failed;
- }
+ ni = lnet_ni_alloc(net, ni_el, name);
+ if (IS_ERR_OR_NULL(ni))
+ goto failed;
if (ni_el) {
if (ni_el != net_el) {
}
}
-void
-lnet_print_text_bufs(struct list_head *tbs)
-{
- struct list_head *tmp;
- struct lnet_text_buf *ltb;
-
- list_for_each(tmp, tbs) {
- ltb = list_entry(tmp, struct lnet_text_buf, ltb_list);
-
- CDEBUG(D_WARNING, "%s\n", ltb->ltb_text);
- }
-
- CDEBUG(D_WARNING, "%d allocated\n", lnet_tbnob);
-}
-
static int
-lnet_str2tbs_sep(struct list_head *tbs, char *str)
+lnet_str2tbs_sep(struct list_head *tbs, const char *str)
{
- struct list_head pending;
- char *sep;
- int nob;
- int i;
- struct lnet_text_buf *ltb;
-
- INIT_LIST_HEAD(&pending);
+ LIST_HEAD(pending);
+ const char *sep;
+ int nob;
+ int i;
+ struct lnet_text_buf *ltb;
/* Split 'str' into separate commands */
for (;;) {
lnet_str2tbs_expand(struct list_head *tbs, char *str)
{
char num[16];
- struct list_head pending;
+ LIST_HEAD(pending);
char *sep;
char *sep2;
char *parsed;
int nob;
int scanned;
- INIT_LIST_HEAD(&pending);
-
sep = strchr(str, '[');
if (sep == NULL) /* nothing to expand */
return 0;
}
static int
-lnet_parse_route (char *str, int *im_a_router)
+lnet_parse_route(char *str, int *im_a_router)
{
/* static scratch buffer OK (single threaded) */
- static char cmd[LNET_SINGLE_TEXTBUF_NOB];
+ static char cmd[LNET_SINGLE_TEXTBUF_NOB];
- struct list_head nets;
- struct list_head gateways;
+ LIST_HEAD(nets);
+ LIST_HEAD(gateways);
struct list_head *tmp1;
struct list_head *tmp2;
- __u32 net;
- lnet_nid_t nid;
- struct lnet_text_buf *ltb;
- int rc;
- char *sep;
- char *token = str;
- int ntokens = 0;
- int myrc = -1;
- __u32 hops;
- int got_hops = 0;
- unsigned int priority = 0;
-
- INIT_LIST_HEAD(&gateways);
- INIT_LIST_HEAD(&nets);
+ __u32 net;
+ lnet_nid_t nid;
+ struct lnet_text_buf *ltb;
+ int rc;
+ char *sep;
+ char *token = str;
+ int ntokens = 0;
+ int myrc = -1;
+ __u32 hops;
+ int got_hops = 0;
+ unsigned int priority = 0;
/* save a copy of the string for error messages */
strncpy(cmd, str, sizeof(cmd));
if (ntokens == 1) {
net = libcfs_str2net(ltb->ltb_text);
- if (net == LNET_NIDNET(LNET_NID_ANY) ||
+ if (net == LNET_NET_ANY ||
LNET_NETTYP(net) == LOLND)
goto token_error;
} else {
goto token_error;
nid = libcfs_str2nid(ltb->ltb_text);
- if (nid == LNET_NID_ANY ||
- LNET_NETTYP(LNET_NIDNET(nid)) == LOLND)
+ if (nid == LNET_NID_ANY || nid == LNET_NID_LO_0)
goto token_error;
}
}
list_for_each(tmp1, &nets) {
ltb = list_entry(tmp1, struct lnet_text_buf, ltb_list);
net = libcfs_str2net(ltb->ltb_text);
- LASSERT (net != LNET_NIDNET(LNET_NID_ANY));
+ LASSERT(net != LNET_NET_ANY);
list_for_each(tmp2, &gateways) {
ltb = list_entry(tmp2, struct lnet_text_buf, ltb_list);
continue;
}
- rc = lnet_add_route(net, hops, nid, priority);
+ rc = lnet_add_route(net, hops, nid, priority, 1);
if (rc != 0 && rc != -EEXIST && rc != -EHOSTUNREACH) {
CERROR("Can't create route "
"to %s via %s\n",
}
int
-lnet_parse_routes (char *routes, int *im_a_router)
+lnet_parse_routes(const char *routes, int *im_a_router)
{
- struct list_head tbs;
- int rc = 0;
+ LIST_HEAD(tbs);
+ int rc = 0;
*im_a_router = 0;
- INIT_LIST_HEAD(&tbs);
-
if (lnet_str2tbs_sep(&tbs, routes) < 0) {
CERROR("Error parsing routes\n");
rc = -EINVAL;
static int
lnet_match_network_token(char *token, int len, __u32 *ipaddrs, int nip)
{
- struct list_head list = LIST_HEAD_INIT(list);
+ LIST_HEAD(list);
int rc;
int i;
*sep++ = 0;
net = lnet_netspec2net(tb->ltb_text);
- if (net == LNET_NIDNET(LNET_NID_ANY)) {
+ if (net == LNET_NET_ANY) {
lnet_syntax("ip2nets", source, offset,
strlen(tb->ltb_text));
return -EINVAL;
}
static int
-lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
+lnet_match_networks(const char **networksp, const char *ip2nets,
+ __u32 *ipaddrs, int nip)
{
static char networks[LNET_SINGLE_TEXTBUF_NOB];
static char source[LNET_SINGLE_TEXTBUF_NOB];
- struct list_head raw_entries;
- struct list_head matched_nets;
- struct list_head current_nets;
+ LIST_HEAD(raw_entries);
+ LIST_HEAD(matched_nets);
+ LIST_HEAD(current_nets);
struct list_head *t;
struct list_head *t2;
struct lnet_text_buf *tb;
- struct lnet_text_buf *tb2;
- __u32 net1;
- __u32 net2;
int len;
int count;
- int dup;
int rc;
- INIT_LIST_HEAD(&raw_entries);
if (lnet_str2tbs_sep(&raw_entries, ip2nets) < 0) {
CERROR("Error parsing ip2nets\n");
LASSERT(lnet_tbnob == 0);
return -EINVAL;
}
- INIT_LIST_HEAD(&matched_nets);
- INIT_LIST_HEAD(¤t_nets);
networks[0] = 0;
count = 0;
len = 0;
if (rc < 0)
break;
- dup = 0;
- list_for_each(t, ¤t_nets) {
- tb = list_entry(t, struct lnet_text_buf, ltb_list);
- net1 = lnet_netspec2net(tb->ltb_text);
- LASSERT(net1 != LNET_NIDNET(LNET_NID_ANY));
-
- list_for_each(t2, &matched_nets) {
- tb2 = list_entry(t2, struct lnet_text_buf,
- ltb_list);
- net2 = lnet_netspec2net(tb2->ltb_text);
- LASSERT(net2 != LNET_NIDNET(LNET_NID_ANY));
-
- if (net1 == net2) {
- dup = 1;
- break;
- }
- }
-
- if (dup)
- break;
- }
-
- if (dup) {
- lnet_free_text_bufs(¤t_nets);
- continue;
- }
-
list_for_each_safe(t, t2, ¤t_nets) {
tb = list_entry(t, struct lnet_text_buf, ltb_list);
- list_del(&tb->ltb_list);
- list_add_tail(&tb->ltb_list, &matched_nets);
+ list_move_tail(&tb->ltb_list, &matched_nets);
- len += snprintf(networks + len, sizeof(networks) - len,
- "%s%s", (len == 0) ? "" : ",",
- tb->ltb_text);
+ len += scnprintf(networks + len, sizeof(networks) - len,
+ "%s%s", (len == 0) ? "" : ",",
+ tb->ltb_text);
if (len >= sizeof(networks)) {
CERROR("Too many matched networks\n");
return count;
}
-static void
-lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip)
-{
- LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
-}
-
-static int
-lnet_ipaddr_enumerate (__u32 **ipaddrsp)
+int lnet_inet_enumerate(struct lnet_inetdev **dev_list, struct net *ns)
{
- int up;
- __u32 netmask;
- __u32 *ipaddrs;
- __u32 *ipaddrs2;
- int nip;
- char **ifnames;
- int nif = lnet_ipif_enumerate(&ifnames);
- int i;
- int rc;
-
- if (nif <= 0)
- return nif;
-
- LIBCFS_ALLOC(ipaddrs, nif * sizeof(*ipaddrs));
- if (ipaddrs == NULL) {
- CERROR("Can't allocate ipaddrs[%d]\n", nif);
- lnet_ipif_free_enumeration(ifnames, nif);
- return -ENOMEM;
- }
-
- for (i = nip = 0; i < nif; i++) {
- if (!strcmp(ifnames[i], "lo"))
+ struct lnet_inetdev *ifaces = NULL;
+ struct net_device *dev;
+ int nalloc = 0;
+ int nip = 0;
+ DECLARE_CONST_IN_IFADDR(ifa);
+
+ rtnl_lock();
+ for_each_netdev(ns, dev) {
+ int flags = dev_get_flags(dev);
+ struct in_device *in_dev;
+ int node_id;
+ int cpt;
+
+ if (flags & IFF_LOOPBACK) /* skip the loopback IF */
continue;
- rc = lnet_ipif_query(ifnames[i], &up,
- &ipaddrs[nip], &netmask);
- if (rc != 0) {
- CWARN("Can't query interface %s: %d\n",
- ifnames[i], rc);
+ if (!(flags & IFF_UP)) {
+ CWARN("lnet: Ignoring interface %s: it's down\n",
+ dev->name);
continue;
}
- if (!up) {
- CWARN("Ignoring interface %s: it's down\n",
- ifnames[i]);
+ in_dev = __in_dev_get_rtnl(dev);
+ if (!in_dev) {
+ CWARN("lnet: Interface %s has no IPv4 status.\n",
+ dev->name);
continue;
}
- nip++;
- }
-
- lnet_ipif_free_enumeration(ifnames, nif);
-
- if (nip == nif) {
- *ipaddrsp = ipaddrs;
- } else {
- if (nip > 0) {
- LIBCFS_ALLOC(ipaddrs2, nip * sizeof(*ipaddrs2));
- if (ipaddrs2 == NULL) {
- CERROR("Can't allocate ipaddrs[%d]\n", nip);
- nip = -ENOMEM;
- } else {
- memcpy(ipaddrs2, ipaddrs,
- nip * sizeof(*ipaddrs));
- *ipaddrsp = ipaddrs2;
- rc = nip;
+ node_id = dev_to_node(&dev->dev);
+ cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
+
+ in_dev_for_each_ifa_rtnl(ifa, in_dev) {
+ if (nip >= nalloc) {
+ struct lnet_inetdev *tmp;
+
+ nalloc += LNET_INTERFACES_NUM;
+ tmp = krealloc(ifaces, nalloc * sizeof(*tmp),
+ GFP_KERNEL);
+ if (!tmp) {
+ kfree(ifaces);
+ ifaces = NULL;
+ nip = -ENOMEM;
+ goto unlock_rtnl;
+ }
+ ifaces = tmp;
}
+
+ ifaces[nip].li_cpt = cpt;
+ ifaces[nip].li_flags = flags;
+ ifaces[nip].li_ipaddr = ntohl(ifa->ifa_local);
+ ifaces[nip].li_netmask = ntohl(ifa->ifa_mask);
+ strlcpy(ifaces[nip].li_name, ifa->ifa_label,
+ sizeof(ifaces[nip].li_name));
+ nip++;
}
- lnet_ipaddr_free_enumeration(ipaddrs, nif);
+ endfor_ifa(in_dev);
+ }
+unlock_rtnl:
+ rtnl_unlock();
+
+ if (nip == 0) {
+ CERROR("lnet: Can't find any usable interfaces, rc = -ENOENT\n");
+ nip = -ENOENT;
}
+
+ *dev_list = ifaces;
return nip;
}
+EXPORT_SYMBOL(lnet_inet_enumerate);
int
-lnet_parse_ip2nets (char **networksp, char *ip2nets)
+lnet_parse_ip2nets(const char **networksp, const char *ip2nets)
{
+ struct lnet_inetdev *ifaces = NULL;
__u32 *ipaddrs = NULL;
- int nip = lnet_ipaddr_enumerate(&ipaddrs);
+ int nip;
int rc;
+ int i;
+ if (current->nsproxy && current->nsproxy->net_ns)
+ nip = lnet_inet_enumerate(&ifaces, current->nsproxy->net_ns);
+ else
+ nip = lnet_inet_enumerate(&ifaces, &init_net);
if (nip < 0) {
- LCONSOLE_ERROR_MSG(0x117, "Error %d enumerating local IP "
- "interfaces for ip2nets to match\n", nip);
+ if (nip != -ENOENT) {
+ LCONSOLE_ERROR_MSG(0x117,
+ "Error %d enumerating local IP interfaces for ip2nets to match\n",
+ nip);
+ } else {
+ LCONSOLE_ERROR_MSG(0x118,
+ "No local IP interfaces for ip2nets to match\n");
+ }
return nip;
}
- if (nip == 0) {
- LCONSOLE_ERROR_MSG(0x118, "No local IP interfaces "
- "for ip2nets to match\n");
- return -ENOENT;
+ CFS_ALLOC_PTR_ARRAY(ipaddrs, nip);
+ if (!ipaddrs) {
+ rc = -ENOMEM;
+ CERROR("lnet: Can't allocate ipaddrs[%d], rc = %d\n",
+ nip, rc);
+ goto out_free_addrs;
}
- rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
- lnet_ipaddr_free_enumeration(ipaddrs, nip);
+ for (i = 0; i < nip; i++)
+ ipaddrs[i] = ifaces[i].li_ipaddr;
+ rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
if (rc < 0) {
LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc);
- return rc;
- }
-
- if (rc == 0) {
+ } else if (rc == 0) {
LCONSOLE_ERROR_MSG(0x11a, "ip2nets does not match "
"any local IP interfaces\n");
- return -ENOENT;
+ rc = -ENOENT;
}
-
- return 0;
+ CFS_FREE_PTR_ARRAY(ipaddrs, nip);
+out_free_addrs:
+ kfree(ifaces);
+ return rc > 0 ? 0 : rc;
}