Zbigniew Jędrzejewski-Szmek 43ff24
From f49887cbe75da56dc8555d56c66daad78400b2b3 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 43ff24
From: Tom Gundersen <teg@jklm.no>
Zbigniew Jędrzejewski-Szmek 43ff24
Date: Thu, 3 Jul 2014 22:47:51 +0200
Zbigniew Jędrzejewski-Szmek 43ff24
Subject: [PATCH] networkd: properly track addresses when first added
Zbigniew Jędrzejewski-Szmek 43ff24
Zbigniew Jędrzejewski-Szmek 43ff24
When doing a NEWADDR, the reply we get back is the NEWADDR itself, rather
Zbigniew Jędrzejewski-Szmek 43ff24
than just an empty ack (unlike how NEWLINK works). For this reason, the
Zbigniew Jędrzejewski-Szmek 43ff24
process that did the NEWADDR does not get the broadcast message.
Zbigniew Jędrzejewski-Szmek 43ff24
Zbigniew Jędrzejewski-Szmek 43ff24
We were only listening for broadcast messages, and hence not tracking the
Zbigniew Jędrzejewski-Szmek 43ff24
addresses we added ourselves. This went unnoticed as the kernel will usually
Zbigniew Jędrzejewski-Szmek 43ff24
send NEWADDR messages from time to time anyway, so things would mostly work,
Zbigniew Jędrzejewski-Szmek 43ff24
but in the worst case we would not notice that a routable address was available
Zbigniew Jędrzejewski-Szmek 43ff24
and consider ourselves offline.
Zbigniew Jędrzejewski-Szmek 43ff24
Zbigniew Jędrzejewski-Szmek 43ff24
(cherry picked from commit 4958aee4977f325be19f0e1e4b424922c3cada5f)
Zbigniew Jędrzejewski-Szmek 43ff24
---
Zbigniew Jędrzejewski-Szmek 43ff24
 src/network/networkd-link.c | 54 +++++++++++++++++++++++++--------------------
Zbigniew Jędrzejewski-Szmek 43ff24
 1 file changed, 30 insertions(+), 24 deletions(-)
Zbigniew Jędrzejewski-Szmek 43ff24
Zbigniew Jędrzejewski-Szmek 43ff24
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
Zbigniew Jędrzejewski-Szmek 43ff24
index 961c1ab8ad..6257372ffd 100644
Zbigniew Jędrzejewski-Szmek 43ff24
--- a/src/network/networkd-link.c
Zbigniew Jędrzejewski-Szmek 43ff24
+++ b/src/network/networkd-link.c
Zbigniew Jędrzejewski-Szmek 43ff24
@@ -599,10 +599,35 @@ static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata)
Zbigniew Jędrzejewski-Szmek 43ff24
         return 0;
Zbigniew Jędrzejewski-Szmek 43ff24
 }
Zbigniew Jędrzejewski-Szmek 43ff24
 
Zbigniew Jędrzejewski-Szmek 43ff24
+static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
Zbigniew Jędrzejewski-Szmek 43ff24
+        _cleanup_link_unref_ Link *link = userdata;
Zbigniew Jędrzejewski-Szmek 43ff24
+        int r;
Zbigniew Jędrzejewski-Szmek 43ff24
+
Zbigniew Jędrzejewski-Szmek 43ff24
+        assert(rtnl);
Zbigniew Jędrzejewski-Szmek 43ff24
+        assert(m);
Zbigniew Jędrzejewski-Szmek 43ff24
+        assert(link);
Zbigniew Jędrzejewski-Szmek 43ff24
+        assert(link->manager);
Zbigniew Jędrzejewski-Szmek 43ff24
+
Zbigniew Jędrzejewski-Szmek 43ff24
+        for (; m; m = sd_rtnl_message_next(m)) {
Zbigniew Jędrzejewski-Szmek 43ff24
+                r = sd_rtnl_message_get_errno(m);
Zbigniew Jędrzejewski-Szmek 43ff24
+                if (r < 0) {
Zbigniew Jędrzejewski-Szmek 43ff24
+                        log_debug_link(link, "getting address failed: %s", strerror(-r));
Zbigniew Jędrzejewski-Szmek 43ff24
+                        continue;
Zbigniew Jędrzejewski-Szmek 43ff24
+                }
Zbigniew Jędrzejewski-Szmek 43ff24
+
Zbigniew Jędrzejewski-Szmek 43ff24
+                r = link_rtnl_process_address(rtnl, m, link->manager);
Zbigniew Jędrzejewski-Szmek 43ff24
+                if (r < 0)
Zbigniew Jędrzejewski-Szmek 43ff24
+                        log_warning_link(link, "could not process address: %s", strerror(-r));
Zbigniew Jędrzejewski-Szmek 43ff24
+        }
Zbigniew Jędrzejewski-Szmek 43ff24
+
Zbigniew Jędrzejewski-Szmek 43ff24
+        return 1;
Zbigniew Jędrzejewski-Szmek 43ff24
+}
Zbigniew Jędrzejewski-Szmek 43ff24
+
Zbigniew Jędrzejewski-Szmek 43ff24
 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
