c04a0efc16119f225581712d0784ec44b64f9310
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
)
753 LASSERT(!list_empty(&nets
));
754 LASSERT(!list_empty(&gateways
));
756 list_for_each(tmp1
, &nets
) {
757 ltb
= list_entry(tmp1
, struct lnet_text_buf
, ltb_list
);
758 net
= libcfs_str2net(ltb
->ltb_text
);
759 LASSERT(net
!= LNET_NIDNET(LNET_NID_ANY
));
761 list_for_each(tmp2
, &gateways
) {
762 ltb
= list_entry(tmp2
, struct lnet_text_buf
, ltb_list
);
763 nid
= libcfs_str2nid(ltb
->ltb_text
);
764 LASSERT(nid
!= LNET_NID_ANY
);
766 if (lnet_islocalnid(nid
)) {
771 rc
= lnet_add_route(net
, hops
, nid
, priority
);
773 CERROR("Can't create route to %s via %s\n",
775 libcfs_nid2str(nid
));
785 lnet_syntax("routes", cmd
, (int)(token
- str
), strlen(token
));
787 lnet_free_text_bufs(&nets
);
788 lnet_free_text_bufs(&gateways
);
793 lnet_parse_route_tbs(struct list_head
*tbs
, int *im_a_router
)
795 struct lnet_text_buf
*ltb
;
797 while (!list_empty(tbs
)) {
798 ltb
= list_entry(tbs
->next
, struct lnet_text_buf
, ltb_list
);
800 if (lnet_parse_route(ltb
->ltb_text
, im_a_router
) < 0) {
801 lnet_free_text_bufs(tbs
);
805 list_del(<b
->ltb_list
);
806 lnet_free_text_buf(ltb
);
813 lnet_parse_routes(char *routes
, int *im_a_router
)
815 struct list_head tbs
;
820 INIT_LIST_HEAD(&tbs
);
822 if (lnet_str2tbs_sep(&tbs
, routes
) < 0) {
823 CERROR("Error parsing routes\n");
826 rc
= lnet_parse_route_tbs(&tbs
, im_a_router
);
829 LASSERT(!lnet_tbnob
);
834 lnet_match_network_token(char *token
, int len
, __u32
*ipaddrs
, int nip
)
840 rc
= cfs_ip_addr_parse(token
, len
, &list
);
844 for (rc
= i
= 0; !rc
&& i
< nip
; i
++)
845 rc
= cfs_ip_addr_match(ipaddrs
[i
], &list
);
847 cfs_expr_list_free_list(&list
);
853 lnet_match_network_tokens(char *net_entry
, __u32
*ipaddrs
, int nip
)
855 static char tokens
[LNET_SINGLE_TEXTBUF_NOB
];
865 LASSERT(strlen(net_entry
) < sizeof(tokens
));
867 /* work on a copy of the string */
868 strcpy(tokens
, net_entry
);
871 /* scan for token start */
872 while (isspace(*sep
))
879 /* scan for token end */
880 while (*sep
&& !isspace(*sep
))
892 rc
= lnet_match_network_token(token
, len
, ipaddrs
, nip
);
894 lnet_syntax("ip2nets", net_entry
,
895 (int)(token
- tokens
), len
);
906 strcpy(net_entry
, net
); /* replace with matched net */
911 lnet_netspec2net(char *netspec
)
913 char *bracket
= strchr(netspec
, '(');
919 net
= libcfs_str2net(netspec
);
928 lnet_splitnets(char *source
, struct list_head
*nets
)
933 struct lnet_text_buf
*tb
;
934 struct lnet_text_buf
*tb2
;
940 LASSERT(!list_empty(nets
));
941 LASSERT(nets
->next
== nets
->prev
); /* single entry */
943 tb
= list_entry(nets
->next
, struct lnet_text_buf
, ltb_list
);
946 sep
= strchr(tb
->ltb_text
, ',');
947 bracket
= strchr(tb
->ltb_text
, '(');
949 if (sep
&& bracket
&& bracket
< sep
) {
950 /* netspec lists interfaces... */
952 offset2
= offset
+ (int)(bracket
- tb
->ltb_text
);
953 len
= strlen(bracket
);
955 bracket
= strchr(bracket
+ 1, ')');
958 !(bracket
[1] == ',' || !bracket
[1])) {
959 lnet_syntax("ip2nets", source
, offset2
, len
);
963 sep
= !bracket
[1] ? NULL
: bracket
+ 1;
969 net
= lnet_netspec2net(tb
->ltb_text
);
970 if (net
== LNET_NIDNET(LNET_NID_ANY
)) {
971 lnet_syntax("ip2nets", source
, offset
,
972 strlen(tb
->ltb_text
));
976 list_for_each(t
, nets
) {
977 tb2
= list_entry(t
, struct lnet_text_buf
, ltb_list
);
982 if (net
== lnet_netspec2net(tb2
->ltb_text
)) {
983 /* duplicate network */
984 lnet_syntax("ip2nets", source
, offset
,
985 strlen(tb
->ltb_text
));
993 offset
+= (int)(sep
- tb
->ltb_text
);
995 tb2
= lnet_new_text_buf(len
);
999 strncpy(tb2
->ltb_text
, sep
, len
);
1000 tb2
->ltb_text
[len
] = '\0';
1001 list_add_tail(&tb2
->ltb_list
, nets
);
1008 lnet_match_networks(char **networksp
, char *ip2nets
, __u32
*ipaddrs
, int nip
)
1010 static char networks
[LNET_SINGLE_TEXTBUF_NOB
];
1011 static char source
[LNET_SINGLE_TEXTBUF_NOB
];
1013 struct list_head raw_entries
;
1014 struct list_head matched_nets
;
1015 struct list_head current_nets
;
1016 struct list_head
*t
;
1017 struct list_head
*t2
;
1018 struct lnet_text_buf
*tb
;
1019 struct lnet_text_buf
*tb2
;
1027 INIT_LIST_HEAD(&raw_entries
);
1028 if (lnet_str2tbs_sep(&raw_entries
, ip2nets
) < 0) {
1029 CERROR("Error parsing ip2nets\n");
1030 LASSERT(!lnet_tbnob
);
1034 INIT_LIST_HEAD(&matched_nets
);
1035 INIT_LIST_HEAD(¤t_nets
);
1041 while (!list_empty(&raw_entries
)) {
1042 tb
= list_entry(raw_entries
.next
, struct lnet_text_buf
,
1044 strncpy(source
, tb
->ltb_text
, sizeof(source
));
1045 source
[sizeof(source
) - 1] = '\0';
1047 /* replace ltb_text with the network(s) add on match */
1048 rc
= lnet_match_network_tokens(tb
->ltb_text
, ipaddrs
, nip
);
1052 list_del(&tb
->ltb_list
);
1054 if (!rc
) { /* no match */
1055 lnet_free_text_buf(tb
);
1059 /* split into separate networks */
1060 INIT_LIST_HEAD(¤t_nets
);
1061 list_add(&tb
->ltb_list
, ¤t_nets
);
1062 rc
= lnet_splitnets(source
, ¤t_nets
);
1067 list_for_each(t
, ¤t_nets
) {
1068 tb
= list_entry(t
, struct lnet_text_buf
, ltb_list
);
1069 net1
= lnet_netspec2net(tb
->ltb_text
);
1070 LASSERT(net1
!= LNET_NIDNET(LNET_NID_ANY
));
1072 list_for_each(t2
, &matched_nets
) {
1073 tb2
= list_entry(t2
, struct lnet_text_buf
,
1075 net2
= lnet_netspec2net(tb2
->ltb_text
);
1076 LASSERT(net2
!= LNET_NIDNET(LNET_NID_ANY
));
1089 lnet_free_text_bufs(¤t_nets
);
1093 list_for_each_safe(t
, t2
, ¤t_nets
) {
1094 tb
= list_entry(t
, struct lnet_text_buf
, ltb_list
);
1096 list_del(&tb
->ltb_list
);
1097 list_add_tail(&tb
->ltb_list
, &matched_nets
);
1099 len
+= snprintf(networks
+ len
, sizeof(networks
) - len
,
1100 "%s%s", !len
? "" : ",",
1103 if (len
>= sizeof(networks
)) {
1104 CERROR("Too many matched networks\n");
1114 lnet_free_text_bufs(&raw_entries
);
1115 lnet_free_text_bufs(&matched_nets
);
1116 lnet_free_text_bufs(¤t_nets
);
1117 LASSERT(!lnet_tbnob
);
1122 *networksp
= networks
;
1127 lnet_ipaddr_enumerate(__u32
**ipaddrsp
)
1135 int nif
= lnet_ipif_enumerate(&ifnames
);
1142 LIBCFS_ALLOC(ipaddrs
, nif
* sizeof(*ipaddrs
));
1144 CERROR("Can't allocate ipaddrs[%d]\n", nif
);
1145 lnet_ipif_free_enumeration(ifnames
, nif
);
1149 for (i
= nip
= 0; i
< nif
; i
++) {
1150 if (!strcmp(ifnames
[i
], "lo"))
1153 rc
= lnet_ipif_query(ifnames
[i
], &up
, &ipaddrs
[nip
], &netmask
);
1155 CWARN("Can't query interface %s: %d\n",
1161 CWARN("Ignoring interface %s: it's down\n",
1169 lnet_ipif_free_enumeration(ifnames
, nif
);
1172 *ipaddrsp
= ipaddrs
;
1175 LIBCFS_ALLOC(ipaddrs2
, nip
* sizeof(*ipaddrs2
));
1177 CERROR("Can't allocate ipaddrs[%d]\n", nip
);
1180 memcpy(ipaddrs2
, ipaddrs
,
1181 nip
* sizeof(*ipaddrs
));
1182 *ipaddrsp
= ipaddrs2
;
1186 LIBCFS_FREE(ipaddrs
, nip
* sizeof(*ipaddrs
));
1192 lnet_parse_ip2nets(char **networksp
, char *ip2nets
)
1194 __u32
*ipaddrs
= NULL
;
1195 int nip
= lnet_ipaddr_enumerate(&ipaddrs
);
1199 LCONSOLE_ERROR_MSG(0x117,
1200 "Error %d enumerating local IP interfaces for ip2nets to match\n",
1206 LCONSOLE_ERROR_MSG(0x118,
1207 "No local IP interfaces for ip2nets to match\n");
1211 rc
= lnet_match_networks(networksp
, ip2nets
, ipaddrs
, nip
);
1212 LIBCFS_FREE(ipaddrs
, nip
* sizeof(*ipaddrs
));
1215 LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc
);
1220 LCONSOLE_ERROR_MSG(0x11a,
1221 "ip2nets does not match any local IP interfaces\n");
This page took 0.053248 seconds and 4 git commands to generate.