]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: when checking whether a link is relevant, check kernel operstate
authorLennart Poettering <lennart@poettering.net>
Wed, 20 Jan 2016 20:22:26 +0000 (21:22 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 25 Jan 2016 14:59:40 +0000 (15:59 +0100)
This mimics what networkd is doing to detect a carrier.

src/basic/missing.h
src/resolve/resolved-link.c
src/resolve/resolved-link.h

index c187afa287bc2dadea0d4f1db5d401bc81bf2392..6ed2133ed192dede406e910126e7e57fa43dda3e 100644 (file)
@@ -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
index b203f19dbbdf7dbbb0f8c120e637fd88f2698cfc..e2f9c8b400845d80a9fa479a94e914ed6ac267ee 100644 (file)
@@ -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;
 
index 6544214b77acc8a8b37b35e98484096a040f32f5..3b6aafb8f0c2f19cacd3becf052395007d203f6d 100644 (file)
@@ -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);