root/opal/mca/if/solaris_ipv6/if_solaris_ipv6.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. if_solaris_ipv6_open

   1 /*
   2  * Copyright (c) 2010      Cisco Systems, Inc.  All rights reserved.
   3  * Copyright (c) 2010      Oracle and/or its affiliates.  All rights reserved.
   4  * $COPYRIGHT$
   5  *
   6  * Additional copyrights may follow
   7  *
   8  * $HEADER$
   9  */
  10 
  11 #include "opal_config.h"
  12 
  13 #include <stdlib.h>
  14 #include <string.h>
  15 
  16 #include "opal/constants.h"
  17 #include "opal/util/output.h"
  18 #include "opal/util/string_copy.h"
  19 #include "opal/mca/if/if.h"
  20 
  21 static int if_solaris_ipv6_open(void);
  22 
  23 /* Discovers Solaris IPv6 interfaces */
  24 opal_if_base_component_t mca_if_solaris_ipv6_component = {
  25     /* First, the mca_component_t struct containing meta information
  26        about the component itself */
  27     {
  28         OPAL_IF_BASE_VERSION_2_0_0,
  29 
  30         /* Component name and version */
  31         "solaris_ipv6",
  32         OPAL_MAJOR_VERSION,
  33         OPAL_MINOR_VERSION,
  34         OPAL_RELEASE_VERSION,
  35 
  36         /* Component open and close functions */
  37         if_solaris_ipv6_open,
  38         NULL
  39     },
  40     {
  41         /* This component is checkpointable */
  42         MCA_BASE_METADATA_PARAM_CHECKPOINT
  43     },
  44 };
  45 
  46 /* configure using getifaddrs(3) */
  47 static int if_solaris_ipv6_open(void)
  48 {
  49 #if OPAL_ENABLE_IPV6
  50     int i;
  51     int sd;
  52     int error;
  53     uint16_t kindex;
  54     struct lifnum lifnum;
  55     struct lifconf lifconf;
  56     struct lifreq *lifreq, lifquery;
  57 
  58     sd = socket (AF_INET6, SOCK_DGRAM, 0);
  59     if (sd < 0) {
  60         opal_output (0, "opal_ifinit: unable to open IPv6 socket\n");
  61         return OPAL_ERROR;
  62     }
  63 
  64     /* we only ask for IPv6; IPv4 discovery has already been done */
  65     lifnum.lifn_family = AF_INET6;
  66     lifnum.lifn_flags = 0;
  67     lifnum.lifn_count = 0;
  68 
  69     /* get the number of interfaces in the system */
  70     error = ioctl (sd, SIOCGLIFNUM, &lifnum);
  71     if (error < 0) {
  72         opal_output (0,
  73                      "opal_ifinit: ioctl SIOCGLIFNUM failed with errno=%d\n", errno);
  74         return OPAL_ERROR;
  75     }
  76 
  77     memset (&lifconf, 0, sizeof (struct lifconf));
  78     memset (&lifquery, 0, sizeof (struct lifreq));
  79     lifconf.lifc_family = AF_INET6;
  80     lifconf.lifc_flags = 0;
  81     lifconf.lifc_len = lifnum.lifn_count * sizeof (struct lifreq) * 2;
  82     lifconf.lifc_buf = malloc (lifconf.lifc_len);
  83     if (NULL == lifconf.lifc_buf) {
  84         opal_output (0, "opal_ifinit: IPv6 discovery: malloc() failed\n");
  85         return OPAL_ERR_OUT_OF_RESOURCE;
  86     }
  87 
  88     memset (lifconf.lifc_buf, 0, lifconf.lifc_len);
  89 
  90     error = ioctl (sd, SIOCGLIFCONF, &lifconf);
  91     if (error < 0) {
  92         opal_output (0,
  93                      "opal_ifinit: IPv6 SIOCGLIFCONF failed with errno=%d\n", errno);
  94     }
  95 
  96     for (i = 0; i + sizeof (struct lifreq) <= lifconf.lifc_len;
  97          i += sizeof (*lifreq)) {
  98 
  99         lifreq = (struct lifreq *)((caddr_t)lifconf.lifc_buf + i);
 100         opal_string_copy (lifquery.lifr_name, lifreq->lifr_name,
 101                  sizeof (lifquery.lifr_name));
 102 
 103         /* lookup kernel index */
 104         error = ioctl (sd, SIOCGLIFINDEX, &lifquery);
 105         if (error < 0) {
 106             opal_output (0,
 107                          "opal_ifinit: SIOCGLIFINDEX failed with errno=%d\n", errno);
 108             return OPAL_ERROR;
 109         }
 110         kindex = lifquery.lifr_index;
 111 
 112         /* lookup interface flags */
 113         error = ioctl (sd, SIOCGLIFFLAGS, &lifquery);
 114         if (error < 0) {
 115             opal_output (0,
 116                          "opal_ifinit: SIOCGLIFFLAGS failed with errno=%d\n", errno);
 117             return OPAL_ERROR;
 118         }
 119 
 120         if (AF_INET6 == lifreq->lifr_addr.ss_family) {
 121             struct sockaddr_in6* my_addr = (struct sockaddr_in6*) &lifreq->lifr_addr;
 122             /* we surely want to check for sin6_scope_id, but Solaris
 123                does not set it correctly, so we have to look for
 124                global scope. For now, global is anything which is
 125                neither loopback nor link local.
 126 
 127                Bug, FIXME: site-local, multicast, ... missing
 128                Check for 2000::/3?
 129             */
 130             if ( (!opal_if_retain_loopback && !IN6_IS_ADDR_LOOPBACK (&my_addr->sin6_addr)) &&
 131                  (! IN6_IS_ADDR_LINKLOCAL (&my_addr->sin6_addr))) {
 132                 /* create interface for newly found address */
 133                 opal_if_t *intf;
 134 
 135                 intf = OBJ_NEW(opal_if_t);
 136                 if (NULL == intf) {
 137                     opal_output (0,
 138                                  "opal_ifinit: unable to allocate %d bytes\n",
 139                                  sizeof (opal_if_t));
 140                     return OPAL_ERR_OUT_OF_RESOURCE;
 141                 }
 142                 intf->af_family = AF_INET6;
 143 
 144                 opal_string_copy (intf->if_name, lifreq->lifr_name, IF_NAMESIZE);
 145                 intf->if_index = opal_list_get_size(&opal_if_list)+1;
 146                 memcpy(&intf->if_addr, my_addr, sizeof (*my_addr));
 147                 intf->if_mask = 64;
 148                 /* lifrq flags are uint64_t */
 149                 intf->if_flags =
 150                     (uint32_t)(0x00000000ffffffff) & lifquery.lifr_flags;
 151 
 152                 /* append to list */
 153                 opal_list_append (&opal_if_list, &(intf->super));
 154             }
 155         }
 156     } /* for */
 157 
 158     if (NULL != lifconf.lifc_buf) {
 159         free (lifconf.lifc_buf);
 160     }
 161 #endif  /* OPAL_ENABLE_IPV6 */
 162 
 163     return OPAL_SUCCESS;
 164 }
 165 
 166 

/* [<][>][^][v][top][bottom][index][help] */