]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/networkd-address-label.c
Merge pull request #16316 from yuwata/backlight-use-actual-brightness
[thirdparty/systemd.git] / src / network / networkd-address-label.c
index 98e40d3f6a1d535544618328c752e2763d7e375a..32b79dd1548107c0f8fd13df148bd93e5254faff 100644 (file)
 #include "parse-util.h"
 #include "socket-util.h"
 
-int address_label_new(AddressLabel **ret) {
-        _cleanup_(address_label_freep) AddressLabel *addrlabel = NULL;
-
-        addrlabel = new0(AddressLabel, 1);
-        if (!addrlabel)
-                return -ENOMEM;
-
-        *ret = TAKE_PTR(addrlabel);
-
-        return 0;
-}
-
 void address_label_free(AddressLabel *label) {
         if (!label)
                 return;
@@ -50,40 +38,79 @@ static int address_label_new_static(Network *network, const char *filename, unsi
         assert(ret);
         assert(!!filename == (section_line > 0));
 
-        r = network_config_section_new(filename, section_line, &n);
-        if (r < 0)
-                return r;
+        if (filename) {
+                r = network_config_section_new(filename, section_line, &n);
+                if (r < 0)
+                        return r;
 
-        label = hashmap_get(network->address_labels_by_section, n);
-        if (label) {
-                *ret = TAKE_PTR(label);
+                label = hashmap_get(network->address_labels_by_section, n);
+                if (label) {
+                        *ret = TAKE_PTR(label);
 
-                return 0;
+                        return 0;
+                }
         }
 
-        r = address_label_new(&label);
-        if (r < 0)
-                return r;
-
-        label->section = TAKE_PTR(n);
+        label = new(AddressLabel, 1);
+        if (!label)
+                return -ENOMEM;
 
-        r = hashmap_put(network->address_labels_by_section, label->section, label);
-        if (r < 0)
-                return r;
+        *label = (AddressLabel) {
+                .network = network,
+        };
 
-        label->network = network;
         LIST_APPEND(labels, network->address_labels, label);
         network->n_address_labels++;
 
+        if (filename) {
+                label->section = TAKE_PTR(n);
+
+                r = hashmap_ensure_allocated(&network->address_labels_by_section, &network_config_hash_ops);
+                if (r < 0)
+                        return r;
+
+                r = hashmap_put(network->address_labels_by_section, label->section, label);
+                if (r < 0)
+                        return r;
+        }
+
         *ret = TAKE_PTR(label);
 
         return 0;
 }
 
+static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+        int r;
+
+        assert(rtnl);
+        assert(m);
+        assert(link);
+        assert(link->ifname);
+        assert(link->address_label_messages > 0);
+
+        link->address_label_messages--;
+
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return 1;
+
+        r = sd_netlink_message_get_errno(m);
+        if (r < 0 && r != -EEXIST) {
+                log_link_message_warning_errno(link, m, r, "Could not set address label");
+                link_enter_failed(link);
+                return 1;
+        } else if (r >= 0)
+                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+
+        if (link->address_label_messages == 0)
+                log_link_debug(link, "Addresses label set");
+
+        return 1;
+}
+
 int address_label_configure(
                 AddressLabel *label,
                 Link *link,
-                sd_netlink_message_handler_t callback,
+                link_netlink_message_handler_t callback,
                 bool update) {
 
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
@@ -98,24 +125,25 @@ int address_label_configure(
         r = sd_rtnl_message_new_addrlabel(link->manager->rtnl, &req, RTM_NEWADDRLABEL,
                                           link->ifindex, AF_INET6);
         if (r < 0)
-                return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m");
+                return log_link_error_errno(link, r, "Could not allocate RTM_NEWADDR message: %m");
 
         r = sd_rtnl_message_addrlabel_set_prefixlen(req, label->prefixlen);
         if (r < 0)
-                return log_error_errno(r, "Could not set prefixlen: %m");
+                return log_link_error_errno(link, r, "Could not set prefixlen: %m");
 
         r = sd_netlink_message_append_u32(req, IFAL_LABEL, label->label);
         if (r < 0)
-                return log_error_errno(r, "Could not append IFAL_LABEL attribute: %m");
+                return log_link_error_errno(link, r, "Could not append IFAL_LABEL attribute: %m");
 
         r = sd_netlink_message_append_in6_addr(req, IFA_ADDRESS, &label->in_addr.in6);
         if (r < 0)
-                return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
+                return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m");
 
-        r = sd_netlink_call_async(link->manager->rtnl, NULL, req, callback,
-                                  link_netlink_destroy_callback, link, 0, __func__);
+        r = netlink_call_async(link->manager->rtnl, NULL, req,
+                               callback ?: address_label_handler,
+                               link_netlink_destroy_callback, link);
         if (r < 0)
-                return log_error_errno(r, "Could not send rtnetlink message: %m");
+                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
 
         link_ref(link);
 
@@ -133,7 +161,7 @@ int config_parse_address_label_prefix(const char *unit,
                                       void *data,
                                       void *userdata) {
 
-        _cleanup_(address_label_freep) AddressLabel *n = NULL;
+        _cleanup_(address_label_free_or_set_invalidp) AddressLabel *n = NULL;
         Network *network = userdata;
         int r;
 
@@ -170,7 +198,7 @@ int config_parse_address_label(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(address_label_freep) AddressLabel *n = NULL;
+        _cleanup_(address_label_free_or_set_invalidp) AddressLabel *n = NULL;
         Network *network = userdata;
         uint32_t k;
         int r;