]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: monitor current IPv6LL address generation mode
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 8 Feb 2022 13:26:23 +0000 (22:26 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 10 Feb 2022 08:34:06 +0000 (17:34 +0900)
src/network/networkd-ipv6ll.c
src/network/networkd-ipv6ll.h
src/network/networkd-link.c
src/network/networkd-link.h

index 0ff28761f2ad30e8c0368d1645c7da7b2b8b529c..1db0856bc4a8af15f44234be2eec9d47fe71f98a 100644 (file)
@@ -118,6 +118,65 @@ int ipv6ll_addrgen_mode_fill_message(sd_netlink_message *message, IPv6LinkLocalA
         return 0;
 }
 
+int link_update_ipv6ll_addrgen_mode(Link *link, sd_netlink_message *message) {
+        uint8_t mode;
+        int family, r;
+
+        assert(link);
+        assert(message);
+
+        r = sd_rtnl_message_get_family(message, &family);
+        if (r < 0)
+                return r;
+
+        if (family != AF_UNSPEC)
+                return 0;
+
+        r = sd_netlink_message_enter_container(message, IFLA_AF_SPEC);
+        if (r == -ENODATA)
+                return 0;
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_enter_container(message, AF_INET6);
+        if (r == -ENODATA)
+                return sd_netlink_message_exit_container(message);
+        if (r < 0)
+                return r;
+
+        mode = (uint8_t) link->ipv6ll_address_gen_mode;
+        r = sd_netlink_message_read_u8(message, IFLA_INET6_ADDR_GEN_MODE, &mode);
+        if (r < 0 && r != -ENODATA)
+                return r;
+
+        r = sd_netlink_message_exit_container(message);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_exit_container(message);
+        if (r < 0)
+                return r;
+
+        if (mode == (uint8_t) link->ipv6ll_address_gen_mode)
+                return 0;
+
+        if (mode >= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX) {
+                log_link_debug(link, "Received invalid IPv6 link-local address generation mode (%u), ignoring.", mode);
+                return 0;
+        }
+
+        if (link->ipv6ll_address_gen_mode < 0)
+                log_link_debug(link, "Saved IPv6 link-local address generation mode: %s",
+                               ipv6_link_local_address_gen_mode_to_string(mode));
+        else
+                log_link_debug(link, "IPv6 link-local address generation mode is changed: %s -> %s",
+                               ipv6_link_local_address_gen_mode_to_string(link->ipv6ll_address_gen_mode),
+                               ipv6_link_local_address_gen_mode_to_string(mode));
+
+        link->ipv6ll_address_gen_mode = mode;
+        return 0;
+}
+
 static const char* const ipv6_link_local_address_gen_mode_table[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX] = {
         [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64]          = "eui64",
         [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE]           = "none",
index 4f63c71fb5f431937884c4e47696bc66a1360bb3..9de9a75d8981dfd267caddc4405d62a059e338af 100644 (file)
@@ -26,6 +26,7 @@ bool link_may_have_ipv6ll(Link *link);
 
 IPv6LinkLocalAddressGenMode link_get_ipv6ll_addrgen_mode(Link *link);
 int ipv6ll_addrgen_mode_fill_message(sd_netlink_message *message, IPv6LinkLocalAddressGenMode mode);
+int link_update_ipv6ll_addrgen_mode(Link *link, sd_netlink_message *message);
 
 const char* ipv6_link_local_address_gen_mode_to_string(IPv6LinkLocalAddressGenMode s) _const_;
 IPv6LinkLocalAddressGenMode ipv6_link_local_address_gen_mode_from_string(const char *s) _pure_;
index 5f5f413fff586c253643cb96f987669fb0e4ba75..5a4b0b5a55928103b886d5ae5b9d18eb8d3300f3 100644 (file)
@@ -2318,6 +2318,10 @@ static int link_update(Link *link, sd_netlink_message *message) {
         if (r < 0)
                 return r;
 
+        r = link_update_ipv6ll_addrgen_mode(link, message);
+        if (r < 0)
+                return r;
+
         return link_update_flags(link, message);
 }
 
@@ -2391,6 +2395,8 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
                 .ifname = TAKE_PTR(ifname),
                 .kind = TAKE_PTR(kind),
 
+                .ipv6ll_address_gen_mode = _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID,
+
                 .state_file = TAKE_PTR(state_file),
                 .lease_file = TAKE_PTR(lease_file),
                 .lldp_file = TAKE_PTR(lldp_file),
index 8b3f1096571afb08c8900290df4e20790f149bec..47e8538d701920f7752b7684609fd7304d646a46 100644 (file)
@@ -68,6 +68,9 @@ typedef struct Link {
         sd_device *sd_device;
         char *driver;
 
+        /* link local addressing */
+        IPv6LinkLocalAddressGenMode ipv6ll_address_gen_mode;
+
         /* wlan */
         enum nl80211_iftype wlan_iftype;
         char *ssid;