/* configure using getifaddrs(3) */
static int if_linux_ipv6_open(void)
{
#if OPAL_ENABLE_IPV6
    FILE *f;
    if ((f = fopen("/proc/net/if_inet6", "r"))) {
        char ifname[IF_NAMESIZE];
        unsigned int idx, pfxlen, scope, dadstat;
        struct in6_addr a6;
        int iter;
        uint32_t flag;
        unsigned int addrbyte[16];

        while (fscanf(f, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x %x %x %x %x %20s\n",
                      &addrbyte[0], &addrbyte[1], &addrbyte[2], &addrbyte[3],
                      &addrbyte[4], &addrbyte[5], &addrbyte[6], &addrbyte[7],
                      &addrbyte[8], &addrbyte[9], &addrbyte[10], &addrbyte[11],
                      &addrbyte[12], &addrbyte[13], &addrbyte[14], &addrbyte[15],
                      &idx, &pfxlen, &scope, &dadstat, ifname) != EOF) {
            opal_if_t *intf;

            opal_output_verbose(1, opal_if_base_framework.framework_output,
                                "found interface %2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x scope %x\n",
                                addrbyte[0], addrbyte[1], addrbyte[2], addrbyte[3],
                                addrbyte[4], addrbyte[5], addrbyte[6], addrbyte[7],
                                addrbyte[8], addrbyte[9], addrbyte[10], addrbyte[11],
                                addrbyte[12], addrbyte[13], addrbyte[14], addrbyte[15], scope);

            /* we don't want any other scope less than link-local */
            if (scope < 0x20) {
                opal_output_verbose(1, opal_if_base_framework.framework_output,
                                    "skipping interface %2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x scope %x\n",
                                    addrbyte[0], addrbyte[1], addrbyte[2], addrbyte[3],
                                    addrbyte[4], addrbyte[5], addrbyte[6], addrbyte[7],
                                    addrbyte[8], addrbyte[9], addrbyte[10], addrbyte[11],
                                    addrbyte[12], addrbyte[13], addrbyte[14], addrbyte[15], scope);
                continue;
            }

            intf = OBJ_NEW(opal_if_t);
            if (NULL == intf) {
                opal_output(0, "opal_ifinit: unable to allocate %lu bytes\n",
                            (unsigned long)sizeof(opal_if_t));
                fclose(f);
                return OPAL_ERR_OUT_OF_RESOURCE;
            }
            intf->af_family = AF_INET6;

            for (iter = 0; iter < 16; iter++) {
                a6.s6_addr[iter] = addrbyte[iter];
            }

            /* now construct the opal_if_t */
            strncpy(intf->if_name, ifname, IF_NAMESIZE);
            intf->if_index = opal_list_get_size(&opal_if_list)+1;
            intf->if_kernel_index = (uint16_t) idx;
            ((struct sockaddr_in6*) &intf->if_addr)->sin6_addr = a6;
            ((struct sockaddr_in6*) &intf->if_addr)->sin6_family = AF_INET6;
            ((struct sockaddr_in6*) &intf->if_addr)->sin6_scope_id = scope;
            intf->if_mask = pfxlen;
            if (OPAL_SUCCESS == opal_ifindextoflags(opal_ifnametoindex (ifname), &flag)) {
                intf->if_flags = flag;
            } else {
                intf->if_flags = IFF_UP;
            }
                
            /* copy new interface information to heap and append
               to list */
            opal_list_append(&opal_if_list, &(intf->super));
            opal_output_verbose(1, opal_if_base_framework.framework_output,
                                "added interface %2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x:%2x%2x\n",
                                addrbyte[0], addrbyte[1], addrbyte[2], addrbyte[3],
                                addrbyte[4], addrbyte[5], addrbyte[6], addrbyte[7],
                                addrbyte[8], addrbyte[9], addrbyte[10], addrbyte[11],
                                addrbyte[12], addrbyte[13], addrbyte[14], addrbyte[15]);
        } /* of while */
        fclose(f);
    }
#endif  /* OPAL_ENABLE_IPV6 */

    return OPAL_SUCCESS;
}
示例#2
0
/*
 * Find and assign system netmask for the address of the uDAPL BTL
 * module, but only if udapl_if_mask has not been set by the "--mca
 * btl_udapl_if_mask" parameter. This routine will either find
 * the system netmask or set the value to 0.
 *
 * @param udapl_btl (IN)      BTL module
 *
 * @return                    OMPI_SUCCESS or OMPI_ERROR
 */
