Skip to content

Commit 1491d52

Browse files
author
Ralph Castain
committed
Extend the parsing capability of the oob tcp module's if_include and if_exclude options to support subnet+mask notation, and to handle virtual IP addresses (it was previously having problems distinguishing between "eth1" and "eth1.3").
This commit was SVN r24747.
1 parent d1fdbad commit 1491d52

File tree

5 files changed

+150
-33
lines changed

5 files changed

+150
-33
lines changed

opal/util/help-opal-util.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,18 @@ of the form <ipaddress>/<mask>. For example:
3535

3636
All malformed entries will be ignored; Open MPI will attempt to continue
3737
your job. The first detected malformed entry was %s.
38+
#
39+
[invalid-net-mask]
40+
We were unable to parse the provided network interface:
41+
42+
Interface: %s
43+
44+
The interface must be one of the following forms:
45+
46+
123.456.789.123
47+
123.456/16
48+
123.456.789
49+
50+
The system can parse any one of these, and will find an interface
51+
that matches within the provided scope. Please revise your input
52+
and try again.

opal/util/if.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,13 @@
6868
#ifdef HAVE_IFADDRS_H
6969
#include <ifaddrs.h>
7070
#endif
71+
#include <ctype.h>
7172

7273
#include "opal/class/opal_list.h"
7374
#include "opal/util/if.h"
7475
#include "opal/util/output.h"
7576
#include "opal/util/argv.h"
77+
#include "opal/util/show_help.h"
7678
#include "opal/constants.h"
7779

7880
#include "opal/mca/if/base/base.h"
@@ -601,6 +603,57 @@ bool opal_ifisloopback(int if_index)
601603
return false;
602604
}
603605

606+
/* Determine if an interface matches any entry in the given list, taking
607+
* into account that the list entries could be given as named interfaces,
608+
* IP addrs, or subnet+mask
609+
*/
610+
bool opal_ifmatches(int idx, char **nets)
611+
{
612+
bool named_if;
613+
int i;
614+
size_t j;
615+
int index;
616+
struct sockaddr_in inaddr;
617+
uint32_t addr, netaddr, netmask;
618+
619+
/* get the address info for the given network in case we need it */
620+
if (OPAL_SUCCESS != opal_ifindextoaddr(idx, (struct sockaddr*)&inaddr, sizeof(inaddr))) {
621+
return false;
622+
}
623+
addr = ntohl(inaddr.sin_addr.s_addr);
624+
625+
for (i=0; NULL != nets[i]; i++) {
626+
/* if the specified interface contains letters in it, then it
627+
* was given as an interface name and not an IP tuple
628+
*/
629+
named_if = false;
630+
for (j=0; j < strlen(nets[i]); j++) {
631+
if (isalpha(nets[i][j]) && '.' != nets[i][j]) {
632+
named_if = true;
633+
break;
634+
}
635+
}
636+
if (named_if) {
637+
if (0 > (index = opal_ifnametoindex(nets[i]))) {
638+
continue;
639+
}
640+
if (index == idx) {
641+
return true;
642+
}
643+
} else {
644+
if (OPAL_SUCCESS != opal_iftupletoaddr(nets[i], &netaddr, &netmask)) {
645+
opal_show_help("help-opal-util.txt", "invalid-net-mask", true, nets[i]);
646+
continue;
647+
}
648+
if (netaddr == (addr & netmask)) {
649+
return true;
650+
}
651+
}
652+
}
653+
/* get here if not found */
654+
return false;
655+
}
656+
604657

605658
#else /* HAVE_STRUCT_SOCKADDR_IN */
606659

@@ -693,5 +746,10 @@ opal_iftupletoaddr(char *inaddr, uint32_t *net, uint32_t *mask)
693746
return 0;
694747
}
695748

749+
bool opal_ifispresent(char *if)
750+
{
751+
return false;
752+
}
753+
696754
#endif /* HAVE_STRUCT_SOCKADDR_IN */
697755

