]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd-ndisc: Don't add NDisc route for local address (#4467)
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Mon, 24 Oct 2016 11:44:01 +0000 (14:44 +0300)
committerLennart Poettering <lennart@poettering.net>
Mon, 24 Oct 2016 11:44:01 +0000 (13:44 +0200)
When systemd-networkd is run on the same IPv6 enabled interface where
radvd is announcing prefixes, a route is being set up pointing to the
interface address. As this will fail with an invalid argument error,
the link is marked as failed and the following message like the
following will appear in in the logs:

systemd-networkd[21459]: eth1: Could not set NDisc route or address: Invalid argument
systemd-networkd[21459]: eth1: Failed

Should the interface be required by systemd-networkd-wait-online,
network-online.target will wait until its timeout hits thereby
significantly delaying system startup.

The fix is to check whether the gateway address obtained from NDisc
messages is equal to any of the interface addresses on the same link
and not set the NDisc route in that case.

src/network/networkd-ndisc.c

index c2b797062396607472de98149c077e21041f3ccd..b282634e4bc124dbf8f007c0018b45b9d09fc130 100644 (file)
@@ -57,6 +57,8 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
         unsigned preference;
         usec_t time_now;
         int r;
+        Address *address;
+        Iterator i;
 
         assert(link);
         assert(rt);
@@ -75,6 +77,32 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
                 return;
         }
 
+        SET_FOREACH(address, link->addresses, i) {
+                if (!memcmp(&gateway, &address->in_addr.in6,
+                            sizeof(address->in_addr.in6))) {
+                        char buffer[INET6_ADDRSTRLEN];
+
+                        log_link_debug(link, "No NDisc route added, gateway %s matches local address",
+                                       inet_ntop(AF_INET6,
+                                                 &address->in_addr.in6,
+                                                 buffer, sizeof(buffer)));
+                        return;
+                }
+        }
+
+        SET_FOREACH(address, link->addresses_foreign, i) {
+                if (!memcmp(&gateway, &address->in_addr.in6,
+                            sizeof(address->in_addr.in6))) {
+                        char buffer[INET6_ADDRSTRLEN];
+
+                        log_link_debug(link, "No NDisc route added, gateway %s matches local address",
+                                       inet_ntop(AF_INET6,
+                                                 &address->in_addr.in6,
+                                                 buffer, sizeof(buffer)));
+                        return;
+                }
+        }
+
         r = sd_ndisc_router_get_preference(rt, &preference);
         if (r < 0) {
                 log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m");