From 6955a3ba9dc5d36487724878333a5745987e6656 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 20 Jan 2016 21:22:26 +0100 Subject: resolved: when checking whether a link is relevant, check kernel operstate This mimics what networkd is doing to detect a carrier. --- src/basic/missing.h | 11 +++++++++++ src/resolve/resolved-link.c | 11 +++++++++-- src/resolve/resolved-link.h | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/basic/missing.h b/src/basic/missing.h index c187afa287..6ed2133ed1 100644 --- a/src/basic/missing.h +++ b/src/basic/missing.h @@ -1149,3 +1149,14 @@ static inline key_serial_t request_key(const char *type, const char *description #ifndef PR_CAP_AMBIENT_CLEAR_ALL #define PR_CAP_AMBIENT_CLEAR_ALL 4 #endif + +/* The following two defines are actually available in the kernel headers for longer, but we define them here anyway, + * since that makes it easier to use them in conjunction with the glibc net/if.h header which conflicts with + * linux/if.h. */ +#ifndef IF_OPER_UNKNOWN +#define IF_OPER_UNKNOWN 0 +#endif + +#ifndef IF_OPER_UP +#define IF_OPER_UP 6 +#endif diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index b203f19dbb..e2f9c8b400 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -49,6 +49,7 @@ int link_new(Manager *m, Link **ret, int ifindex) { l->llmnr_support = RESOLVE_SUPPORT_YES; l->mdns_support = RESOLVE_SUPPORT_NO; l->dnssec_mode = _DNSSEC_MODE_INVALID; + l->operstate = IF_OPER_UNKNOWN; r = hashmap_put(m->links, INT_TO_PTR(ifindex), l); if (r < 0) @@ -177,7 +178,8 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) { if (r < 0) return r; - sd_netlink_message_read_u32(m, IFLA_MTU, &l->mtu); + (void) sd_netlink_message_read_u32(m, IFLA_MTU, &l->mtu); + (void) sd_netlink_message_read_u8(m, IFLA_OPERSTATE, &l->operstate); if (sd_netlink_message_read_string(m, IFLA_IFNAME, &n) >= 0) { strncpy(l->name, n, sizeof(l->name)-1); @@ -514,7 +516,12 @@ bool link_relevant(Link *l, int family, bool multicast) { return false; } - sd_network_link_get_operational_state(l->ifindex, &state); + /* Check kernel operstate + * https://www.kernel.org/doc/Documentation/networking/operstates.txt */ + if (!IN_SET(l->operstate, IF_OPER_UNKNOWN, IF_OPER_UP)) + return false; + + (void) sd_network_link_get_operational_state(l->ifindex, &state); if (state && !STR_IN_SET(state, "unknown", "degraded", "routable")) return false; diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h index 6544214b77..3b6aafb8f0 100644 --- a/src/resolve/resolved-link.h +++ b/src/resolve/resolved-link.h @@ -82,6 +82,7 @@ struct Link { char name[IF_NAMESIZE]; uint32_t mtu; + uint8_t operstate; }; int link_new(Manager *m, Link **ret, int ifindex); -- cgit v1.2.3-54-g00ecf