static void libcfs_decnum_addr2str(__u32 addr, char *str);
static void libcfs_hexnum_addr2str(__u32 addr, char *str);
static int libcfs_num_str2addr(const char *str, int nob, __u32 *addr);
-static int libcfs_num_parse(char *str, int len, cfs_list_t *list);
-static int libcfs_num_match(__u32 addr, cfs_list_t *list);
+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);
struct netstrfns {
- int nf_type;
- char *nf_name;
- char *nf_modname;
- void (*nf_addr2str)(__u32 addr, char *str);
- int (*nf_str2addr)(const char *str, int nob, __u32 *addr);
- int (*nf_parse_addrlist)(char *str, int len,
- cfs_list_t *list);
- int (*nf_match_addr)(__u32 addr, cfs_list_t *list);
+ int nf_type;
+ char *nf_name;
+ char *nf_modname;
+ void (*nf_addr2str)(__u32 addr, char *str);
+ 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);
};
static struct netstrfns libcfs_netstrfns[] = {
/* .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_type */ SOCKLND,
/* .nf_name */ "tcp",
/* .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_type */ O2IBLND,
/* .nf_name */ "o2ib",
/* .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_type */ CIBLND,
/* .nf_name */ "cib",
/* .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_type */ OPENIBLND,
/* .nf_name */ "openib",
/* .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_type */ IIBLND,
/* .nf_name */ "iib",
/* .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_type */ VIBLND,
/* .nf_name */ "vib",
/* .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_type */ RALND,
/* .nf_name */ "ra",
/* .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_type */ QSWLND,
/* .nf_name */ "elan",
/* .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_type */ GMLND,
/* .nf_name */ "gm",
/* .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_type */ MXLND,
/* .nf_name */ "mx",
/* .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_type */ PTLLND,
/* .nf_name */ "ptl",
/* .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_type */ GNILND,
/* .nf_name */ "gni",
/* .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_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},
/* placeholder for net0 alias. It MUST BE THE LAST ENTRY */
{/* .nf_type */ -1},
};
static struct netstrfns *
libcfs_str2net_internal(const char *str, __u32 *net)
{
- struct netstrfns *nf;
+ struct netstrfns *nf = NULL;
int nob;
int netnum;
int i;
* One of this is created for each \<net\> parsed.
*/
struct nidrange {
- /**
- * Link to list of this structures which is built on nid range
- * list parsing.
- */
- cfs_list_t nr_link;
- /**
- * List head for addrrange::ar_link.
- */
- cfs_list_t nr_addrranges;
- /**
- * Flag indicating that *@<net> is found.
- */
- int nr_all;
- /**
- * Pointer to corresponding element of libcfs_netstrfns.
- */
- struct netstrfns *nr_netstrfns;
- /**
- * Number of network. E.g. 5 if \<net\> is "elan5".
- */
- int nr_netnum;
+ /**
+ * Link to list of this structures which is built on nid range
+ * list parsing.
+ */
+ struct list_head nr_link;
+ /**
+ * List head for addrrange::ar_link.
+ */
+ struct list_head nr_addrranges;
+ /**
+ * Flag indicating that *@<net> is found.
+ */
+ int nr_all;
+ /**
+ * Pointer to corresponding element of libcfs_netstrfns.
+ */
+ struct netstrfns *nr_netstrfns;
+ /**
+ * Number of network. E.g. 5 if \<net\> is "elan5".
+ */
+ int nr_netnum;
};
/**
* Structure to represent \<addrrange\> token of the syntax.
*/
struct addrrange {
- /**
- * Link to nidrange::nr_addrranges.
- */
- cfs_list_t ar_link;
- /**
+ /**
+ * Link to nidrange::nr_addrranges.
+ */
+ struct list_head ar_link;
+ /**
* List head for cfs_expr_list::el_list.
- */
- cfs_list_t ar_numaddr_ranges;
+ */
+ struct list_head ar_numaddr_ranges;
};
/**
* \retval errno otherwise
*/
static int
-libcfs_num_parse(char *str, int len, cfs_list_t *list)
+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)
- cfs_list_add_tail(&el->el_link, list);
+ list_add_tail(&el->el_link, list);
return rc;
}
* Allocates struct addrrange and links to \a nidrange via
* (nidrange::nr_addrranges)
*
- * \retval 1 if \a src parses to '*' | \<ipaddr_range\> | \<cfs_expr_list\>
- * \retval 0 otherwise
+ * \retval 0 if \a src parses to '*' | \<ipaddr_range\> | \<cfs_expr_list\>
+ * \retval -errno otherwise
*/
static int
parse_addrange(const struct cfs_lstr *src, struct nidrange *nidrange)
{
- struct addrrange *addrrange;
+ struct addrrange *addrrange;
- if (src->ls_len == 1 && src->ls_str[0] == '*') {
- nidrange->nr_all = 1;
- return 1;
- }
+ if (src->ls_len == 1 && src->ls_str[0] == '*') {
+ nidrange->nr_all = 1;
+ return 0;
+ }
- LIBCFS_ALLOC(addrrange, sizeof(struct addrrange));
- if (addrrange == NULL)
- return 0;
- cfs_list_add_tail(&addrrange->ar_link, &nidrange->nr_addrranges);
- CFS_INIT_LIST_HEAD(&addrrange->ar_numaddr_ranges);
+ LIBCFS_ALLOC(addrrange, sizeof(struct addrrange));
+ if (addrrange == NULL)
+ return -ENOMEM;
+ list_add_tail(&addrrange->ar_link, &nidrange->nr_addrranges);
+ INIT_LIST_HEAD(&addrrange->ar_numaddr_ranges);
- return nidrange->nr_netstrfns->nf_parse_addrlist(src->ls_str,
- src->ls_len,
- &addrrange->ar_numaddr_ranges);
+ return nidrange->nr_netstrfns->nf_parse_addrlist(src->ls_str,
+ src->ls_len,
+ &addrrange->ar_numaddr_ranges);
}
/**
*/
static struct nidrange *
add_nidrange(const struct cfs_lstr *src,
- cfs_list_t *nidlist)
+ struct list_head *nidlist)
{
struct netstrfns *nf;
struct nidrange *nr;
return NULL;
}
- cfs_list_for_each_entry(nr, nidlist, nr_link) {
- if (nr->nr_netstrfns != nf)
- continue;
- if (nr->nr_netnum != netnum)
- continue;
- return nr;
- }
+ list_for_each_entry(nr, nidlist, nr_link) {
+ if (nr->nr_netstrfns != nf)
+ continue;
+ if (nr->nr_netnum != netnum)
+ continue;
+ return nr;
+ }
- LIBCFS_ALLOC(nr, sizeof(struct nidrange));
- if (nr == NULL)
- return NULL;
- cfs_list_add_tail(&nr->nr_link, nidlist);
- CFS_INIT_LIST_HEAD(&nr->nr_addrranges);
- nr->nr_netstrfns = nf;
- nr->nr_all = 0;
- nr->nr_netnum = netnum;
+ LIBCFS_ALLOC(nr, sizeof(struct nidrange));
+ if (nr == NULL)
+ return NULL;
+ list_add_tail(&nr->nr_link, nidlist);
+ INIT_LIST_HEAD(&nr->nr_addrranges);
+ nr->nr_netstrfns = nf;
+ nr->nr_all = 0;
+ nr->nr_netnum = netnum;
- return nr;
+ return nr;
}
/**
* \retval 0 otherwise
*/
static int
-parse_nidrange(struct cfs_lstr *src, cfs_list_t *nidlist)
+parse_nidrange(struct cfs_lstr *src, struct list_head *nidlist)
{
struct cfs_lstr addrrange;
struct cfs_lstr net;
* \retval none
*/
static void
-free_addrranges(cfs_list_t *list)
+free_addrranges(struct list_head *list)
{
- while (!cfs_list_empty(list)) {
+ while (!list_empty(list)) {
struct addrrange *ar;
- ar = cfs_list_entry(list->next, struct addrrange, ar_link);
+ ar = list_entry(list->next, struct addrrange, ar_link);
cfs_expr_list_free_list(&ar->ar_numaddr_ranges);
- cfs_list_del(&ar->ar_link);
+ list_del(&ar->ar_link);
LIBCFS_FREE(ar, sizeof(struct addrrange));
}
}
* \retval none
*/
void
-cfs_free_nidlist(cfs_list_t *list)
+cfs_free_nidlist(struct list_head *list)
{
- cfs_list_t *pos, *next;
- struct nidrange *nr;
-
- cfs_list_for_each_safe(pos, next, list) {
- nr = cfs_list_entry(pos, struct nidrange, nr_link);
- free_addrranges(&nr->nr_addrranges);
- cfs_list_del(pos);
- LIBCFS_FREE(nr, sizeof(struct nidrange));
- }
+ struct list_head *pos, *next;
+ struct nidrange *nr;
+
+ list_for_each_safe(pos, next, list) {
+ nr = list_entry(pos, struct nidrange, nr_link);
+ free_addrranges(&nr->nr_addrranges);
+ list_del(pos);
+ LIBCFS_FREE(nr, sizeof(struct nidrange));
+ }
}
/**
* \retval 0 otherwise
*/
int
-cfs_parse_nidlist(char *str, int len, cfs_list_t *nidlist)
+cfs_parse_nidlist(char *str, int len, struct list_head *nidlist)
{
struct cfs_lstr src;
struct cfs_lstr res;
- int rc;
- ENTRY;
+ int rc;
+ ENTRY;
- src.ls_str = str;
- src.ls_len = len;
- CFS_INIT_LIST_HEAD(nidlist);
- while (src.ls_str) {
+ src.ls_str = str;
+ src.ls_len = len;
+ INIT_LIST_HEAD(nidlist);
+ while (src.ls_str) {
rc = cfs_gettok(&src, ' ', &res);
- if (rc == 0) {
- cfs_free_nidlist(nidlist);
- RETURN(0);
- }
- rc = parse_nidrange(&res, nidlist);
- if (rc == 0) {
- cfs_free_nidlist(nidlist);
- RETURN(0);
- }
- }
- RETURN(1);
+ if (rc == 0) {
+ cfs_free_nidlist(nidlist);
+ RETURN(0);
+ }
+ rc = parse_nidrange(&res, nidlist);
+ if (rc == 0) {
+ cfs_free_nidlist(nidlist);
+ RETURN(0);
+ }
+ }
+ RETURN(1);
}
/*
* \retval 0 otherwise
*/
static int
-libcfs_num_match(__u32 addr, cfs_list_t *numaddr)
+libcfs_num_match(__u32 addr, struct list_head *numaddr)
{
struct cfs_expr_list *el;
- LASSERT(!cfs_list_empty(numaddr));
- el = cfs_list_entry(numaddr->next, struct cfs_expr_list, el_link);
+ LASSERT(!list_empty(numaddr));
+ el = list_entry(numaddr->next, struct cfs_expr_list, el_link);
return cfs_expr_list_match(addr, el);
}
* \retval 1 on match
* \retval 0 otherwises
*/
-int cfs_match_nid(lnet_nid_t nid, cfs_list_t *nidlist)
+int cfs_match_nid(lnet_nid_t nid, struct list_head *nidlist)
{
- struct nidrange *nr;
- struct addrrange *ar;
- ENTRY;
-
- cfs_list_for_each_entry(nr, nidlist, nr_link) {
- if (nr->nr_netstrfns->nf_type != LNET_NETTYP(LNET_NIDNET(nid)))
- continue;
- if (nr->nr_netnum != LNET_NETNUM(LNET_NIDNET(nid)))
- continue;
- if (nr->nr_all)
- RETURN(1);
- cfs_list_for_each_entry(ar, &nr->nr_addrranges, ar_link)
- if (nr->nr_netstrfns->nf_match_addr(LNET_NIDADDR(nid),
- &ar->ar_numaddr_ranges))
- RETURN(1);
- }
- RETURN(0);
+ struct nidrange *nr;
+ struct addrrange *ar;
+ ENTRY;
+
+ list_for_each_entry(nr, nidlist, nr_link) {
+ if (nr->nr_netstrfns->nf_type != LNET_NETTYP(LNET_NIDNET(nid)))
+ continue;
+ if (nr->nr_netnum != LNET_NETNUM(LNET_NIDNET(nid)))
+ continue;
+ if (nr->nr_all)
+ RETURN(1);
+ list_for_each_entry(ar, &nr->nr_addrranges, ar_link)
+ if (nr->nr_netstrfns->nf_match_addr(LNET_NIDADDR(nid),
+ &ar->ar_numaddr_ranges))
+ RETURN(1);
+ }
+ RETURN(0);
+}
+
+static int
+libcfs_num_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) {
+ LASSERT(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) {
+ LASSERT(j++ < 4);
+ if (i != 0)
+ i += cfs_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.
+ *
+ * \retval number of characters written
+ */
+static int
+cfs_print_network(char *buffer, int count, struct nidrange *nr)
+{
+ struct netstrfns *nf = nr->nr_netstrfns;
+
+ if (nr->nr_netnum == 0)
+ return cfs_snprintf(buffer, count, "@%s", nf->nf_name);
+ else
+ return cfs_snprintf(buffer, count, "@%s%u",
+ nf->nf_name, nr->nr_netnum);
+}
+
+
+/**
+ * Print a list of addrrange (\a addrranges) into the specified \a buffer.
+ * At max \a count characters can be printed into \a buffer.
+ *
+ * \retval number of characters written
+ */
+static int
+cfs_print_addrranges(char *buffer, int count, struct list_head *addrranges,
+ struct nidrange *nr)
+{
+ int i = 0;
+ struct addrrange *ar;
+ struct netstrfns *nf = nr->nr_netstrfns;
+
+ list_for_each_entry(ar, addrranges, ar_link) {
+ if (i != 0)
+ i += cfs_snprintf(buffer + i, count - i, " ");
+ i += nf->nf_print_addrlist(buffer + i, count - i,
+ &ar->ar_numaddr_ranges);
+ i += cfs_print_network(buffer + i, count - i, nr);
+ }
+ return i;
+}
+
+
+/**
+ * Print a list of nidranges (\a nidlist) into the specified \a buffer.
+ * At max \a count characters can be printed into \a buffer.
+ * Nidranges are separated by a space character.
+ *
+ * \retval number of characters written
+ */
+int cfs_print_nidlist(char *buffer, int count, struct list_head *nidlist)
+{
+ int i = 0;
+ struct nidrange *nr;
+ ENTRY;
+
+ if (count <= 0)
+ RETURN(0);
+
+ list_for_each_entry(nr, nidlist, nr_link) {
+ if (i != 0)
+ i += cfs_snprintf(buffer + i, count - i, " ");
+
+ if (nr->nr_all != 0) {
+ LASSERT(list_empty(&nr->nr_addrranges));
+ i += cfs_snprintf(buffer + i, count - i, "*");
+ i += cfs_print_network(buffer + i, count - i, nr);
+ } else {
+ i += cfs_print_addrranges(buffer + i, count - i,
+ &nr->nr_addrranges, nr);
+ }
+ }
+ RETURN(i);
}
#ifdef __KERNEL__
EXPORT_SYMBOL(libcfs_str2anynid);
EXPORT_SYMBOL(cfs_free_nidlist);
EXPORT_SYMBOL(cfs_parse_nidlist);
+EXPORT_SYMBOL(cfs_print_nidlist);
EXPORT_SYMBOL(cfs_match_nid);
#endif