summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-20 21:22:26 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-25 15:59:40 +0100
commit6955a3ba9dc5d36487724878333a5745987e6656 (patch)
tree4cd271b1530c147fb8e2888d8420dca137ea9516
parent55abd6dadd50e2d7d0e5fcc5bb49c21c52226d1b (diff)
resolved: when checking whether a link is relevant, check kernel operstate
This mimics what networkd is doing to detect a carrier.
-rw-r--r--src/basic/missing.h11
-rw-r--r--src/resolve/resolved-link.c11
-rw-r--r--src/resolve/resolved-link.h1
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);