|
11 | 11 | #include "tcp.h"
|
12 | 12 |
|
13 | 13 | #include <ucs/async/async.h>
|
| 14 | +#include <ucs/sys/netlink.h> |
14 | 15 | #include <ucs/sys/string.h>
|
15 | 16 | #include <ucs/config/types.h>
|
16 | 17 | #include <sys/socket.h>
|
@@ -201,6 +202,10 @@ uct_tcp_iface_is_reachable_v2(const uct_iface_h tl_iface,
|
201 | 202 | uct_iface_local_addr_ns_t *local_addr_ns;
|
202 | 203 | uct_tcp_device_addr_t *tcp_dev_addr;
|
203 | 204 | int is_local_loopback, is_remote_loopback;
|
| 205 | + struct sockaddr_storage remote_addr; |
| 206 | + char remote_addr_str[UCS_SOCKADDR_STRING_LEN]; |
| 207 | + unsigned ndev_index; |
| 208 | + ucs_status_t status; |
204 | 209 |
|
205 | 210 | if (!uct_iface_is_reachable_params_valid(
|
206 | 211 | params, UCT_IFACE_IS_REACHABLE_FIELD_DEVICE_ADDR)) {
|
@@ -236,9 +241,38 @@ uct_tcp_iface_is_reachable_v2(const uct_iface_h tl_iface,
|
236 | 241 | }
|
237 | 242 | }
|
238 | 243 |
|
239 |
| - /* Later connect() call can still fail if the peer is actually unreachable |
240 |
| - * at UCT/TCP EP creation time */ |
241 |
| - return uct_iface_scope_is_reachable(tl_iface, params); |
| 244 | + if ((params->field_mask & UCT_IFACE_IS_REACHABLE_FIELD_SCOPE) && |
| 245 | + (params->scope == UCT_IFACE_REACHABILITY_SCOPE_DEVICE)) { |
| 246 | + return uct_iface_scope_is_reachable(tl_iface, params); |
| 247 | + } |
| 248 | + |
| 249 | + /* Check if the remote address is routable */ |
| 250 | + status = ucs_ifname_to_index(iface->if_name, &ndev_index); |
| 251 | + if (status != UCS_OK) { |
| 252 | + uct_iface_fill_info_str_buf( |
| 253 | + params, "failed to get interface index"); |
| 254 | + return 0; |
| 255 | + } |
| 256 | + |
| 257 | + remote_addr.ss_family = tcp_dev_addr->sa_family; |
| 258 | + status = ucs_sockaddr_set_inet_addr((struct sockaddr *)&remote_addr, |
| 259 | + tcp_dev_addr + 1); |
| 260 | + if (status != UCS_OK) { |
| 261 | + uct_iface_fill_info_str_buf( |
| 262 | + params, "failed to set inet address"); |
| 263 | + return 0; |
| 264 | + } |
| 265 | + |
| 266 | + if (!ucs_netlink_route_exists(ndev_index, |
| 267 | + (const struct sockaddr *)&remote_addr)) { |
| 268 | + uct_iface_fill_info_str_buf( |
| 269 | + params, "no route to %s", |
| 270 | + ucs_sockaddr_str((const struct sockaddr *)&remote_addr, |
| 271 | + remote_addr_str, UCS_SOCKADDR_STRING_LEN)); |
| 272 | + return 0; |
| 273 | + } |
| 274 | + |
| 275 | + return 1; |
242 | 276 | }
|
243 | 277 |
|
244 | 278 | static const char *
|
|
0 commit comments