4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2012, 2015, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
37 #define DEBUG_SUBSYSTEM S_LNET
38 #include "../../include/linux/lnet/lib-lnet.h"
40 struct lnet_text_buf { /* tmp struct for parsing routes */
41 struct list_head ltb_list; /* stash on lists */
42 int ltb_size; /* allocated size */
43 char ltb_text[0]; /* text buffer */
46 static int lnet_tbnob; /* track text buf allocation */
47 #define LNET_MAX_TEXTBUF_NOB (64 << 10) /* bound allocation */
48 #define LNET_SINGLE_TEXTBUF_NOB (4 << 10)
51 lnet_syntax(char *name, char *str, int offset, int width)
53 static char dots[LNET_SINGLE_TEXTBUF_NOB];
54 static char dashes[LNET_SINGLE_TEXTBUF_NOB];
56 memset(dots, '.', sizeof(dots));
57 dots[sizeof(dots) - 1] = 0;
58 memset(dashes, '-', sizeof(dashes));
59 dashes[sizeof(dashes) - 1] = 0;
61 LCONSOLE_ERROR_MSG(0x10f, "Error parsing '%s=\"%s\"'\n", name, str);
62 LCONSOLE_ERROR_MSG(0x110, "here...........%.*s..%.*s|%.*s|\n",
63 (int)strlen(name), dots, offset, dots,
64 (width < 1) ? 0 : width - 1, dashes);
81 lnet_net_unique(__u32 net, struct list_head *nilist)
83 struct list_head *tmp;
86 list_for_each(tmp, nilist) {
87 ni = list_entry(tmp, lnet_ni_t, ni_list);
89 if (LNET_NIDNET(ni->ni_nid) == net)
97 lnet_ni_free(struct lnet_ni *ni)
102 cfs_percpt_free(ni->ni_refs);
104 if (ni->ni_tx_queues)
105 cfs_percpt_free(ni->ni_tx_queues);
108 cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts);
110 for (i = 0; i < LNET_MAX_INTERFACES && ni->ni_interfaces[i]; i++) {
111 LIBCFS_FREE(ni->ni_interfaces[i],
112 strlen(ni->ni_interfaces[i]) + 1);
114 LIBCFS_FREE(ni, sizeof(*ni));
118 lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist)
120 struct lnet_tx_queue *tq;
125 if (!lnet_net_unique(net, nilist)) {
126 LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n",
127 libcfs_net2str(net));
131 LIBCFS_ALLOC(ni, sizeof(*ni));
133 CERROR("Out of memory creating network %s\n",
134 libcfs_net2str(net));
138 spin_lock_init(&ni->ni_lock);
139 INIT_LIST_HEAD(&ni->ni_cptlist);
140 ni->ni_refs = cfs_percpt_alloc(lnet_cpt_table(),
141 sizeof(*ni->ni_refs[0]));
145 ni->ni_tx_queues = cfs_percpt_alloc(lnet_cpt_table(),
146 sizeof(*ni->ni_tx_queues[0]));
147 if (!ni->ni_tx_queues)
150 cfs_percpt_for_each(tq, i, ni->ni_tx_queues)
151 INIT_LIST_HEAD(&tq->tq_delayed);
155 ni->ni_ncpts = LNET_CPT_NUMBER;
157 rc = cfs_expr_list_values(el, LNET_CPT_NUMBER, &ni->ni_cpts);
159 CERROR("Failed to set CPTs for NI %s: %d\n",
160 libcfs_net2str(net), rc);
164 LASSERT(rc <= LNET_CPT_NUMBER);
165 if (rc == LNET_CPT_NUMBER) {
166 LIBCFS_FREE(ni->ni_cpts, rc * sizeof(ni->ni_cpts[0]));
173 /* LND will fill in the address part of the NID */
174 ni->ni_nid = LNET_MKNID(net, 0);
175 ni->ni_last_alive = ktime_get_real_seconds();
176 list_add_tail(&ni->ni_list, nilist);
184 lnet_parse_networks(struct list_head *nilist, char *networks)
186 struct cfs_expr_list *el = NULL;
194 struct list_head *temp_node;
197 CERROR("networks string is undefined\n");
201 if (strlen(networks) > LNET_SINGLE_TEXTBUF_NOB) {
202 /* _WAY_ conservative */
203 LCONSOLE_ERROR_MSG(0x112,
204 "Can't parse networks: string too long\n");
208 tokensize = strlen(networks) + 1;
210 LIBCFS_ALLOC(tokens, tokensize);
212 CERROR("Can't allocate net tokens\n");
216 memcpy(tokens, networks, tokensize);
220 while (str && *str) {
221 char *comma = strchr(str, ',');
222 char *bracket = strchr(str, '(');
223 char *square = strchr(str, '[');
229 * NB we don't check interface conflicts here; it's the LNDs
230 * responsibility (if it cares at all)
232 if (square && (!comma || square < comma)) {
234 * i.e: o2ib0(ib0)[1,2], number between square
235 * brackets are CPTs this NI needs to be bond
237 if (bracket && bracket > square) {
242 tmp = strchr(square, ']');
248 rc = cfs_expr_list_parse(square, tmp - square + 1,
249 0, LNET_CPT_NUMBER - 1, &el);
255 while (square <= tmp)
259 if (!bracket || (comma && comma < bracket)) {
260 /* no interface list specified */
264 net = libcfs_str2net(cfs_trimwhite(str));
266 if (net == LNET_NIDNET(LNET_NID_ANY)) {
267 LCONSOLE_ERROR_MSG(0x113,
268 "Unrecognised network type\n");
273 if (LNET_NETTYP(net) != LOLND && /* LO is implicit */
274 !lnet_ni_alloc(net, el, nilist))
278 cfs_expr_list_free(el);
287 net = libcfs_str2net(cfs_trimwhite(str));
288 if (net == LNET_NIDNET(LNET_NID_ANY)) {
293 ni = lnet_ni_alloc(net, el, nilist);
298 cfs_expr_list_free(el);
305 bracket = strchr(iface, ')');
313 comma = strchr(iface, ',');
317 iface = cfs_trimwhite(iface);
323 if (niface == LNET_MAX_INTERFACES) {
324 LCONSOLE_ERROR_MSG(0x115,
325 "Too many interfaces for net %s\n",
326 libcfs_net2str(net));
331 * Allocate a separate piece of memory and copy
332 * into it the string, so we don't have
333 * a depencency on the tokens string. This way we
334 * can free the tokens at the end of the function.
335 * The newly allocated ni_interfaces[] can be
336 * freed when freeing the NI
338 LIBCFS_ALLOC(ni->ni_interfaces[niface],
340 if (!ni->ni_interfaces[niface]) {
341 CERROR("Can't allocate net interface name\n");
344 strncpy(ni->ni_interfaces[niface], iface,
351 comma = strchr(bracket + 1, ',');
354 str = cfs_trimwhite(str);
363 str = cfs_trimwhite(str);
370 list_for_each(temp_node, nilist)
373 LIBCFS_FREE(tokens, tokensize);
377 lnet_syntax("networks", networks, (int)(tmp - tokens), strlen(tmp));
379 while (!list_empty(nilist)) {
380 ni = list_entry(nilist->next, lnet_ni_t, ni_list);
382 list_del(&ni->ni_list);
387 cfs_expr_list_free(el);
389 LIBCFS_FREE(tokens, tokensize);
394 static struct lnet_text_buf *
395 lnet_new_text_buf(int str_len)
397 struct lnet_text_buf *ltb;
400 /* NB allocate space for the terminating 0 */
401 nob = offsetof(struct lnet_text_buf, ltb_text[str_len + 1]);
402 if (nob > LNET_SINGLE_TEXTBUF_NOB) {
403 /* _way_ conservative for "route net gateway..." */
404 CERROR("text buffer too big\n");
408 if (lnet_tbnob + nob > LNET_MAX_TEXTBUF_NOB) {
409 CERROR("Too many text buffers\n");
413 LIBCFS_ALLOC(ltb, nob);
418 ltb->ltb_text[0] = 0;
424 lnet_free_text_buf(struct lnet_text_buf *ltb)
426 lnet_tbnob -= ltb->ltb_size;
427 LIBCFS_FREE(ltb, ltb->ltb_size);
431 lnet_free_text_bufs(struct list_head *tbs)
433 struct lnet_text_buf *ltb;
435 while (!list_empty(tbs)) {
436 ltb = list_entry(tbs->next, struct lnet_text_buf, ltb_list);
438 list_del(<b->ltb_list);
439 lnet_free_text_buf(ltb);
444 lnet_str2tbs_sep(struct list_head *tbs, char *str)
446 struct list_head pending;
450 struct lnet_text_buf *ltb;
452 INIT_LIST_HEAD(&pending);
454 /* Split 'str' into separate commands */
456 /* skip leading whitespace */
457 while (isspace(*str))
460 /* scan for separator or comment */
461 for (sep = str; *sep; sep++)
462 if (lnet_issep(*sep) || *sep == '#')
465 nob = (int)(sep - str);
467 ltb = lnet_new_text_buf(nob);
469 lnet_free_text_bufs(&pending);
473 for (i = 0; i < nob; i++)
475 ltb->ltb_text[i] = ' ';
477 ltb->ltb_text[i] = str[i];
479 ltb->ltb_text[nob] = 0;
481 list_add_tail(<b->ltb_list, &pending);
485 /* scan for separator */
488 } while (*sep && !lnet_issep(*sep));
497 list_splice(&pending, tbs->prev);
502 lnet_expand1tb(struct list_head *list,
503 char *str, char *sep1, char *sep2,
504 char *item, int itemlen)
506 int len1 = (int)(sep1 - str);
507 int len2 = strlen(sep2 + 1);
508 struct lnet_text_buf *ltb;
510 LASSERT(*sep1 == '[');
511 LASSERT(*sep2 == ']');
513 ltb = lnet_new_text_buf(len1 + itemlen + len2);
517 memcpy(ltb->ltb_text, str, len1);
518 memcpy(<b->ltb_text[len1], item, itemlen);
519 memcpy(<b->ltb_text[len1 + itemlen], sep2 + 1, len2);
520 ltb->ltb_text[len1 + itemlen + len2] = 0;
522 list_add_tail(<b->ltb_list, list);
527 lnet_str2tbs_expand(struct list_head *tbs, char *str)
530 struct list_head pending;
542 INIT_LIST_HEAD(&pending);
544 sep = strchr(str, '[');
545 if (!sep) /* nothing to expand */
548 sep2 = strchr(sep, ']');
552 for (parsed = sep; parsed < sep2; parsed = enditem) {
554 while (enditem < sep2 && *enditem != ',')
557 if (enditem == parsed) /* no empty items */
560 if (sscanf(parsed, "%d-%d/%d%n", &lo, &hi,
561 &stride, &scanned) < 3) {
562 if (sscanf(parsed, "%d-%d%n", &lo, &hi, &scanned) < 2) {
563 /* simple string enumeration */
564 if (lnet_expand1tb(&pending, str, sep, sep2,
566 (int)(enditem - parsed))) {
575 /* range expansion */
577 if (enditem != parsed + scanned) /* no trailing junk */
580 if (hi < 0 || lo < 0 || stride < 0 || hi < lo ||
584 for (i = lo; i <= hi; i += stride) {
585 snprintf(num, sizeof(num), "%d", i);
587 if (nob + 1 == sizeof(num))
590 if (lnet_expand1tb(&pending, str, sep, sep2,
596 list_splice(&pending, tbs->prev);
600 lnet_free_text_bufs(&pending);
605 lnet_parse_hops(char *str, unsigned int *hops)
607 int len = strlen(str);
610 return (sscanf(str, "%u%n", hops, &nob) >= 1 &&
612 *hops > 0 && *hops < 256);
615 #define LNET_PRIORITY_SEPARATOR (':')
618 lnet_parse_priority(char *str, unsigned int *priority, char **token)
624 sep = strchr(str, LNET_PRIORITY_SEPARATOR);
629 len = strlen(sep + 1);
631 if ((sscanf((sep + 1), "%u%n", priority, &nob) < 1) || (len != nob)) {
633 * Update the caller's token pointer so it treats the found
634 * priority as the token to report in the error message.
636 *token += sep - str + 1;
640 CDEBUG(D_NET, "gateway %s, priority %d, nob %d\n", str, *priority, nob);
643 * Change priority separator to \0 to be able to parse NID
650 lnet_parse_route(char *str, int *im_a_router)
652 /* static scratch buffer OK (single threaded) */
653 static char cmd[LNET_SINGLE_TEXTBUF_NOB];
655 struct list_head nets;
656 struct list_head gateways;
657 struct list_head *tmp1;
658 struct list_head *tmp2;
661 struct lnet_text_buf *ltb;
669 unsigned int priority = 0;
671 INIT_LIST_HEAD(&gateways);
672 INIT_LIST_HEAD(&nets);
674 /* save a copy of the string for error messages */
675 strncpy(cmd, str, sizeof(cmd));
676 cmd[sizeof(cmd) - 1] = '\0';
680 /* scan for token start */
681 while (isspace(*sep))
684 if (ntokens < (got_hops ? 3 : 2))
692 /* scan for token end */
693 while (*sep && !isspace(*sep))
699 tmp2 = &nets; /* expanding nets */
700 } else if (ntokens == 2 &&
701 lnet_parse_hops(token, &hops)) {
702 got_hops = 1; /* got a hop count */
705 tmp2 = &gateways; /* expanding gateways */
708 ltb = lnet_new_text_buf(strlen(token));
712 strcpy(ltb->ltb_text, token);
713 tmp1 = <b->ltb_list;
714 list_add_tail(tmp1, tmp2);
716 while (tmp1 != tmp2) {
717 ltb = list_entry(tmp1, struct lnet_text_buf, ltb_list);
719 rc = lnet_str2tbs_expand(tmp1->next, ltb->ltb_text);
725 if (rc > 0) { /* expanded! */
726 list_del(<b->ltb_list);
727 lnet_free_text_buf(ltb);
732 net = libcfs_str2net(ltb->ltb_text);
733 if (net == LNET_NIDNET(LNET_NID_ANY) ||
734 LNET_NETTYP(net) == LOLND)
737 rc = lnet_parse_priority(ltb->ltb_text,
742 nid = libcfs_str2nid(ltb->ltb_text);
743 if (nid == LNET_NID_ANY ||
744 LNET_NETTYP(LNET_NIDNET(nid)) == LOLND)
751 * if there are no hops set then we want to flag this value as
752 * unset since hops is an optional parameter
755 hops = LNET_UNDEFINED_HOPS;
757 LASSERT(!list_empty(&nets));
758 LASSERT(!list_empty(&gateways));
760 list_for_each(tmp1, &nets) {
761 ltb = list_entry(tmp1, struct lnet_text_buf, ltb_list);
762 net = libcfs_str2net(ltb->ltb_text);
763 LASSERT(net != LNET_NIDNET(LNET_NID_ANY));
765 list_for_each(tmp2, &gateways) {
766 ltb = list_entry(tmp2, struct lnet_text_buf, ltb_list);
767 nid = libcfs_str2nid(ltb->ltb_text);
768 LASSERT(nid != LNET_NID_ANY);
770 if (lnet_islocalnid(nid)) {
775 rc = lnet_add_route(net, hops, nid, priority);
776 if (rc && rc != -EEXIST && rc != -EHOSTUNREACH) {
777 CERROR("Can't create route to %s via %s\n",
779 libcfs_nid2str(nid));
789 lnet_syntax("routes", cmd, (int)(token - str), strlen(token));
791 lnet_free_text_bufs(&nets);
792 lnet_free_text_bufs(&gateways);
797 lnet_parse_route_tbs(struct list_head *tbs, int *im_a_router)
799 struct lnet_text_buf *ltb;
801 while (!list_empty(tbs)) {
802 ltb = list_entry(tbs->next, struct lnet_text_buf, ltb_list);
804 if (lnet_parse_route(ltb->ltb_text, im_a_router) < 0) {
805 lnet_free_text_bufs(tbs);
809 list_del(<b->ltb_list);
810 lnet_free_text_buf(ltb);
817 lnet_parse_routes(char *routes, int *im_a_router)
819 struct list_head tbs;
824 INIT_LIST_HEAD(&tbs);
826 if (lnet_str2tbs_sep(&tbs, routes) < 0) {
827 CERROR("Error parsing routes\n");
830 rc = lnet_parse_route_tbs(&tbs, im_a_router);
833 LASSERT(!lnet_tbnob);
838 lnet_match_network_token(char *token, int len, __u32 *ipaddrs, int nip)
844 rc = cfs_ip_addr_parse(token, len, &list);
848 for (rc = i = 0; !rc && i < nip; i++)
849 rc = cfs_ip_addr_match(ipaddrs[i], &list);
851 cfs_expr_list_free_list(&list);
857 lnet_match_network_tokens(char *net_entry, __u32 *ipaddrs, int nip)
859 static char tokens[LNET_SINGLE_TEXTBUF_NOB];
869 LASSERT(strlen(net_entry) < sizeof(tokens));
871 /* work on a copy of the string */
872 strcpy(tokens, net_entry);
875 /* scan for token start */
876 while (isspace(*sep))
883 /* scan for token end */
884 while (*sep && !isspace(*sep))
896 rc = lnet_match_network_token(token, len, ipaddrs, nip);
898 lnet_syntax("ip2nets", net_entry,
899 (int)(token - tokens), len);
910 strcpy(net_entry, net); /* replace with matched net */
915 lnet_netspec2net(char *netspec)
917 char *bracket = strchr(netspec, '(');
923 net = libcfs_str2net(netspec);
932 lnet_splitnets(char *source, struct list_head *nets)
937 struct lnet_text_buf *tb;
938 struct lnet_text_buf *tb2;
944 LASSERT(!list_empty(nets));
945 LASSERT(nets->next == nets->prev); /* single entry */
947 tb = list_entry(nets->next, struct lnet_text_buf, ltb_list);
950 sep = strchr(tb->ltb_text, ',');
951 bracket = strchr(tb->ltb_text, '(');
953 if (sep && bracket && bracket < sep) {
954 /* netspec lists interfaces... */
956 offset2 = offset + (int)(bracket - tb->ltb_text);
957 len = strlen(bracket);
959 bracket = strchr(bracket + 1, ')');
962 !(bracket[1] == ',' || !bracket[1])) {
963 lnet_syntax("ip2nets", source, offset2, len);
967 sep = !bracket[1] ? NULL : bracket + 1;
973 net = lnet_netspec2net(tb->ltb_text);
974 if (net == LNET_NIDNET(LNET_NID_ANY)) {
975 lnet_syntax("ip2nets", source, offset,
976 strlen(tb->ltb_text));
980 list_for_each(t, nets) {
981 tb2 = list_entry(t, struct lnet_text_buf, ltb_list);
986 if (net == lnet_netspec2net(tb2->ltb_text)) {
987 /* duplicate network */
988 lnet_syntax("ip2nets", source, offset,
989 strlen(tb->ltb_text));
997 offset += (int)(sep - tb->ltb_text);
999 tb2 = lnet_new_text_buf(len);
1003 strncpy(tb2->ltb_text, sep, len);
1004 tb2->ltb_text[len] = '\0';
1005 list_add_tail(&tb2->ltb_list, nets);
1012 lnet_match_networks(char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
1014 static char networks[LNET_SINGLE_TEXTBUF_NOB];
1015 static char source[LNET_SINGLE_TEXTBUF_NOB];
1017 struct list_head raw_entries;
1018 struct list_head matched_nets;
1019 struct list_head current_nets;
1020 struct list_head *t;
1021 struct list_head *t2;
1022 struct lnet_text_buf *tb;
1023 struct lnet_text_buf *temp;
1024 struct lnet_text_buf *tb2;
1032 INIT_LIST_HEAD(&raw_entries);
1033 if (lnet_str2tbs_sep(&raw_entries, ip2nets) < 0) {
1034 CERROR("Error parsing ip2nets\n");
1035 LASSERT(!lnet_tbnob);
1039 INIT_LIST_HEAD(&matched_nets);
1040 INIT_LIST_HEAD(¤t_nets);
1046 list_for_each_entry_safe(tb, temp, &raw_entries, ltb_list) {
1047 strncpy(source, tb->ltb_text, sizeof(source));
1048 source[sizeof(source) - 1] = '\0';
1050 /* replace ltb_text with the network(s) add on match */
1051 rc = lnet_match_network_tokens(tb->ltb_text, ipaddrs, nip);
1055 list_del(&tb->ltb_list);
1057 if (!rc) { /* no match */
1058 lnet_free_text_buf(tb);
1062 /* split into separate networks */
1063 INIT_LIST_HEAD(¤t_nets);
1064 list_add(&tb->ltb_list, ¤t_nets);
1065 rc = lnet_splitnets(source, ¤t_nets);
1070 list_for_each(t, ¤t_nets) {
1071 tb = list_entry(t, struct lnet_text_buf, ltb_list);
1072 net1 = lnet_netspec2net(tb->ltb_text);
1073 LASSERT(net1 != LNET_NIDNET(LNET_NID_ANY));
1075 list_for_each(t2, &matched_nets) {
1076 tb2 = list_entry(t2, struct lnet_text_buf,
1078 net2 = lnet_netspec2net(tb2->ltb_text);
1079 LASSERT(net2 != LNET_NIDNET(LNET_NID_ANY));
1092 lnet_free_text_bufs(¤t_nets);
1096 list_for_each_safe(t, t2, ¤t_nets) {
1097 tb = list_entry(t, struct lnet_text_buf, ltb_list);
1099 list_del(&tb->ltb_list);
1100 list_add_tail(&tb->ltb_list, &matched_nets);
1102 len += snprintf(networks + len, sizeof(networks) - len,
1103 "%s%s", !len ? "" : ",",
1106 if (len >= sizeof(networks)) {
1107 CERROR("Too many matched networks\n");
1117 lnet_free_text_bufs(&raw_entries);
1118 lnet_free_text_bufs(&matched_nets);
1119 lnet_free_text_bufs(¤t_nets);
1120 LASSERT(!lnet_tbnob);
1125 *networksp = networks;
1130 lnet_ipaddr_enumerate(__u32 **ipaddrsp)
1138 int nif = lnet_ipif_enumerate(&ifnames);
1145 LIBCFS_ALLOC(ipaddrs, nif * sizeof(*ipaddrs));
1147 CERROR("Can't allocate ipaddrs[%d]\n", nif);
1148 lnet_ipif_free_enumeration(ifnames, nif);
1152 for (i = nip = 0; i < nif; i++) {
1153 if (!strcmp(ifnames[i], "lo"))
1156 rc = lnet_ipif_query(ifnames[i], &up, &ipaddrs[nip], &netmask);
1158 CWARN("Can't query interface %s: %d\n",
1164 CWARN("Ignoring interface %s: it's down\n",
1172 lnet_ipif_free_enumeration(ifnames, nif);
1175 *ipaddrsp = ipaddrs;
1178 LIBCFS_ALLOC(ipaddrs2, nip * sizeof(*ipaddrs2));
1180 CERROR("Can't allocate ipaddrs[%d]\n", nip);
1183 memcpy(ipaddrs2, ipaddrs,
1184 nip * sizeof(*ipaddrs));
1185 *ipaddrsp = ipaddrs2;
1189 LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
1195 lnet_parse_ip2nets(char **networksp, char *ip2nets)
1197 __u32 *ipaddrs = NULL;
1198 int nip = lnet_ipaddr_enumerate(&ipaddrs);
1202 LCONSOLE_ERROR_MSG(0x117,
1203 "Error %d enumerating local IP interfaces for ip2nets to match\n",
1209 LCONSOLE_ERROR_MSG(0x118,
1210 "No local IP interfaces for ip2nets to match\n");
1214 rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
1215 LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
1218 LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc);
1223 LCONSOLE_ERROR_MSG(0x11a,
1224 "ip2nets does not match any local IP interfaces\n");