1
1
openmpi/opal/mca/if/solaris_ipv6/if_solaris_ipv6.c
Ralph Castain bab990d812 Revert r23928 as being the incorrect fix. The correct fix is not to include ipv6 interfaces when ipv6 support was not requested.
This commit was SVN r23930.

The following SVN revision numbers were found above:
  r23928 --> open-mpi/ompi@7394f6d167
2010-10-25 14:31:18 +00:00

165 строки
5.0 KiB
C

/*
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "opal_config.h"
#include <stdlib.h>
#include <string.h>
#include "opal/constants.h"
#include "opal/util/output.h"
#include "opal/mca/if/if.h"
static int if_solaris_ipv6_open(void);
/* Discovers Solaris IPv6 interfaces */
opal_if_base_component_t mca_if_solaris_ipv6_component = {
/* First, the mca_component_t struct containing meta information
about the component itself */
{
OPAL_IF_BASE_VERSION_2_0_0,
/* Component name and version */
"solaris_ipv6",
OPAL_MAJOR_VERSION,
OPAL_MINOR_VERSION,
OPAL_RELEASE_VERSION,
/* Component open and close functions */
if_solaris_ipv6_open,
NULL
},
{
/* This component is checkpointable */
MCA_BASE_METADATA_PARAM_CHECKPOINT
},
};
/* configure using getifaddrs(3) */
static int if_solaris_ipv6_open(void)
{
#if OPAL_WANT_IPV6
int i;
int sd;
int error;
uint16_t kindex;
struct lifnum lifnum;
struct lifconf lifconf;
struct lifreq *lifreq, lifquery;
sd = socket (AF_INET6, SOCK_DGRAM, 0);
if (sd < 0) {
opal_output (0, "opal_ifinit: unable to open IPv6 socket\n");
return OPAL_ERROR;
}
/* we only ask for IPv6; IPv4 discovery has already been done */
lifnum.lifn_family = AF_INET6;
lifnum.lifn_flags = 0;
lifnum.lifn_count = 0;
/* get the number of interfaces in the system */
error = ioctl (sd, SIOCGLIFNUM, &lifnum);
if (error < 0) {
opal_output (0,
"opal_ifinit: ioctl SIOCGLIFNUM failed with errno=%d\n", errno);
return OPAL_ERROR;
}
memset (&lifconf, 0, sizeof (struct lifconf));
memset (&lifquery, 0, sizeof (struct lifreq));
lifconf.lifc_family = AF_INET6;
lifconf.lifc_flags = 0;
lifconf.lifc_len = lifnum.lifn_count * sizeof (struct lifreq) * 2;
lifconf.lifc_buf = malloc (lifconf.lifc_len);
if (NULL == lifconf.lifc_buf) {
opal_output (0, "opal_ifinit: IPv6 discovery: malloc() failed\n");
return OPAL_ERR_OUT_OF_RESOURCE;
}
memset (lifconf.lifc_buf, 0, lifconf.lifc_len);
error = ioctl (sd, SIOCGLIFCONF, &lifconf);
if (error < 0) {
opal_output (0,
"opal_ifinit: IPv6 SIOCGLIFCONF failed with errno=%d\n", errno);
}
for (i = 0; i + sizeof (struct lifreq) <= lifconf.lifc_len;
i += sizeof (*lifreq)) {
lifreq = (struct lifreq *)((caddr_t)lifconf.lifc_buf + i);
strncpy (lifquery.lifr_name, lifreq->lifr_name,
sizeof (lifquery.lifr_name));
/* lookup kernel index */
error = ioctl (sd, SIOCGLIFINDEX, &lifquery);
if (error < 0) {
opal_output (0,
"opal_ifinit: SIOCGLIFINDEX failed with errno=%d\n", errno);
return OPAL_ERROR;
}
kindex = lifquery.lifr_index;
/* lookup interface flags */
error = ioctl (sd, SIOCGLIFFLAGS, &lifquery);
if (error < 0) {
opal_output (0,
"opal_ifinit: SIOCGLIFFLAGS failed with errno=%d\n", errno);
return OPAL_ERROR;
}
if (AF_INET6 == lifreq->lifr_addr.ss_family) {
struct sockaddr_in6* my_addr = (struct sockaddr_in6*) &lifreq->lifr_addr;
/* we surely want to check for sin6_scope_id, but Solaris
does not set it correctly, so we have to look for
global scope. For now, global is anything which is
neither loopback nor link local.
Bug, FIXME: site-local, multicast, ... missing
Check for 2000::/3?
*/
if ( (!opal_if_retain_loopback && !IN6_IS_ADDR_LOOPBACK (&my_addr->sin6_addr)) &&
(! IN6_IS_ADDR_LINKLOCAL (&my_addr->sin6_addr))) {
/* create interface for newly found address */
opal_if_t *intf;
intf = OBJ_NEW(opal_if_t);
if (NULL == intf) {
opal_output (0,
"opal_ifinit: unable to allocate %d bytes\n",
sizeof (opal_if_t));
return OPAL_ERR_OUT_OF_RESOURCE;
}
strncpy (intf->if_name, lifreq->lifr_name, IF_NAMESIZE);
intf->if_index = opal_list_get_size(&opal_if_list)+1;
memcpy(&intf->if_addr, my_addr, sizeof (*my_addr));
intf->if_mask = 64;
/* lifrq flags are uint64_t */
intf->if_flags =
(uint32_t)(0x00000000ffffffff) & lifquery.lifr_flags;
/* append to list */
opal_list_append (&opal_if_list, &(intf->super));
}
}
} /* for */
if (NULL != lifconf.lifc_buf) {
free (lifconf.lifc_buf);
}
#endif /* OPAL_WANT_IPV6 */
return OPAL_SUCCESS;
}