* \retval 0 if \a str parsed to numeric address
* \retval errno otherwise
*/
-static int
+int
libcfs_num_parse(char *str, int len, struct list_head *list)
{
struct cfs_expr_list *el;
return 0;
}
+static __u32
+libcfs_net_str_len(const char *str)
+{
+ int i;
+ struct netstrfns *nf = NULL;
+
+ for (i = 0; i < libcfs_nnetstrfns; i++) {
+ nf = &libcfs_netstrfns[i];
+ if (!strncmp(str, nf->nf_name, strlen(nf->nf_name)))
+ return strlen(nf->nf_name);
+ }
+
+ return 0;
+}
+
+int
+parse_net_range(char *str, __u32 len, struct list_head *net_num,
+ __u32 *net_type)
+{
+ struct cfs_lstr next;
+ __u32 net_type_len;
+ __u32 net;
+ char *bracket;
+ char *star;
+
+ if (!str)
+ return -EINVAL;
+
+ next.ls_str = str;
+ next.ls_len = len;
+
+ net_type_len = libcfs_net_str_len(str);
+
+ if (net_type_len < len) {
+ char c = str[net_type_len];
+
+ str[net_type_len] = '\0';
+ net = libcfs_str2net(str);
+ str[net_type_len] = c;
+ } else {
+ net = libcfs_str2net(str);
+ }
+
+ if (net == LNET_NIDNET(LNET_NID_ANY))
+ return -EINVAL;
+
+ *net_type = LNET_NETTYP(net);
+
+ /*
+ * the net is either followed with an absolute number, *, or an
+ * expression enclosed in []
+ */
+ bracket = strchr(next.ls_str, '[');
+ star = strchr(next.ls_str, '*');
+
+ /* "*[" pattern not allowed */
+ if (bracket && star && star < bracket)
+ return -EINVAL;
+
+ if (!bracket) {
+ next.ls_str = str + net_type_len;
+ next.ls_len = strlen(next.ls_str);
+ } else {
+ next.ls_str = bracket;
+ next.ls_len = strlen(bracket);
+ }
+
+ /* if there is no net number just return */
+ if (next.ls_len == 0)
+ return 0;
+
+ return libcfs_num_parse(next.ls_str, next.ls_len,
+ net_num);
+}
+
+int
+parse_address(struct cfs_lstr *src, const __u32 net_type,
+ struct list_head *addr)
+{
+ int i;
+ struct netstrfns *nf = NULL;
+
+ for (i = 0; i < libcfs_nnetstrfns; i++) {
+ nf = &libcfs_netstrfns[i];
+ if (net_type == nf->nf_type)
+ return nf->nf_parse_addrlist(src->ls_str, src->ls_len,
+ addr);
+ }
+
+ return -EINVAL;
+}
+
+int
+cfs_parse_nid_parts(char *str, struct list_head *addr,
+ struct list_head *net_num, __u32 *net_type)
+{
+ struct cfs_lstr next;
+ struct cfs_lstr addrrange;
+ bool found = false;
+ int rc;
+
+ if (!str)
+ return -EINVAL;
+
+ next.ls_str = str;
+ next.ls_len = strlen(str);
+
+ rc = cfs_gettok(&next, '@', &addrrange);
+ if (!rc)
+ return -EINVAL;
+
+ if (!next.ls_str) {
+ /* only net is present */
+ next.ls_str = str;
+ next.ls_len = strlen(str);
+ } else {
+ found = true;
+ }
+
+ /* assume only net is present */
+ rc = parse_net_range(next.ls_str, next.ls_len, net_num, net_type);
+
+ /*
+ * if we successfully parsed the net range and there is no
+ * address, or if we fail to parse the net range then return
+ */
+ if ((!rc && !found) || rc)
+ return rc;
+
+ return parse_address(&addrrange, *net_type, addr);
+}
+
/**
* Frees addrrange structures of \a list.
*