Zbigniew Jędrzejewski-Szmek 43ff24
         _cleanup_link_unref_ Link *link = userdata;
Zbigniew Jędrzejewski-Szmek 43ff24
         int r;
Zbigniew Jędrzejewski-Szmek 43ff24
 
Zbigniew Jędrzejewski-Szmek 43ff24
+        assert(rtnl);
Zbigniew Jędrzejewski-Szmek 43ff24
         assert(m);
Zbigniew Jędrzejewski-Szmek 43ff24
         assert(link);
Zbigniew Jędrzejewski-Szmek 43ff24
         assert(link->ifname);
Zbigniew Jędrzejewski-Szmek 43ff24
@@ -623,6 +648,11 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
Zbigniew Jędrzejewski-Szmek 43ff24
                                 link->ifname, strerror(-r),
Zbigniew Jędrzejewski-Szmek 43ff24
                                 "ERRNO=%d", -r,
Zbigniew Jędrzejewski-Szmek 43ff24
                                 NULL);
Zbigniew Jędrzejewski-Szmek 43ff24
+        if (r >= 0) {
Zbigniew Jędrzejewski-Szmek 43ff24
+                /* calling handler directly so take a ref */
Zbigniew Jędrzejewski-Szmek 43ff24
+                link_ref(link);
Zbigniew Jędrzejewski-Szmek 43ff24
+                link_get_address_handler(rtnl, m, link);
Zbigniew Jędrzejewski-Szmek 43ff24
+        }
Zbigniew Jędrzejewski-Szmek 43ff24
 
Zbigniew Jędrzejewski-Szmek 43ff24
         if (link->addr_messages == 0) {
Zbigniew Jędrzejewski-Szmek 43ff24
                 log_debug_link(link, "addresses set");
Zbigniew Jędrzejewski-Szmek 43ff24
@@ -2233,30 +2263,6 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use
Zbigniew Jędrzejewski-Szmek 43ff24
         return 1;
Zbigniew Jędrzejewski-Szmek 43ff24
 }
Zbigniew Jędrzejewski-Szmek 43ff24
 
Zbigniew Jędrzejewski-Szmek 43ff24
-static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
Zbigniew Jędrzejewski-Szmek 43ff24
-        _cleanup_link_unref_ Link *link = userdata;
Zbigniew Jędrzejewski-Szmek 43ff24
-        int r;
Zbigniew Jędrzejewski-Szmek 43ff24
-
Zbigniew Jędrzejewski-Szmek 43ff24
-        assert(rtnl);
Zbigniew Jędrzejewski-Szmek 43ff24
-        assert(m);
Zbigniew Jędrzejewski-Szmek 43ff24
-        assert(link);
Zbigniew Jędrzejewski-Szmek 43ff24
-        assert(link->manager);
Zbigniew Jędrzejewski-Szmek 43ff24
-
Zbigniew Jędrzejewski-Szmek 43ff24
-        for (; m; m = sd_rtnl_message_next(m)) {
Zbigniew Jędrzejewski-Szmek 43ff24
-                r = sd_rtnl_message_get_errno(m);
Zbigniew Jędrzejewski-Szmek 43ff24
-                if (r < 0) {
Zbigniew Jędrzejewski-Szmek 43ff24
-                        log_debug_link(link, "getting address failed: %s", strerror(-r));
Zbigniew Jędrzejewski-Szmek 43ff24
-                        continue;
Zbigniew Jędrzejewski-Szmek 43ff24
-                }
Zbigniew Jędrzejewski-Szmek 43ff24
-
Zbigniew Jędrzejewski-Szmek 43ff24
-                r = link_rtnl_process_address(rtnl, m, link->manager);
Zbigniew Jędrzejewski-Szmek 43ff24
-                if (r < 0)
Zbigniew Jędrzejewski-Szmek 43ff24
-                        log_warning_link(link, "could not process address: %s", strerror(-r));
Zbigniew Jędrzejewski-Szmek 43ff24
-        }
Zbigniew Jędrzejewski-Szmek 43ff24
-
Zbigniew Jędrzejewski-Szmek 43ff24
-        return 1;
Zbigniew Jędrzejewski-Szmek 43ff24
-}
Zbigniew Jędrzejewski-Szmek 43ff24
-
Zbigniew Jędrzejewski-Szmek 43ff24
 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
Zbigniew Jędrzejewski-Szmek 43ff24
         Link *link;
Zbigniew Jędrzejewski-Szmek 43ff24
         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;