static int mca_btl_udapl_assign_netmask(mca_btl_udapl_module_t* udapl_btl)
{
    struct sockaddr *saddr;
    struct sockaddr_in *btl_addr;
    char btl_addr_string[INET_ADDRSTRLEN]; 
    char btl_ifname[INET_ADDRSTRLEN];

    /* Setting if_mask to 0 informs future steps to assume all
     * addresses are reachable.
     */
    udapl_btl->udapl_if_mask = 0; 

    if (mca_btl_udapl_component.udapl_compare_subnet) {
        /* go get system netmask value */

        /* use generic address to find address family */
        saddr = (struct sockaddr *)&(udapl_btl->udapl_addr.addr);

        if (saddr->sa_family == AF_INET) {

            btl_addr = (struct sockaddr_in *)saddr;

            /*
             * Retrieve the netmask of the udapl btl address. To
             * accomplish this requires 4 steps and the use of an opal
             * utility. This same utility is used by the tcp oob.
             * Steps:
             *     1. Get string value of known udapl btl module address.
             *     2. Use string value to find the interface name of address.
             *     3. Use interface name to find its index.
             *     4. From the index get the netmask.
             */

            /* retrieve string value of udapl btl address */
            inet_ntop(AF_INET, (void *) &btl_addr->sin_addr,
                btl_addr_string, INET_ADDRSTRLEN);

            /* use address string to retrieve associated interface name */
            if (OPAL_SUCCESS != 
                opal_ifaddrtoname(btl_addr_string,
                    btl_ifname, INET_ADDRSTRLEN)) {

                BTL_UDAPL_VERBOSE_HELP(VERBOSE_SHOW_HELP,
                    ("help-mpi-btl-udapl.txt", "interface not found",
                        true, ompi_process_info.nodename, btl_addr_string));

                return OMPI_ERROR;
            }

            /* use interface name to retrieve index;  then
             * use index to retrieve udapl btl address netmask
             */
            if (OPAL_SUCCESS != 
                opal_ifindextomask(opal_ifnametoindex(btl_ifname),
                    &(udapl_btl->udapl_if_mask), sizeof(udapl_btl->udapl_if_mask))) {

                BTL_UDAPL_VERBOSE_HELP(VERBOSE_SHOW_HELP,
                    ("help-mpi-btl-udapl.txt", "netmask not found",
                        true, ompi_process_info.nodename, btl_addr_string));

                return OMPI_ERROR;
            }

            /* report if_mask used by address */
            BTL_UDAPL_VERBOSE_OUTPUT(VERBOSE_INFORM,
                ("uDAPL BTL address %s : if_mask = %d",
                btl_addr_string, udapl_btl->udapl_if_mask));

        } else {
            /* current uDAPL BTL does not support IPv6 */
            BTL_UDAPL_VERBOSE_HELP(VERBOSE_SHOW_HELP,
                ("help-mpi-btl-udapl.txt", "IPv4 only",
                    true, ompi_process_info.nodename));

            return OMPI_ERROR;
        }
    }

    return OMPI_SUCCESS;
}
static int mca_btl_sctp_component_create_instance(void)
{
    int if_count = opal_ifcount();
    int if_index;
    char **include;
    char **exclude;
    char **argv;

    if(if_count <= 0) {
        return OMPI_ERROR;
    }

    /* Allocate memory for btl pointers.  This may be more space then
       we need as some of the interfaces may get filtered out by the
       if_include and if_exclude parameters.  But that is just a few
       unused pointers. */
    mca_btl_sctp_component.sctp_btls = 
        (mca_btl_sctp_module_t **)malloc(if_count * sizeof(mca_btl_sctp_module_t*));
    if(NULL == mca_btl_sctp_component.sctp_btls) {
        return OMPI_ERR_OUT_OF_RESOURCE;
    }

    /* if the user specified an interface list - use these exclusively */
    argv = include = opal_argv_split(mca_btl_sctp_component.sctp_if_include,',');
    while(argv && *argv) {
        char* if_name = *argv;
        int if_index = opal_ifnametoindex(if_name);
        if(if_index < 0) {
            BTL_ERROR(("invalid interface \"%s\"", if_name));
        } else {
            mca_btl_sctp_create(if_index, if_name);
        }
        argv++;
    }
    opal_argv_free(include);
    if(mca_btl_sctp_component.sctp_num_btls) {
        return OMPI_SUCCESS;
    }

    /* if the interface list was not specified by the user, create 
     * a BTL for each interface that was not excluded.
     */
    exclude = opal_argv_split(mca_btl_sctp_component.sctp_if_exclude,',');
    for(if_index = opal_ifbegin(); if_index >= 0; if_index = opal_ifnext(if_index)) {
        char if_name[32];
        opal_ifindextoname(if_index, if_name, sizeof(if_name));

        /* check to see if this interface exists in the exclude list */
        if(opal_ifcount() > 1) {
            argv = exclude;
            while(argv && *argv) {
                if(strncmp(*argv,if_name,strlen(*argv)) == 0) {
                    break;
                }
                argv++;
            }
            /* if this interface was not found in the excluded list - create a BTL */
            if(argv == 0 || *argv == 0) {
                mca_btl_sctp_create(if_index, if_name);
            }
        } else {
            mca_btl_sctp_create(if_index, if_name);
        }
    }
    opal_argv_free(exclude);
    return OMPI_SUCCESS;
}