1
1

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.
Этот коммит содержится в:
Ralph Castain 2011-06-05 19:16:42 +00:00
родитель d1fdbadc91
Коммит 1491d52bd7
5 изменённых файлов: 150 добавлений и 33 удалений

Просмотреть файл

@ -35,3 +35,18 @@ of the form <ipaddress>/<mask>. For example:
All malformed entries will be ignored; Open MPI will attempt to continue All malformed entries will be ignored; Open MPI will attempt to continue
your job. The first detected malformed entry was %s. your job. The first detected malformed entry was %s.
#
[invalid-net-mask]
We were unable to parse the provided network interface:
Interface: %s
The interface must be one of the following forms:
123.456.789.123
123.456/16
123.456.789
The system can parse any one of these, and will find an interface
that matches within the provided scope. Please revise your input
and try again.

Просмотреть файл

@ -68,11 +68,13 @@
#ifdef HAVE_IFADDRS_H #ifdef HAVE_IFADDRS_H
#include <ifaddrs.h> #include <ifaddrs.h>
#endif #endif
#include <ctype.h>
#include "opal/class/opal_list.h" #include "opal/class/opal_list.h"
#include "opal/util/if.h" #include "opal/util/if.h"
#include "opal/util/output.h" #include "opal/util/output.h"
#include "opal/util/argv.h" #include "opal/util/argv.h"
#include "opal/util/show_help.h"
#include "opal/constants.h" #include "opal/constants.h"
#include "opal/mca/if/base/base.h" #include "opal/mca/if/base/base.h"
@ -601,6 +603,57 @@ bool opal_ifisloopback(int if_index)
return false; return false;
} }
/* Determine if an interface matches any entry in the given list, taking
* into account that the list entries could be given as named interfaces,
* IP addrs, or subnet+mask
*/
bool opal_ifmatches(int idx, char **nets)
{
bool named_if;
int i;
size_t j;
int index;
struct sockaddr_in inaddr;
uint32_t addr, netaddr, netmask;
/* get the address info for the given network in case we need it */
if (OPAL_SUCCESS != opal_ifindextoaddr(idx, (struct sockaddr*)&inaddr, sizeof(inaddr))) {
return false;
}
addr = ntohl(inaddr.sin_addr.s_addr);
for (i=0; NULL != nets[i]; i++) {
/* if the specified interface contains letters in it, then it
* was given as an interface name and not an IP tuple
*/
named_if = false;
for (j=0; j < strlen(nets[i]); j++) {
if (isalpha(nets[i][j]) && '.' != nets[i][j]) {
named_if = true;
break;
}
}
if (named_if) {
if (0 > (index = opal_ifnametoindex(nets[i]))) {
continue;
}
if (index == idx) {
return true;
}
} else {
if (OPAL_SUCCESS != opal_iftupletoaddr(nets[i], &netaddr, &netmask)) {
opal_show_help("help-opal-util.txt", "invalid-net-mask", true, nets[i]);
continue;
}
if (netaddr == (addr & netmask)) {
return true;
}
}
}
/* get here if not found */
return false;
}
#else /* HAVE_STRUCT_SOCKADDR_IN */ #else /* HAVE_STRUCT_SOCKADDR_IN */
@ -693,5 +746,10 @@ opal_iftupletoaddr(char *inaddr, uint32_t *net, uint32_t *mask)
return 0; return 0;
} }
bool opal_ifispresent(char *if)
{
return false;
}
#endif /* HAVE_STRUCT_SOCKADDR_IN */ #endif /* HAVE_STRUCT_SOCKADDR_IN */

Просмотреть файл

