1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/*
* 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/mca/if/if.h"
#include "opal/util/output.h"
#include "opal/util/string_copy.h"
static int if_bsdx_open(void);
/* Supports specific flavors of BSD:
* NetBSD
* FreeBSD
* OpenBSD
* DragonFly
*/
opal_if_base_component_t mca_if_bsdx_ipv4_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 */
"bsdx_ipv4", OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION, OPAL_RELEASE_VERSION,
/* Component open and close functions */
if_bsdx_open, NULL},
{/* This component is checkpointable */
MCA_BASE_METADATA_PARAM_CHECKPOINT},
};
/* convert a netmask (in network byte order) to CIDR notation */
static int prefix(uint32_t netmask)
{
uint32_t mask = ntohl(netmask);
int plen = 0;
if (0 == mask) {
plen = 32;
} else {
while ((mask % 2) == 0) {
plen += 1;
mask /= 2;
}
}
return (32 - plen);
}
/* configure using getifaddrs(3) */
static int if_bsdx_open(void)
{
struct ifaddrs **ifadd_list;
struct ifaddrs *cur_ifaddrs;
struct sockaddr_in *sin_addr;
/*
* the manpage claims that getifaddrs() allocates the memory,
* and freeifaddrs() is later used to release the allocated memory.
* however, without this malloc the call to getifaddrs() segfaults
*/
ifadd_list = (struct ifaddrs **) malloc(sizeof(struct ifaddrs *));
/* create the linked list of ifaddrs structs */
if (getifaddrs(ifadd_list) < 0) {
opal_output(0, "opal_ifinit: getifaddrs() failed with error=%d\n", errno);
return OPAL_ERROR;
}
for (cur_ifaddrs = *ifadd_list; NULL != cur_ifaddrs; cur_ifaddrs = cur_ifaddrs->ifa_next) {
opal_if_t *intf;
struct in_addr a4;
/* skip non- af_inet interface addresses */
if (AF_INET != cur_ifaddrs->ifa_addr->sa_family) {
continue;
}
/* skip interface if it is down (IFF_UP not set) */
if (0 == (cur_ifaddrs->ifa_flags & IFF_UP)) {
continue;
}
/* skip interface if it is a loopback device (IFF_LOOPBACK set) */
if (!opal_if_retain_loopback && 0 != (cur_ifaddrs->ifa_flags & IFF_LOOPBACK)) {
continue;
}
/* or if it is a point-to-point interface */
/* TODO: do we really skip p2p? */
if (0 != (cur_ifaddrs->ifa_flags & IFF_POINTOPOINT)) {
continue;
}
sin_addr = (struct sockaddr_in *) cur_ifaddrs->ifa_addr;
intf = OBJ_NEW(opal_if_t);
if (NULL == intf) {
opal_output(0, "opal_ifinit: unable to allocate %d bytes\n", (int) sizeof(opal_if_t));
return OPAL_ERR_OUT_OF_RESOURCE;
}
intf->af_family = AF_INET;
/* fill values into the opal_if_t */
memcpy(&a4, &(sin_addr->sin_addr), sizeof(struct in_addr));
opal_string_copy(intf->if_name, cur_ifaddrs->ifa_name, OPAL_IF_NAMESIZE);
intf->if_index = opal_list_get_size(&opal_if_list) + 1;
((struct sockaddr_in *) &intf->if_addr)->sin_addr = a4;
((struct sockaddr_in *) &intf->if_addr)->sin_family = AF_INET;
((struct sockaddr_in *) &intf->if_addr)->sin_len = cur_ifaddrs->ifa_addr->sa_len;
intf->if_mask = prefix(sin_addr->sin_addr.s_addr);
intf->if_flags = cur_ifaddrs->ifa_flags;
intf->if_kernel_index = (uint16_t) if_nametoindex(cur_ifaddrs->ifa_name);
opal_list_append(&opal_if_list, &(intf->super));
} /* of for loop over ifaddrs list */
return OPAL_SUCCESS;
}
|