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
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
#include <ifaddrs.h>
#endif
#include <ctype.h>
#include "opal/class/opal_list.h"
#include "opal/util/if.h"
#include "opal/util/output.h"
#include "opal/util/argv.h"
#include "opal/util/show_help.h"
#include "opal/constants.h"
#include "opal/mca/if/base/base.h"
@ -601,6 +603,57 @@ bool opal_ifisloopback(int if_index)
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 */
@ -693,5 +746,10 @@ opal_iftupletoaddr(char *inaddr, uint32_t *net, uint32_t *mask)
return 0;
}
bool opal_ifispresent(char *if)
{
return false;
}
#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);
/*
* 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

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

@ -25,4 +25,11 @@ Dynamic ports: %s
Only one can be specified. Please choose either static or
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;
bool found_local = false;
bool found_nonlocal = false;
char **interfaces = NULL;
mca_oob_tcp_device_t *dev;
bool including = true;
char name[32];
*priority = 1;
/* are there any interfaces? */
if(opal_ifcount() <= 0)
if (opal_ifcount() <= 0) {
return NULL;
}
/* Which interfaces should we use? Start by building a list of
all devices that meet the requirements of the if_include and
if_exclude list. This might include local and non-local
interfaces mixed together. After that sorting is done, if there
is a mix of devices, we go through the devices that survived
the initial sort and remove all the local devices (since we
have non-local devices to use). */
/* did someone mistakenly specify both includes AND excludes? */
if (NULL != mca_oob_tcp_component.tcp_include &&
NULL != mca_oob_tcp_component.tcp_exclude) {
orte_show_help("help-oob-tcp.txt", "include-exclude", true,
mca_oob_tcp_component.tcp_include,
mca_oob_tcp_component.tcp_exclude);
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)) {
char name[32];
mca_oob_tcp_device_t *dev;
/* get the name for diagnostic purposes */
opal_ifindextoname(i, name, sizeof(name));
if (mca_oob_tcp_component.tcp_include != NULL &&
strstr(mca_oob_tcp_component.tcp_include,name) == NULL) {
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;
}
if (mca_oob_tcp_component.tcp_exclude != NULL &&
strstr(mca_oob_tcp_component.tcp_exclude,name) != NULL) {
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;
/* handle include/exclude directives */
if (NULL != interfaces) {
/* if we are including, then ignore this if not present */
if (including) {
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;
}
} else {
/* we are excluding, so ignore if present */
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);
@ -1353,6 +1379,13 @@ mca_oob_t* mca_oob_tcp_component_init(int* priority)
opal_list_append(&mca_oob_tcp_component.tcp_available_devices,
&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) {
opal_list_item_t *item, *next;
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_free_list_init(&mca_oob_tcp_component.tcp_peer_free,
sizeof(mca_oob_tcp_peer_t),
OBJ_CLASS(mca_oob_tcp_peer_t),
8, /* initial number */
mca_oob_tcp_component.tcp_peer_limit, /* maximum number */
8); /* increment to grow by */
sizeof(mca_oob_tcp_peer_t),
OBJ_CLASS(mca_oob_tcp_peer_t),
8, /* initial number */
mca_oob_tcp_component.tcp_peer_limit, /* maximum number */
8); /* increment to grow by */
opal_free_list_init(&mca_oob_tcp_component.tcp_msgs,
sizeof(mca_oob_tcp_msg_t),
OBJ_CLASS(mca_oob_tcp_msg_t),
8, /* initial number */
-1, /* maximum number */
8); /* increment to grow by */
sizeof(mca_oob_tcp_msg_t),
OBJ_CLASS(mca_oob_tcp_msg_t),
8, /* initial number */
-1, /* maximum number */
8); /* increment to grow by */
/* intialize event library */