]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd-link.c: Add Router Advertisement starting and stopping
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Fri, 12 May 2017 13:48:33 +0000 (16:48 +0300)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Mon, 15 May 2017 11:49:50 +0000 (14:49 +0300)
Start and stop Router Advertisement sending once the link has acquired
a link-local IPv6 address.

src/network/networkd-link.c

index 37bebcf19161ceef8c0709d61284ae6db44bde89..98a5e3109eff1d6ed792128efc871a614c9febb3 100644 (file)
@@ -32,6 +32,7 @@
 #include "networkd-lldp-tx.h"
 #include "networkd-manager.h"
 #include "networkd-ndisc.h"
+#include "networkd-radv.h"
 #include "set.h"
 #include "socket-util.h"
 #include "stdio-util.h"
@@ -119,6 +120,15 @@ static bool link_ipv6_enabled(Link *link) {
         return link_ipv6ll_enabled(link) || network_has_static_ipv6_addresses(link->network);
 }
 
+static bool link_radv_enabled(Link *link) {
+        assert(link);
+
+        if (!link_ipv6ll_enabled(link))
+                return false;
+
+        return link->network->router_prefix_delegation;
+}
+
 static bool link_lldp_rx_enabled(Link *link) {
         assert(link);
 
@@ -521,6 +531,7 @@ static void link_free(Link *link) {
         sd_ipv4ll_unref(link->ipv4ll);
         sd_dhcp6_client_unref(link->dhcp6_client);
         sd_ndisc_unref(link->ndisc);
+        sd_radv_unref(link->radv);
 
         if (link->manager)
                 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
@@ -640,6 +651,12 @@ static int link_stop_clients(Link *link) {
                         r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m");
         }
 
+        if (link->radv) {
+                k = sd_radv_stop(link->radv);
+                if (k < 0)
+                        r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m");
+        }
+
         link_lldp_emit_stop(link);
         return r;
 }
@@ -1554,6 +1571,17 @@ static int link_acquire_ipv6_conf(Link *link) {
                         return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
         }
 
+        if (link_radv_enabled(link)) {
+                assert(link->radv);
+                assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
+
+                log_link_debug(link, "Starting IPv6 Router Advertisements");
+
+                r = sd_radv_start(link->radv);
+                if (r < 0 && r != -EBUSY)
+                        return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
+        }
+
         return 0;
 }
 
@@ -2562,6 +2590,12 @@ static int link_configure(Link *link) {
                         return r;
         }
 
+        if (link_radv_enabled(link)) {
+                r = radv_configure(link);
+                if (r < 0)
+                        return r;
+        }
+
         if (link_lldp_rx_enabled(link)) {
                 r = sd_lldp_new(&link->lldp);
                 if (r < 0)
@@ -3098,6 +3132,12 @@ int link_update(Link *link, sd_netlink_message *m) {
                                 return r;
                         }
                 }
+
+                if (link->radv) {
+                        r = sd_radv_set_mtu(link->radv, link->mtu);
+                        if (r < 0)
+                                return log_link_warning_errno(link, r, "Could not set MTU for Router Advertisement: %m");
+                }
         }
 
         /* The kernel may broadcast NEWLINK messages without the MAC address
@@ -3166,6 +3206,12 @@ int link_update(Link *link, sd_netlink_message *m) {
                                 if (r < 0)
                                         return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
                         }
+
+                        if (link->radv) {
+                                r = sd_radv_set_mac(link->radv, &link->mac);
+                                if (r < 0)
+                                        return log_link_warning_errno(link, r, "Could not update MAC for Router Advertisement: %m");
+                        }
                 }
         }