This source file includes following definitions.
- if_solaris_ipv6_open
1
2
3
4
5
6
7
8
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
24 opal_if_base_component_t mca_if_solaris_ipv6_component = {
25
26
27 {
28 OPAL_IF_BASE_VERSION_2_0_0,
29
30
31 "solaris_ipv6",
32 OPAL_MAJOR_VERSION,
33 OPAL_MINOR_VERSION,
34 OPAL_RELEASE_VERSION,
35
36
37 if_solaris_ipv6_open,
38 NULL
39 },
40 {
41
42 MCA_BASE_METADATA_PARAM_CHECKPOINT
43 },
44 };
45
46
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
65 lifnum.lifn_family = AF_INET6;
66 lifnum.lifn_flags = 0;
67 lifnum.lifn_count = 0;
68
69
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
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
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
123
124
125
126
127
128
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
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
149 intf->if_flags =
150 (uint32_t)(0x00000000ffffffff) & lifquery.lifr_flags;
151
152
153 opal_list_append (&opal_if_list, &(intf->super));
154 }
155 }
156 }
157
158 if (NULL != lifconf.lifc_buf) {
159 free (lifconf.lifc_buf);
160 }
161 #endif
162
163 return OPAL_SUCCESS;
164 }
165
166