usnic: properly check src iface in route queries
rtnetlink doesn't check the source address when determining whether to return route info for a query. So we need to check that the OIF matches the OIF of the source interface name. Without this check, OMPI might pair a local interface which does not have a route to a particular remote interface. Fixes Cisco bug CSCup55797. Reviewed-by: Jeff Squyres <jsquyres@cisco.com> cmr=v1.8.2:reviewer=ompi-rm1.8 This commit was SVN r32090.
Этот коммит содержится в:
родитель
f3cb124e50
Коммит
f6bb853409
@ -17,6 +17,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <net/if.h>
|
||||||
#include <netlink/netlink.h>
|
#include <netlink/netlink.h>
|
||||||
#include <netlink/addr.h>
|
#include <netlink/addr.h>
|
||||||
#include <netlink/route/rtnl.h>
|
#include <netlink/route/rtnl.h>
|
||||||
@ -45,6 +46,7 @@ struct usnic_rtnl_sk {
|
|||||||
|
|
||||||
struct nl_lookup_arg {
|
struct nl_lookup_arg {
|
||||||
uint32_t nh_addr;
|
uint32_t nh_addr;
|
||||||
|
int oif;
|
||||||
int found;
|
int found;
|
||||||
int replied;
|
int replied;
|
||||||
int msg_count;
|
int msg_count;
|
||||||
@ -130,9 +132,17 @@ static int rtnl_raw_parse_cb(struct nl_msg *msg, void *arg)
|
|||||||
return NL_STOP;
|
return NL_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb[RTA_METRICS]) {
|
if (tb[RTA_OIF]) {
|
||||||
|
if (nla_get_u32(tb[RTA_OIF]) == (uint32_t)lookup_arg->oif)
|
||||||
|
found = 1;
|
||||||
|
else
|
||||||
|
usnic_err("Retrieved route has a different outgoing interface %d (expected %d)\n",
|
||||||
|
nla_get_u32(tb[RTA_OIF]),
|
||||||
|
lookup_arg->oif);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found && tb[RTA_METRICS]) {
|
||||||
lookup_arg->metric = (int)nla_get_u32(tb[RTA_METRICS]);
|
lookup_arg->metric = (int)nla_get_u32(tb[RTA_METRICS]);
|
||||||
found = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found && tb[RTA_GATEWAY])
|
if (found && tb[RTA_GATEWAY])
|
||||||
@ -173,7 +183,9 @@ static int nl_set_recv_timeout(struct nl_handle *handle)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ompi_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk, uint32_t src_addr,
|
int ompi_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk,
|
||||||
|
const char *src_ifname,
|
||||||
|
uint32_t src_addr,
|
||||||
uint32_t dst_addr, int *metric)
|
uint32_t dst_addr, int *metric)
|
||||||
{
|
{
|
||||||
struct nl_msg *nlm;
|
struct nl_msg *nlm;
|
||||||
@ -181,8 +193,15 @@ int ompi_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk, uint32_t src_add
|
|||||||
struct nl_lookup_arg arg;
|
struct nl_lookup_arg arg;
|
||||||
int msg_cnt;
|
int msg_cnt;
|
||||||
int err;
|
int err;
|
||||||
|
int oif;
|
||||||
|
|
||||||
|
oif = if_nametoindex(src_ifname);
|
||||||
|
if (0 == oif) {
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
arg.nh_addr = 0;
|
arg.nh_addr = 0;
|
||||||
|
arg.oif = oif;
|
||||||
arg.found = 0;
|
arg.found = 0;
|
||||||
arg.replied = 0;
|
arg.replied = 0;
|
||||||
arg.unlsk = unlsk;
|
arg.unlsk = unlsk;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
/* the netlink headers have many C99-isms that cause warnings on the v1.6
|
/* the netlink headers have many C99-isms that cause warnings on the v1.6
|
||||||
* branch when --enable-picky is passed to configure :( */
|
* branch when --enable-picky is passed to configure :( */
|
||||||
@ -44,6 +45,7 @@ struct usnic_rtnl_sk {
|
|||||||
|
|
||||||
struct nl_lookup_arg {
|
struct nl_lookup_arg {
|
||||||
uint32_t nh_addr;
|
uint32_t nh_addr;
|
||||||
|
int oif;
|
||||||
int found;
|
int found;
|
||||||
int replied;
|
int replied;
|
||||||
int msg_count;
|
int msg_count;
|
||||||
@ -128,9 +130,17 @@ static int rtnl_raw_parse_cb(struct nl_msg *msg, void *arg)
|
|||||||
return NL_STOP;
|
return NL_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb[RTA_METRICS]) {
|
if (tb[RTA_OIF]) {
|
||||||
|
if (nla_get_u32(tb[RTA_OIF]) == (uint32_t)lookup_arg->oif)
|
||||||
|
found = 1;
|
||||||
|
else
|
||||||
|
usnic_err("Retrieved route has a different outgoing interface %d (expected %d)\n",
|
||||||
|
nla_get_u32(tb[RTA_OIF]),
|
||||||
|
lookup_arg->oif);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found && tb[RTA_METRICS]) {
|
||||||
lookup_arg->metric = (int)nla_get_u32(tb[RTA_METRICS]);
|
lookup_arg->metric = (int)nla_get_u32(tb[RTA_METRICS]);
|
||||||
found = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found && tb[RTA_GATEWAY])
|
if (found && tb[RTA_GATEWAY])
|
||||||
@ -171,7 +181,9 @@ static int nl_set_recv_timeout(struct nl_sock *sock)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ompi_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk, uint32_t src_addr,
|
int ompi_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk,
|
||||||
|
const char *src_ifname,
|
||||||
|
uint32_t src_addr,
|
||||||
uint32_t dst_addr, int *metric)
|
uint32_t dst_addr, int *metric)
|
||||||
{
|
{
|
||||||
struct nl_msg *nlm;
|
struct nl_msg *nlm;
|
||||||
@ -179,8 +191,15 @@ int ompi_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk, uint32_t src_add
|
|||||||
struct nl_lookup_arg arg;
|
struct nl_lookup_arg arg;
|
||||||
int msg_cnt;
|
int msg_cnt;
|
||||||
int err;
|
int err;
|
||||||
|
int oif;
|
||||||
|
|
||||||
|
oif = if_nametoindex(src_ifname);
|
||||||
|
if (0 == oif) {
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
arg.nh_addr = 0;
|
arg.nh_addr = 0;
|
||||||
|
arg.oif = oif;
|
||||||
arg.found = 0;
|
arg.found = 0;
|
||||||
arg.replied = 0;
|
arg.replied = 0;
|
||||||
arg.unlsk = unlsk;
|
arg.unlsk = unlsk;
|
||||||
|
@ -30,7 +30,9 @@ void ompi_btl_usnic_rtnl_sk_free(struct usnic_rtnl_sk* u_nlsk);
|
|||||||
|
|
||||||
/* src_addr and dst_addr are IPv4 addresses in network byte order. Returns
|
/* src_addr and dst_addr are IPv4 addresses in network byte order. Returns
|
||||||
* zero on successful route lookup, -1 otherwise. */
|
* zero on successful route lookup, -1 otherwise. */
|
||||||
int ompi_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk, uint32_t src_addr,
|
int ompi_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk,
|
||||||
|
const char *src_ifname,
|
||||||
|
uint32_t src_addr,
|
||||||
uint32_t dst_addr, int *metric);
|
uint32_t dst_addr, int *metric);
|
||||||
|
|
||||||
#endif /* LIBNL_UTILS_H */
|
#endif /* LIBNL_UTILS_H */
|
||||||
|
@ -310,6 +310,7 @@ static uint64_t compute_weight(
|
|||||||
|
|
||||||
metric = 0;
|
metric = 0;
|
||||||
err = ompi_btl_usnic_nl_ip_rt_lookup(mca_btl_usnic_component.unlsk,
|
err = ompi_btl_usnic_nl_ip_rt_lookup(mca_btl_usnic_component.unlsk,
|
||||||
|
module->if_name,
|
||||||
module->if_ipv4_addr,
|
module->if_ipv4_addr,
|
||||||
proc_modex_addr->ipv4_addr,
|
proc_modex_addr->ipv4_addr,
|
||||||
&metric);
|
&metric);
|
||||||
|
@ -127,6 +127,9 @@ AC_DEFUN([MCA_ompi_btl_usnic_CONFIG],[
|
|||||||
[define to 1 if usnic BTL unit tests are enabled, 0 otherwise])
|
[define to 1 if usnic BTL unit tests are enabled, 0 otherwise])
|
||||||
unset unit_tests
|
unset unit_tests
|
||||||
|
|
||||||
|
# for if_nametoindex(3)
|
||||||
|
AC_CHECK_HEADERS([net/if.h])
|
||||||
|
|
||||||
OMPI_CHECK_OPENFABRICS([btl_usnic],
|
OMPI_CHECK_OPENFABRICS([btl_usnic],
|
||||||
[btl_usnic_happy="yes"],
|
[btl_usnic_happy="yes"],
|
||||||
[btl_usnic_happy="no"])
|
[btl_usnic_happy="no"])
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user