*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
*
* GPL HEADER END
*/
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2014, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
return str;
}
-static int libcfs_lo_str2addr(const char *str, int nob, __u32 *addr);
-static void libcfs_ip_addr2str(__u32 addr, char *str, size_t size);
-static int libcfs_ip_str2addr(const char *str, int nob, __u32 *addr);
-static bool cfs_ip_is_contiguous(struct list_head *nidlist);
-static void cfs_ip_min_max(struct list_head *nidlist, __u32 *min, __u32 *max);
-static void libcfs_decnum_addr2str(__u32 addr, char *str, size_t size);
-static void libcfs_hexnum_addr2str(__u32 addr, char *str, size_t size);
-static int libcfs_num_str2addr(const char *str, int nob, __u32 *addr);
-static int libcfs_num_parse(char *str, int len, struct list_head *list);
-static int libcfs_num_match(__u32 addr, struct list_head *list);
-static int libcfs_num_addr_range_print(char *buffer, int count,
- struct list_head *list);
-static int libcfs_ip_addr_range_print(char *buffer, int count,
- struct list_head *list);
-static bool cfs_num_is_contiguous(struct list_head *nidlist);
-static void cfs_num_min_max(struct list_head *nidlist, __u32 *min, __u32 *max);
-
-struct netstrfns {
- __u32 nf_type;
- char *nf_name;
- char *nf_modname;
- void (*nf_addr2str)(__u32 addr, char *str, size_t size);
- int (*nf_str2addr)(const char *str, int nob, __u32 *addr);
- int (*nf_parse_addrlist)(char *str, int len,
- struct list_head *list);
- int (*nf_print_addrlist)(char *buffer, int count,
- struct list_head *list);
- int (*nf_match_addr)(__u32 addr, struct list_head *list);
- bool (*nf_is_contiguous)(struct list_head *nidlist);
- void (*nf_min_max)(struct list_head *nidlist, __u32 *min_nid,
- __u32 *max_nid);
-};
-
-static struct netstrfns libcfs_netstrfns[] = {
- {/* .nf_type */ LOLND,
- /* .nf_name */ "lo",
- /* .nf_modname */ "klolnd",
- /* .nf_addr2str */ libcfs_decnum_addr2str,
- /* .nf_str2addr */ libcfs_lo_str2addr,
- /* .nf_parse_addr*/ libcfs_num_parse,
- /* .nf_print_addrlist*/ libcfs_num_addr_range_print,
- /* .nf_match_addr*/ libcfs_num_match,
- /* .nf_is_contiguous */ cfs_num_is_contiguous,
- /* .nf_min_max */ cfs_num_min_max},
- {/* .nf_type */ SOCKLND,
- /* .nf_name */ "tcp",
- /* .nf_modname */ "ksocklnd",
- /* .nf_addr2str */ libcfs_ip_addr2str,
- /* .nf_str2addr */ libcfs_ip_str2addr,
- /* .nf_parse_addrlist*/ cfs_ip_addr_parse,
- /* .nf_print_addrlist*/ libcfs_ip_addr_range_print,
- /* .nf_match_addr*/ cfs_ip_addr_match,
- /* .nf_is_contiguous */ cfs_ip_is_contiguous,
- /* .nf_min_max */ cfs_ip_min_max},
- {/* .nf_type */ O2IBLND,
- /* .nf_name */ "o2ib",
- /* .nf_modname */ "ko2iblnd",
- /* .nf_addr2str */ libcfs_ip_addr2str,
- /* .nf_str2addr */ libcfs_ip_str2addr,
- /* .nf_parse_addrlist*/ cfs_ip_addr_parse,
- /* .nf_print_addrlist*/ libcfs_ip_addr_range_print,
- /* .nf_match_addr*/ cfs_ip_addr_match,
- /* .nf_is_contiguous */ cfs_ip_is_contiguous,
- /* .nf_min_max */ cfs_ip_min_max},
- {/* .nf_type */ CIBLND,
- /* .nf_name */ "cib",
- /* .nf_modname */ "kciblnd",
- /* .nf_addr2str */ libcfs_ip_addr2str,
- /* .nf_str2addr */ libcfs_ip_str2addr,
- /* .nf_parse_addrlist*/ cfs_ip_addr_parse,
- /* .nf_print_addrlist*/ libcfs_ip_addr_range_print,
- /* .nf_match_addr*/ cfs_ip_addr_match,
- /* .nf_is_contiguous */ cfs_ip_is_contiguous,
- /* .nf_min_max */ cfs_ip_min_max},
- {/* .nf_type */ OPENIBLND,
- /* .nf_name */ "openib",
- /* .nf_modname */ "kopeniblnd",
- /* .nf_addr2str */ libcfs_ip_addr2str,
- /* .nf_str2addr */ libcfs_ip_str2addr,
- /* .nf_parse_addrlist*/ cfs_ip_addr_parse,
- /* .nf_print_addrlist*/ libcfs_ip_addr_range_print,
- /* .nf_match_addr*/ cfs_ip_addr_match,
- /* .nf_is_contiguous */ cfs_ip_is_contiguous,
- /* .nf_min_max */ cfs_ip_min_max},
- {/* .nf_type */ IIBLND,
- /* .nf_name */ "iib",
- /* .nf_modname */ "kiiblnd",
- /* .nf_addr2str */ libcfs_ip_addr2str,
- /* .nf_str2addr */ libcfs_ip_str2addr,
- /* .nf_parse_addrlist*/ cfs_ip_addr_parse,
- /* .nf_print_addrlist*/ libcfs_ip_addr_range_print,
- /* .nf_match_addr*/ cfs_ip_addr_match,
- /* .nf_is_contiguous */ cfs_ip_is_contiguous,
- /* .nf_min_max */ cfs_ip_min_max},
- {/* .nf_type */ VIBLND,
- /* .nf_name */ "vib",
- /* .nf_modname */ "kviblnd",
- /* .nf_addr2str */ libcfs_ip_addr2str,
- /* .nf_str2addr */ libcfs_ip_str2addr,
- /* .nf_parse_addrlist*/ cfs_ip_addr_parse,
- /* .nf_print_addrlist*/ libcfs_ip_addr_range_print,
- /* .nf_match_addr*/ cfs_ip_addr_match,
- /* .nf_is_contiguous */ cfs_ip_is_contiguous,
- /* .nf_min_max */ cfs_ip_min_max},
- {/* .nf_type */ RALND,
- /* .nf_name */ "ra",
- /* .nf_modname */ "kralnd",
- /* .nf_addr2str */ libcfs_ip_addr2str,
- /* .nf_str2addr */ libcfs_ip_str2addr,
- /* .nf_parse_addrlist*/ cfs_ip_addr_parse,
- /* .nf_print_addrlist*/ libcfs_ip_addr_range_print,
- /* .nf_match_addr*/ cfs_ip_addr_match,
- /* .nf_is_contiguous */ cfs_ip_is_contiguous,
- /* .nf_min_max */ cfs_ip_min_max},
- {/* .nf_type */ QSWLND,
- /* .nf_name */ "elan",
- /* .nf_modname */ "kqswlnd",
- /* .nf_addr2str */ libcfs_decnum_addr2str,
- /* .nf_str2addr */ libcfs_num_str2addr,
- /* .nf_parse_addrlist*/ libcfs_num_parse,
- /* .nf_print_addrlist*/ libcfs_num_addr_range_print,
- /* .nf_match_addr*/ libcfs_num_match,
- /* .nf_is_contiguous */ cfs_num_is_contiguous,
- /* .nf_min_max */ cfs_num_min_max},
- {/* .nf_type */ GMLND,
- /* .nf_name */ "gm",
- /* .nf_modname */ "kgmlnd",
- /* .nf_addr2str */ libcfs_hexnum_addr2str,
- /* .nf_str2addr */ libcfs_num_str2addr,
- /* .nf_parse_addrlist*/ libcfs_num_parse,
- /* .nf_print_addrlist*/ libcfs_num_addr_range_print,
- /* .nf_match_addr*/ libcfs_num_match,
- /* .nf_is_contiguous */ cfs_num_is_contiguous,
- /* .nf_min_max */ cfs_num_min_max},
- {/* .nf_type */ MXLND,
- /* .nf_name */ "mx",
- /* .nf_modname */ "kmxlnd",
- /* .nf_addr2str */ libcfs_ip_addr2str,
- /* .nf_str2addr */ libcfs_ip_str2addr,
- /* .nf_parse_addrlist*/ cfs_ip_addr_parse,
- /* .nf_print_addrlist*/ libcfs_ip_addr_range_print,
- /* .nf_match_addr*/ cfs_ip_addr_match,
- /* .nf_is_contiguous */ cfs_ip_is_contiguous,
- /* .nf_min_max */ cfs_ip_min_max},
- {/* .nf_type */ PTLLND,
- /* .nf_name */ "ptl",
- /* .nf_modname */ "kptllnd",
- /* .nf_addr2str */ libcfs_decnum_addr2str,
- /* .nf_str2addr */ libcfs_num_str2addr,
- /* .nf_parse_addrlist*/ libcfs_num_parse,
- /* .nf_print_addrlist*/ libcfs_num_addr_range_print,
- /* .nf_match_addr*/ libcfs_num_match,
- /* .nf_is_contiguous */ cfs_num_is_contiguous,
- /* .nf_min_max */ cfs_num_min_max},
- {/* .nf_type */ GNILND,
- /* .nf_name */ "gni",
- /* .nf_modname */ "kgnilnd",
- /* .nf_addr2str */ libcfs_decnum_addr2str,
- /* .nf_str2addr */ libcfs_num_str2addr,
- /* .nf_parse_addrlist*/ libcfs_num_parse,
- /* .nf_print_addrlist*/ libcfs_num_addr_range_print,
- /* .nf_match_addr*/ libcfs_num_match,
- /* .nf_is_contiguous */ cfs_num_is_contiguous,
- /* .nf_min_max */ cfs_num_min_max},
- {/* .nf_type */ GNIIPLND,
- /* .nf_name */ "gip",
- /* .nf_modname */ "kgnilnd",
- /* .nf_addr2str */ libcfs_ip_addr2str,
- /* .nf_str2addr */ libcfs_ip_str2addr,
- /* .nf_parse_addrlist*/ cfs_ip_addr_parse,
- /* .nf_print_addrlist*/ libcfs_ip_addr_range_print,
- /* .nf_match_addr*/ cfs_ip_addr_match,
- /* .nf_is_contiguous */ cfs_ip_is_contiguous,
- /* .nf_min_max */ cfs_ip_min_max},
- /* placeholder for net0 alias. It MUST BE THE LAST ENTRY */
- {/* .nf_type */ -1},
-};
-
-static const size_t libcfs_nnetstrfns =
- sizeof(libcfs_netstrfns)/sizeof(libcfs_netstrfns[0]);
-
static int
libcfs_lo_str2addr(const char *str, int nob, __u32 *addr)
{
return 0;
}
-static void
-libcfs_decnum_addr2str(__u32 addr, char *str, size_t size)
+int
+cfs_ip_addr_parse(char *str, int len, struct list_head *list)
{
- snprintf(str, size, "%u", addr);
+ struct cfs_expr_list *el;
+ struct cfs_lstr src;
+ int rc;
+ int i;
+
+ src.ls_str = str;
+ src.ls_len = len;
+ i = 0;
+
+ while (src.ls_str != NULL) {
+ struct cfs_lstr res;
+
+ if (!cfs_gettok(&src, '.', &res)) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ rc = cfs_expr_list_parse(res.ls_str, res.ls_len, 0, 255, &el);
+ if (rc != 0)
+ goto out;
+
+ list_add_tail(&el->el_link, list);
+ i++;
+ }
+
+ if (i == 4)
+ return 0;
+
+ rc = -EINVAL;
+out:
+ cfs_expr_list_free_list(list);
+
+ return rc;
+}
+
+static int
+libcfs_ip_addr_range_print(char *buffer, int count, struct list_head *list)
+{
+ int i = 0, j = 0;
+ struct cfs_expr_list *el;
+
+ list_for_each_entry(el, list, el_link) {
+ assert(j++ < 4);
+ if (i != 0)
+ i += snprintf(buffer + i, count - i, ".");
+ i += cfs_expr_list_print(buffer + i, count - i, el);
+ }
+ return i;
+}
+
+/**
+ * Matches address (\a addr) against address set encoded in \a list.
+ *
+ * \retval 1 if \a addr matches
+ * \retval 0 otherwise
+ */
+int
+cfs_ip_addr_match(__u32 addr, struct list_head *list)
+{
+ struct cfs_expr_list *el;
+ int i = 0;
+
+ list_for_each_entry_reverse(el, list, el_link) {
+ if (!cfs_expr_list_match(addr & 0xff, el))
+ return 0;
+ addr >>= 8;
+ i++;
+ }
+
+ return i == 4;
}
static void
-libcfs_hexnum_addr2str(__u32 addr, char *str, size_t size)
+libcfs_decnum_addr2str(__u32 addr, char *str, size_t size)
{
- snprintf(str, size, "0x%x", addr);
+ snprintf(str, size, "%u", addr);
}
static int
return 0;
}
+/**
+ * Nf_parse_addrlist method for networks using numeric addresses.
+ *
+ * Examples of such networks are gm and elan.
+ *
+ * \retval 0 if \a str parsed to numeric address
+ * \retval errno otherwise
+ */
+static int
+libcfs_num_parse(char *str, int len, struct list_head *list)
+{
+ struct cfs_expr_list *el;
+ int rc;
+
+ rc = cfs_expr_list_parse(str, len, 0, MAX_NUMERIC_VALUE, &el);
+ if (rc == 0)
+ list_add_tail(&el->el_link, list);
+
+ return rc;
+}
+
+static int
+libcfs_num_addr_range_print(char *buffer, int count, struct list_head *list)
+{
+ struct cfs_expr_list *el;
+ int i = 0, j = 0;
+
+ list_for_each_entry(el, list, el_link) {
+ assert(j++ < 1);
+ i += cfs_expr_list_print(buffer + i, count - i, el);
+ }
+ return i;
+}
+
+/*
+ * Nf_match_addr method for networks using numeric addresses
+ *
+ * \retval 1 on match
+ * \retval 0 otherwise
+ */
+static int
+libcfs_num_match(__u32 addr, struct list_head *numaddr)
+{
+ struct cfs_expr_list *el;
+
+ assert(!list_empty(numaddr));
+ el = list_entry(numaddr->next, struct cfs_expr_list, el_link);
+
+ return cfs_expr_list_match(addr, el);
+}
+
+static bool cfs_ip_is_contiguous(struct list_head *nidlist);
+static void cfs_ip_min_max(struct list_head *nidlist, __u32 *min, __u32 *max);
+static bool cfs_num_is_contiguous(struct list_head *nidlist);
+static void cfs_num_min_max(struct list_head *nidlist, __u32 *min, __u32 *max);
+
+static struct netstrfns libcfs_netstrfns[] = {
+ {
+ .nf_type = LOLND,
+ .nf_name = "lo",
+ .nf_modname = "klolnd",
+ .nf_addr2str = libcfs_decnum_addr2str,
+ .nf_str2addr = libcfs_lo_str2addr,
+ .nf_parse_addrlist = libcfs_num_parse,
+ .nf_print_addrlist = libcfs_num_addr_range_print,
+ .nf_match_addr = libcfs_num_match,
+ .nf_is_contiguous = cfs_num_is_contiguous,
+ .nf_min_max = cfs_num_min_max
+ },
+ {
+ .nf_type = SOCKLND,
+ .nf_name = "tcp",
+ .nf_modname = "ksocklnd",
+ .nf_addr2str = libcfs_ip_addr2str,
+ .nf_str2addr = libcfs_ip_str2addr,
+ .nf_parse_addrlist = cfs_ip_addr_parse,
+ .nf_print_addrlist = libcfs_ip_addr_range_print,
+ .nf_match_addr = cfs_ip_addr_match,
+ .nf_is_contiguous = cfs_ip_is_contiguous,
+ .nf_min_max = cfs_ip_min_max
+ },
+ {
+ .nf_type = O2IBLND,
+ .nf_name = "o2ib",
+ .nf_modname = "ko2iblnd",
+ .nf_addr2str = libcfs_ip_addr2str,
+ .nf_str2addr = libcfs_ip_str2addr,
+ .nf_parse_addrlist = cfs_ip_addr_parse,
+ .nf_print_addrlist = libcfs_ip_addr_range_print,
+ .nf_match_addr = cfs_ip_addr_match,
+ .nf_is_contiguous = cfs_ip_is_contiguous,
+ .nf_min_max = cfs_ip_min_max
+ },
+ {
+ .nf_type = GNILND,
+ .nf_name = "gni",
+ .nf_modname = "kgnilnd",
+ .nf_addr2str = libcfs_decnum_addr2str,
+ .nf_str2addr = libcfs_num_str2addr,
+ .nf_parse_addrlist = libcfs_num_parse,
+ .nf_print_addrlist = libcfs_num_addr_range_print,
+ .nf_match_addr = libcfs_num_match,
+ .nf_is_contiguous = cfs_num_is_contiguous,
+ .nf_min_max = cfs_num_min_max
+ },
+ {
+ .nf_type = GNIIPLND,
+ .nf_name = "gip",
+ .nf_modname = "kgnilnd",
+ .nf_addr2str = libcfs_ip_addr2str,
+ .nf_str2addr = libcfs_ip_str2addr,
+ .nf_parse_addrlist = cfs_ip_addr_parse,
+ .nf_print_addrlist = libcfs_ip_addr_range_print,
+ .nf_match_addr = cfs_ip_addr_match,
+ .nf_is_contiguous = cfs_ip_is_contiguous,
+ .nf_min_max = cfs_ip_min_max
+ },
+ {
+ .nf_type = PTL4LND,
+ .nf_name = "ptlf",
+ .nf_modname = "kptl4lnd",
+ .nf_addr2str = libcfs_decnum_addr2str,
+ .nf_str2addr = libcfs_num_str2addr,
+ .nf_parse_addrlist = libcfs_num_parse,
+ .nf_print_addrlist = libcfs_num_addr_range_print,
+ .nf_match_addr = libcfs_num_match,
+ .nf_is_contiguous = cfs_num_is_contiguous,
+ .nf_min_max = cfs_num_min_max
+ }
+};
+
+static const size_t libcfs_nnetstrfns =
+ sizeof(libcfs_netstrfns)/sizeof(libcfs_netstrfns[0]);
+
static struct netstrfns *
libcfs_lnd2netstrfns(__u32 lnd)
{
for (i = 0; i < libcfs_nnetstrfns; i++) {
nf = &libcfs_netstrfns[i];
- if (nf->nf_type >= 0 &&
- !strncmp(name, nf->nf_name, strlen(nf->nf_name)))
+ if (!strncmp(name, nf->nf_name, strlen(nf->nf_name)))
return nf;
}
return NULL;
int i;
for (i = 0; i < libcfs_nnetstrfns; i++)
- if (libcfs_netstrfns[i].nf_type >= 0 &&
- !strcmp(libcfs_netstrfns[i].nf_name, name))
+ if (!strcmp(libcfs_netstrfns[i].nf_name, name))
return &libcfs_netstrfns[i];
return NULL;
for (i = 0; i < libcfs_nnetstrfns; i++) {
nf = &libcfs_netstrfns[i];
- if (nf->nf_type >= 0 &&
- !strncmp(str, nf->nf_name, strlen(nf->nf_name)))
+ if (!strncmp(str, nf->nf_name, strlen(nf->nf_name)))
break;
}
};
/**
- * Nf_parse_addrlist method for networks using numeric addresses.
- *
- * Examples of such networks are gm and elan.
- *
- * \retval 0 if \a str parsed to numeric address
- * \retval errno otherwise
- */
-static int
-libcfs_num_parse(char *str, int len, struct list_head *list)
-{
- struct cfs_expr_list *el;
- int rc;
-
- rc = cfs_expr_list_parse(str, len, 0, MAX_NUMERIC_VALUE, &el);
- if (rc == 0)
- list_add_tail(&el->el_link, list);
-
- return rc;
-}
-
-/**
* Parses \<addrrange\> token on the syntax.
*
* Allocates struct addrrange and links to \a nidrange via
return 1;
}
-/*
- * Nf_match_addr method for networks using numeric addresses
- *
- * \retval 1 on match
- * \retval 0 otherwise
- */
-static int
-libcfs_num_match(__u32 addr, struct list_head *numaddr)
-{
- struct cfs_expr_list *el;
-
- assert(!list_empty(numaddr));
- el = list_entry(numaddr->next, struct cfs_expr_list, el_link);
-
- return cfs_expr_list_match(addr, el);
-}
-
/**
* Matches a nid (\a nid) against the compiled list of nidranges (\a nidlist).
*
return 0;
}
-static int
-libcfs_num_addr_range_print(char *buffer, int count, struct list_head *list)
-{
- struct cfs_expr_list *el;
- int i = 0, j = 0;
-
- list_for_each_entry(el, list, el_link) {
- assert(j++ < 1);
- i += cfs_expr_list_print(buffer + i, count - i, el);
- }
- return i;
-}
-
-static int
-libcfs_ip_addr_range_print(char *buffer, int count, struct list_head *list)
-{
- int i = 0, j = 0;
- struct cfs_expr_list *el;
-
- list_for_each_entry(el, list, el_link) {
- assert(j++ < 4);
- if (i != 0)
- i += snprintf(buffer + i, count - i, ".");
- i += cfs_expr_list_print(buffer + i, count - i, el);
- }
- return i;
-}
-
-
/**
* Print the network part of the nidrange \a nr into the specified \a buffer.
*