@ -188,6 +188,10 @@ OPAL_DECLSPEC int opal_iftupletoaddr(const char *addr, uint32_t *net, uint32_t *
*/ */
OPAL_DECLSPEC bool opal_ifisloopback(int if_index); OPAL_DECLSPEC bool opal_ifisloopback(int if_index);
/*
* Determine if a specified interface is included in a NULL-terminated argv array
*/
OPAL_DECLSPEC bool opal_ifmatches(int idx, char **nets);
END_C_DECLS END_C_DECLS

Просмотреть файл

@ -25,4 +25,11 @@ Dynamic ports: %s
Only one can be specified. Please choose either static or Only one can be specified. Please choose either static or
dynamic ports and try again. dynamic ports and try again.
#
[include-exclude]
Both TCP interface include and exclude lists were specified:
Include: %s
Exclude: %s
Only one of these can be given.

Просмотреть файл

@ -1299,39 +1299,65 @@ mca_oob_t* mca_oob_tcp_component_init(int* priority)
int i; int i;
bool found_local = false; bool found_local = false;
bool found_nonlocal = false; bool found_nonlocal = false;
char **interfaces = NULL;
mca_oob_tcp_device_t *dev;
bool including = true;
char name[32];
*priority = 1; *priority = 1;
/* are there any interfaces? */ /* are there any interfaces? */
if(opal_ifcount() <= 0) if (opal_ifcount() <= 0) {
return NULL; return NULL;
}
/* Which interfaces should we use? Start by building a list of /* did someone mistakenly specify both includes AND excludes? */
all devices that meet the requirements of the if_include and if (NULL != mca_oob_tcp_component.tcp_include &&
if_exclude list. This might include local and non-local NULL != mca_oob_tcp_component.tcp_exclude) {
interfaces mixed together. After that sorting is done, if there orte_show_help("help-oob-tcp.txt", "include-exclude", true,
is a mix of devices, we go through the devices that survived mca_oob_tcp_component.tcp_include,
the initial sort and remove all the local devices (since we mca_oob_tcp_component.tcp_exclude);
have non-local devices to use). */ return NULL;
}
/* if interface include was given, construct a list
* of those interfaces which match the specifications - remember,
* the includes could be given as named interfaces, IP addrs, or
* subnet+mask
*/
if (NULL != mca_oob_tcp_component.tcp_include) {
interfaces = opal_argv_split(mca_oob_tcp_component.tcp_include, ',');
including = true;
} else if (NULL != mca_oob_tcp_component.tcp_exclude) {
interfaces = opal_argv_split(mca_oob_tcp_component.tcp_exclude, ',');
including = false;
}
/* look at all available interfaces */
for (i = opal_ifbegin() ; i > 0 ; i = opal_ifnext(i)) { for (i = opal_ifbegin() ; i > 0 ; i = opal_ifnext(i)) {
char name[32];
mca_oob_tcp_device_t *dev;
/* get the name for diagnostic purposes */
opal_ifindextoname(i, name, sizeof(name)); opal_ifindextoname(i, name, sizeof(name));
if (mca_oob_tcp_component.tcp_include != NULL && /* handle include/exclude directives */
strstr(mca_oob_tcp_component.tcp_include,name) == NULL) { if (NULL != interfaces) {
OPAL_OUTPUT_VERBOSE((1, mca_oob_tcp_output_handle, /* if we are including, then ignore this if not present */
"%s oob:tcp:init rejecting interface %s", if (including) {
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), name)); if (!opal_ifmatches(i, interfaces)) {
continue; OPAL_OUTPUT_VERBOSE((1, mca_oob_tcp_output_handle,
} "%s oob:tcp:init rejecting interface %s",
if (mca_oob_tcp_component.tcp_exclude != NULL && ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), name));
strstr(mca_oob_tcp_component.tcp_exclude,name) != NULL) { continue;
OPAL_OUTPUT_VERBOSE((1, mca_oob_tcp_output_handle, }
"%s oob:tcp:init rejecting interface %s", } else {
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), name)); /* we are excluding, so ignore if present */
continue; if (opal_ifmatches(i, interfaces)) {
OPAL_OUTPUT_VERBOSE((1, mca_oob_tcp_output_handle,
"%s oob:tcp:init rejecting interface %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), name));
continue;
}
}
} }
dev = OBJ_NEW(mca_oob_tcp_device_t); dev = OBJ_NEW(mca_oob_tcp_device_t);
@ -1353,6 +1379,13 @@ mca_oob_t* mca_oob_tcp_component_init(int* priority)
opal_list_append(&mca_oob_tcp_component.tcp_available_devices, opal_list_append(&mca_oob_tcp_component.tcp_available_devices,
&dev->super); &dev->super);
} }
/* cleanup */
if (NULL != interfaces) {
opal_argv_free(interfaces);
}
/* remove all the local devices if we have non-local devices to use. */
if (found_local && found_nonlocal) { if (found_local && found_nonlocal) {
opal_list_item_t *item, *next; opal_list_item_t *item, *next;
for (item = opal_list_get_first(&mca_oob_tcp_component.tcp_available_devices) ; 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)
opal_hash_table_init(&mca_oob_tcp_component.tcp_peer_names, 128); opal_hash_table_init(&mca_oob_tcp_component.tcp_peer_names, 128);
opal_free_list_init(&mca_oob_tcp_component.tcp_peer_free, opal_free_list_init(&mca_oob_tcp_component.tcp_peer_free,
sizeof(mca_oob_tcp_peer_t), sizeof(mca_oob_tcp_peer_t),
OBJ_CLASS(mca_oob_tcp_peer_t), OBJ_CLASS(mca_oob_tcp_peer_t),
8, /* initial number */ 8, /* initial number */
mca_oob_tcp_component.tcp_peer_limit, /* maximum number */ mca_oob_tcp_component.tcp_peer_limit, /* maximum number */
8); /* increment to grow by */ 8); /* increment to grow by */
opal_free_list_init(&mca_oob_tcp_component.tcp_msgs, opal_free_list_init(&mca_oob_tcp_component.tcp_msgs,
sizeof(mca_oob_tcp_msg_t), sizeof(mca_oob_tcp_msg_t),
OBJ_CLASS(mca_oob_tcp_msg_t), OBJ_CLASS(mca_oob_tcp_msg_t),
8, /* initial number */ 8, /* initial number */
-1, /* maximum number */ -1, /* maximum number */
8); /* increment to grow by */ 8); /* increment to grow by */
/* intialize event library */ /* intialize event library */