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 }