opal/util/if.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ OPAL_DECLSPEC int opal_iftupletoaddr(const char *addr, uint32_t *net, uint32_t *
188188
*/
189189
OPAL_DECLSPEC bool opal_ifisloopback(int if_index);
190190

191+
/*
192+
* Determine if a specified interface is included in a NULL-terminated argv array
193+
*/
194+
OPAL_DECLSPEC bool opal_ifmatches(int idx, char **nets);
191195

192196
END_C_DECLS
193197

orte/mca/oob/tcp/help-oob-tcp.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,11 @@ Dynamic ports: %s
2525

2626
Only one can be specified. Please choose either static or
2727
dynamic ports and try again.
28+
#
29+
[include-exclude]
30+
Both TCP interface include and exclude lists were specified:
31+
32+
Include: %s
33+
Exclude: %s
2834

35+
Only one of these can be given.

orte/mca/oob/tcp/oob_tcp.c

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,39 +1299,65 @@ mca_oob_t* mca_oob_tcp_component_init(int* priority)
12991299
int i;
13001300
bool found_local = false;
13011301
bool found_nonlocal = false;
1302+
char **interfaces = NULL;
1303+
mca_oob_tcp_device_t *dev;
1304+
bool including = true;
1305+
char name[32];
13021306

13031307
*priority = 1;
13041308

13051309
/* are there any interfaces? */
1306-
if(opal_ifcount() <= 0)
1310+
if (opal_ifcount() <= 0) {
13071311
return NULL;
1312+
}
1313+
1314+
/* did someone mistakenly specify both includes AND excludes? */
1315+
if (NULL != mca_oob_tcp_component.tcp_include &&
1316+
NULL != mca_oob_tcp_component.tcp_exclude) {
1317+
orte_show_help("help-oob-tcp.txt", "include-exclude", true,
1318+
mca_oob_tcp_component.tcp_include,
1319+
mca_oob_tcp_component.tcp_exclude);
1320+
return NULL;
1321+
}
13081322

1309-
/* Which interfaces should we use? Start by building a list of
1310-
all devices that meet the requirements of the if_include and
1311-
if_exclude list. This might include local and non-local
1312-
interfaces mixed together. After that sorting is done, if there
1313-
is a mix of devices, we go through the devices that survived
1314-
the initial sort and remove all the local devices (since we
1315-
have non-local devices to use). */
1323+
/* if interface include was given, construct a list
1324+
* of those interfaces which match the specifications - remember,
1325+
* the includes could be given as named interfaces, IP addrs, or
1326+
* subnet+mask
1327+
*/
1328+
if (NULL != mca_oob_tcp_component.tcp_include) {
1329+
interfaces = opal_argv_split(mca_oob_tcp_component.tcp_include, ',');
1330+
including = true;
1331+
} else if (NULL != mca_oob_tcp_component.tcp_exclude) {
1332+
interfaces = opal_argv_split(mca_oob_tcp_component.tcp_exclude, ',');
1333+
including = false;
1334+
}
1335+
1336+
/* look at all available interfaces */
13161337
for (i = opal_ifbegin() ; i > 0 ; i = opal_ifnext(i)) {
1317-
char name[32];
1318-
mca_oob_tcp_device_t *dev;
13191338

1339+
/* get the name for diagnostic purposes */
13201340
opal_ifindextoname(i, name, sizeof(name));
13211341

1322-
if (mca_oob_tcp_component.tcp_include != NULL &&
1323-
strstr(mca_oob_tcp_component.tcp_include,name) == NULL) {
1324-
OPAL_OUTPUT_VERBOSE((1, mca_oob_tcp_output_handle,
1325-
"%s oob:tcp:init rejecting interface %s",
1326-
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), name));
1327-
continue;
1328-
}
1329-
if (mca_oob_tcp_component.tcp_exclude != NULL &&
1330-
strstr(mca_oob_tcp_component.tcp_exclude,name) != NULL) {
1331-
OPAL_OUTPUT_VERBOSE((1, mca_oob_tcp_output_handle,
1332-
"%s oob:tcp:init rejecting interface %s",
1333-
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), name));
1334-
continue;
1342+
/* handle include/exclude directives */
1343+
if (NULL != interfaces) {
1344+
/* if we are including, then ignore this if not present */
1345+
if (including) {
1346+
if (!opal_ifmatches(i, interfaces)) {
1347+
OPAL_OUTPUT_VERBOSE((1, mca_oob_tcp_output_handle,
1348+
"%s oob:tcp:init rejecting interface %s",
1349+
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), name));
1350+
continue;
1351+
}
1352+
} else {
1353+
/* we are excluding, so ignore if present */
1354+
if (opal_ifmatches(i, interfaces)) {
1355+
OPAL_OUTPUT_VERBOSE((1, mca_oob_tcp_output_handle,
1356+
"%s oob:tcp:init rejecting interface %s",
1357+
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), name));
1358+
continue;
1359+
}
1360+
}
13351361
}
13361362

13371363
dev = OBJ_NEW(mca_oob_tcp_device_t);
@@ -1353,6 +1379,13 @@ mca_oob_t* mca_oob_tcp_component_init(int* priority)
13531379
opal_list_append(&mca_oob_tcp_component.tcp_available_devices,
13541380
&dev->super);
13551381
}
1382+
1383+
/* cleanup */
1384+
if (NULL != interfaces) {
1385+
opal_argv_free(interfaces);
1386+
}
1387+
1388+
/* remove all the local devices if we have non-local devices to use. */
13561389
if (found_local && found_nonlocal) {
13571390
opal_list_item_t *item, *next;
13581391
for (item = opal_list_get_first(&mca_oob_tcp_component.tcp_available_devices) ;
@@ -1377,18 +1410,18 @@ mca_oob_t* mca_oob_tcp_component_init(int* priority)
13771410
opal_hash_table_init(&mca_oob_tcp_component.tcp_peer_names, 128);
13781411

13791412
opal_free_list_init(&mca_oob_tcp_component.tcp_peer_free,
1380-
sizeof(mca_oob_tcp_peer_t),
1381-
OBJ_CLASS(mca_oob_tcp_peer_t),
1382-
8, /* initial number */
1383-
mca_oob_tcp_component.tcp_peer_limit, /* maximum number */
1384-
8); /* increment to grow by */
1413+
sizeof(mca_oob_tcp_peer_t),
1414+
OBJ_CLASS(mca_oob_tcp_peer_t),
1415+
8, /* initial number */
1416+
mca_oob_tcp_component.tcp_peer_limit, /* maximum number */
1417+
8); /* increment to grow by */
13851418

13861419
opal_free_list_init(&mca_oob_tcp_component.tcp_msgs,
1387-
sizeof(mca_oob_tcp_msg_t),
1388-
OBJ_CLASS(mca_oob_tcp_msg_t),
1389-
8, /* initial number */
1390-
-1, /* maximum number */
1391-
8); /* increment to grow by */
1420+
sizeof(mca_oob_tcp_msg_t),
1421+
OBJ_CLASS(mca_oob_tcp_msg_t),
1422+
8, /* initial number */
1423+
-1, /* maximum number */
1424+
8); /* increment to grow by */
13921425

13931426

13941427
/* intialize event library */

0 commit comments

Comments
 (0)