]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/networkd-address-label.c
network: drop sections contain invalid settings in network_verify()
[thirdparty/systemd.git] / src / network / networkd-address-label.c
index b89995ec4426556e6d5a2b721064c29ec36022b6..ab738448c52bdc1c1e6775bdd183ef3491663427 100644 (file)
@@ -1,21 +1,4 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2017 Susant Sahani
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include <net/if.h>
 #include <linux/if_addrlabel.h>
 #include "parse-util.h"
 #include "socket-util.h"
 
-int address_label_new(AddressLabel **ret) {
-        _cleanup_address_label_free_ AddressLabel *addrlabel = NULL;
-
-        addrlabel = new0(AddressLabel, 1);
-        if (!addrlabel)
-                return -ENOMEM;
-
-        *ret = addrlabel;
-        addrlabel = NULL;
-
-        return 0;
-}
-
 void address_label_free(AddressLabel *label) {
         if (!label)
                 return;
@@ -60,51 +30,85 @@ void address_label_free(AddressLabel *label) {
 }
 
 static int address_label_new_static(Network *network, const char *filename, unsigned section_line, AddressLabel **ret) {
-        _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
-        _cleanup_address_label_free_ AddressLabel *label = NULL;
+        _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
+        _cleanup_(address_label_freep) AddressLabel *label = NULL;
         int r;
 
         assert(network);
         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 = label;
-                label = NULL;
+                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 = n;
-        n = NULL;
+        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++;
 
-        *ret = label;
-        label = NULL;
+        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_warning_errno(link, r, "could not set address label: %m");
+        else if (r >= 0)
+                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;
@@ -133,7 +137,9 @@ int address_label_configure(
         if (r < 0)
                 return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
 
-        r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+        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");
 
@@ -153,7 +159,7 @@ int config_parse_address_label_prefix(const char *unit,
                                       void *data,
                                       void *userdata) {
 
-        _cleanup_address_label_free_ AddressLabel *n = NULL;
+        _cleanup_(address_label_free_or_set_invalidp) AddressLabel *n = NULL;
         Network *network = userdata;
         int r;
 
@@ -190,7 +196,7 @@ int config_parse_address_label(
                 void *data,
                 void *userdata) {
 
-        _cleanup_address_label_free_ AddressLabel *n = NULL;
+        _cleanup_(address_label_free_or_set_invalidp) AddressLabel *n = NULL;
         Network *network = userdata;
         uint32_t k;
         int r;
@@ -212,7 +218,7 @@ int config_parse_address_label(
         }
 
         if (k == 0xffffffffUL) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Adress label is invalid, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Address label is invalid, ignoring: %s", rvalue);
                 return 0;
         }