1
1
openmpi/opal/mca/if/solaris_ipv6/if_solaris_ipv6.c
William Zhang 4ebb37a26c opal/util: Change opal/util/if.h macro IF_NAMESIZE to OPAL_IF_NAMESIZE
Due to IF_NAMESIZE being a reused and conditionally defined macro,
issues could arise from macro mismatches. In particular, in cases where
opal/util/if.h is included, but net/if.h is not, IF_NAMESIZE will be 32.
If net/if.h is included on Linux systems, IF_NAMESIZE will be 16. This
can cause a mismatch when using the same macro on a system. Thus
different parts of the code can have differring ideas on the size of a
structure containing a char name[IF_NAMESIZE]. To avoid this error case,
we avoid reusing the IF_NAMESIZE macro and instead define our own as
OPAL_IF_NAMESIZE.

Signed-off-by: William Zhang <wilzhang@amazon.com>
2019-07-29 21:24:39 +00:00

167 строки
5.1 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/util/string_copy.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_ENABLE_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);
opal_string_copy (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;
}
intf->af_family = AF_INET6;
opal_string_copy (intf->if_name, lifreq->lifr_name, OPAL_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_ENABLE_IPV6 */
return OPAL_SUCCESS;
}