This source file includes following definitions.
- weighted_init
- weighted_fini
- weighted_reachable
- get_weights
- calculate_weight
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include "opal_config.h"
18 #include "opal/constants.h"
19 #include "opal/types.h"
20
21 #include <string.h>
22 #ifdef HAVE_UNISTD_H
23 #include <unistd.h>
24 #endif
25 #ifdef HAVE_MATH_H
26 #include <math.h>
27 #endif
28
29 #include "opal/mca/if/if.h"
30
31 #include "opal/mca/reachable/base/base.h"
32 #include "reachable_weighted.h"
33 #include "opal/util/net.h"
34 #include "opal/util/string_copy.h"
35
36 static int weighted_init(void);
37 static int weighted_fini(void);
38 static opal_reachable_t* weighted_reachable(opal_list_t *local_if,
39 opal_list_t *remote_if);
40
41 static int get_weights(opal_if_t *local_if, opal_if_t *remote_if);
42 static int calculate_weight(int bandwidth_local, int bandwidth_remote,
43 int connection_quality);
44
45
46
47
48
49
50
51
52
53 enum connection_quality {
54 CQ_NO_CONNECTION = 0,
55 CQ_PRIVATE_DIFFERENT_NETWORK = 50,
56 CQ_PRIVATE_SAME_NETWORK = 80,
57 CQ_PUBLIC_DIFFERENT_NETWORK = 90,
58 CQ_PUBLIC_SAME_NETWORK = 100
59 };
60
61 const opal_reachable_base_module_t opal_reachable_weighted_module = {
62 weighted_init,
63 weighted_fini,
64 weighted_reachable
65 };
66
67
68 static int init_cntr = 0;
69
70
71 static int weighted_init(void)
72 {
73 ++init_cntr;
74
75 return OPAL_SUCCESS;
76 }
77
78 static int weighted_fini(void)
79 {
80 --init_cntr;
81
82 return OPAL_SUCCESS;
83 }
84
85
86 static opal_reachable_t* weighted_reachable(opal_list_t *local_if,
87 opal_list_t *remote_if)
88 {
89 opal_reachable_t *reachable_results = NULL;
90 int i, j;
91 opal_if_t *local_iter, *remote_iter;
92
93 reachable_results = opal_reachable_allocate(opal_list_get_size(local_if),
94 opal_list_get_size(remote_if));
95 if (NULL == reachable_results) {
96 return NULL;
97 }
98
99 i = 0;
100 OPAL_LIST_FOREACH(local_iter, local_if, opal_if_t) {
101 j = 0;
102 OPAL_LIST_FOREACH(remote_iter, remote_if, opal_if_t) {
103 reachable_results->weights[i][j] = get_weights(local_iter, remote_iter);
104 j++;
105 }
106 i++;
107 }
108
109 return reachable_results;
110 }
111
112
113 static int get_weights(opal_if_t *local_if, opal_if_t *remote_if)
114 {
115 char str_local[128], str_remote[128], *conn_type;
116 struct sockaddr *local_sockaddr, *remote_sockaddr;
117 int weight;
118
119 local_sockaddr = (struct sockaddr *)&local_if->if_addr;
120 remote_sockaddr = (struct sockaddr *)&remote_if->if_addr;
121
122
123
124 opal_string_copy(str_local, opal_net_get_hostname(local_sockaddr), sizeof(str_local));
125 str_local[sizeof(str_local) - 1] = '\0';
126 opal_string_copy(str_remote, opal_net_get_hostname(remote_sockaddr), sizeof(str_remote));
127 str_remote[sizeof(str_remote) - 1] = '\0';
128
129
130 weight = calculate_weight(0, 0, CQ_NO_CONNECTION);
131
132 if (AF_INET == local_sockaddr->sa_family &&
133 AF_INET == remote_sockaddr->sa_family) {
134
135 if (opal_net_addr_isipv4public(local_sockaddr) &&
136 opal_net_addr_isipv4public(remote_sockaddr)) {
137 if (opal_net_samenetwork(local_sockaddr,
138 remote_sockaddr,
139 local_if->if_mask)) {
140 conn_type = "IPv4 PUBLIC SAME NETWORK";
141 weight = calculate_weight(local_if->if_bandwidth,
142 remote_if->if_bandwidth,
143 CQ_PUBLIC_SAME_NETWORK);
144 } else {
145 conn_type = "IPv4 PUBLIC DIFFERENT NETWORK";
146 weight = calculate_weight(local_if->if_bandwidth,
147 remote_if->if_bandwidth,
148 CQ_PUBLIC_DIFFERENT_NETWORK);
149 }
150 } else if (!opal_net_addr_isipv4public(local_sockaddr) &&
151 !opal_net_addr_isipv4public(remote_sockaddr)) {
152 if (opal_net_samenetwork(local_sockaddr,
153 remote_sockaddr,
154 local_if->if_mask)) {
155 conn_type = "IPv4 PRIVATE SAME NETWORK";
156 weight = calculate_weight(local_if->if_bandwidth,
157 remote_if->if_bandwidth,
158 CQ_PRIVATE_SAME_NETWORK);
159 } else {
160 conn_type = "IPv4 PRIVATE DIFFERENT NETWORK";
161 weight = calculate_weight(local_if->if_bandwidth,
162 remote_if->if_bandwidth,
163 CQ_PRIVATE_DIFFERENT_NETWORK);
164 }
165 } else {
166
167 conn_type = "IPv4 NO CONNECTION";
168 weight = calculate_weight(local_if->if_bandwidth,
169 remote_if->if_bandwidth,
170 CQ_NO_CONNECTION);
171 }
172
173 #if OPAL_ENABLE_IPV6
174 } else if (AF_INET6 == local_sockaddr->sa_family &&
175 AF_INET6 == remote_sockaddr->sa_family) {
176 if (opal_net_addr_isipv6linklocal(local_sockaddr) &&
177 opal_net_addr_isipv6linklocal(remote_sockaddr)) {
178
179
180
181
182
183
184
185
186
187
188
189
190
191 conn_type = "IPv6 LINK-LOCAL SAME NETWORK";
192 weight = calculate_weight(local_if->if_bandwidth,
193 remote_if->if_bandwidth,
194 CQ_PRIVATE_SAME_NETWORK);
195 } else if (!opal_net_addr_isipv6linklocal(local_sockaddr) &&
196 !opal_net_addr_isipv6linklocal(remote_sockaddr)) {
197 if (opal_net_samenetwork(local_sockaddr,
198 remote_sockaddr,
199 local_if->if_mask)) {
200 conn_type = "IPv6 PUBLIC SAME NETWORK";
201 weight = calculate_weight(local_if->if_bandwidth,
202 remote_if->if_bandwidth,
203 CQ_PUBLIC_SAME_NETWORK);
204 } else {
205 conn_type = "IPv6 PUBLIC DIFFERENT NETWORK";
206 weight = calculate_weight(local_if->if_bandwidth,
207 remote_if->if_bandwidth,
208 CQ_PUBLIC_DIFFERENT_NETWORK);
209 }
210 } else {
211
212 conn_type = "IPv6 NO CONNECTION";
213 weight = calculate_weight(local_if->if_bandwidth,
214 remote_if->if_bandwidth,
215 CQ_NO_CONNECTION);
216 }
217 #endif
218
219 } else {
220
221
222 conn_type = "Address type mismatch";
223 weight = calculate_weight(0, 0, CQ_NO_CONNECTION);
224 }
225
226 opal_output_verbose(20, opal_reachable_base_framework.framework_output,
227 "reachable:weighted: path from %s to %s: %s",
228 str_local, str_remote, conn_type);
229
230 return weight;
231 }
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 static int calculate_weight(int bandwidth_local, int bandwidth_remote,
261 int connection_quality)
262 {
263 int weight = connection_quality * (MIN(bandwidth_local, bandwidth_remote) +
264 1.0 / (1.0 + (double)abs(bandwidth_local - bandwidth_remote)));
265 return weight;
266 }