]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: use request queue to set link flags
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 21 May 2021 04:50:39 +0000 (13:50 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 7 Jun 2021 21:33:27 +0000 (06:33 +0900)
src/network/networkd-link.c
src/network/networkd-setlink.c
src/network/networkd-setlink.h

index fb2b9c2a3f31a4011fa8f61ca00b7065c352515d..261e7384cdeb950f5425946162499a427c6355f9 100644 (file)
@@ -974,81 +974,6 @@ static int link_set_nomaster(Link *link) {
         return 0;
 }
 
-static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
-        int r;
-
-        assert(m);
-        assert(link);
-        assert(link->ifname);
-
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0)
-                log_link_message_warning_errno(link, m, r, "Could not set link flags, ignoring");
-
-        return 1;
-}
-
-static int link_set_flags(Link *link) {
-        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
-        unsigned ifi_change = 0;
-        unsigned ifi_flags = 0;
-        int r;
-
-        assert(link);
-        assert(link->manager);
-        assert(link->manager->rtnl);
-
-        if (link->flags & IFF_LOOPBACK)
-                return 0;
-
-        if (!link->network)
-                return 0;
-
-        if (link->network->arp < 0 && link->network->multicast < 0 && link->network->allmulticast < 0 &&
-            link->network->promiscuous < 0)
-                return 0;
-
-        r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
-        if (r < 0)
-                return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
-
-        if (link->network->arp >= 0) {
-                ifi_change |= IFF_NOARP;
-                SET_FLAG(ifi_flags, IFF_NOARP, link->network->arp == 0);
-        }
-
-        if (link->network->multicast >= 0) {
-                ifi_change |= IFF_MULTICAST;
-                SET_FLAG(ifi_flags, IFF_MULTICAST, link->network->multicast);
-        }
-
-        if (link->network->allmulticast >= 0) {
-                ifi_change |= IFF_ALLMULTI;
-                SET_FLAG(ifi_flags, IFF_ALLMULTI, link->network->allmulticast);
-        }
-
-        if (link->network->promiscuous >= 0) {
-                ifi_change |= IFF_PROMISC;
-                SET_FLAG(ifi_flags, IFF_PROMISC, link->network->promiscuous);
-        }
-
-        r = sd_rtnl_message_link_set_flags(req, ifi_flags, ifi_change);
-        if (r < 0)
-                return log_link_error_errno(link, r, "Could not set link flags: %m");
-
-        r = netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
-                               link_netlink_destroy_callback, link);
-        if (r < 0)
-                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
-
-        link_ref(link);
-
-        return 0;
-}
-
 static int link_acquire_dynamic_ipv6_conf(Link *link) {
         int r;
 
@@ -2010,7 +1935,7 @@ static int link_configure(Link *link) {
         if (r < 0)
                 return r;
 
-        r = link_set_flags(link);
+        r = link_request_to_set_flags(link);
         if (r < 0)
                 return r;
 
index 32866ee5de47c4b55977cddc31dd19768afc182b..9ea78fa81872ff5b024b5b2a70f5f5704411f85d 100644 (file)
@@ -1,5 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <netinet/in.h>
+#include <linux/if.h>
+
 #include "missing_network.h"
 #include "netlink-util.h"
 #include "networkd-link.h"
@@ -8,6 +11,7 @@
 #include "string-table.h"
 
 static const char *const set_link_operation_table[_SET_LINK_OPERATION_MAX] = {
+        [SET_LINK_FLAGS]                   = "link flags",
         [SET_LINK_MTU]                     = "MTU",
 };
 
@@ -42,6 +46,10 @@ static int set_link_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Li
         return 1;
 }
 
+static int link_set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+        return set_link_handler_internal(rtnl, m, link, SET_LINK_FLAGS, true);
+}
+
 static int link_set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
@@ -87,6 +95,35 @@ static int link_configure(
                 return log_link_debug_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
 
         switch (op) {
+        case SET_LINK_FLAGS: {
+                unsigned ifi_change = 0, ifi_flags = 0;
+
+                if (link->network->arp >= 0) {
+                        ifi_change |= IFF_NOARP;
+                        SET_FLAG(ifi_flags, IFF_NOARP, link->network->arp == 0);
+                }
+
+                if (link->network->multicast >= 0) {
+                        ifi_change |= IFF_MULTICAST;
+                        SET_FLAG(ifi_flags, IFF_MULTICAST, link->network->multicast);
+                }
+
+                if (link->network->allmulticast >= 0) {
+                        ifi_change |= IFF_ALLMULTI;
+                        SET_FLAG(ifi_flags, IFF_ALLMULTI, link->network->allmulticast);
+                }
+
+                if (link->network->promiscuous >= 0) {
+                        ifi_change |= IFF_PROMISC;
+                        SET_FLAG(ifi_flags, IFF_PROMISC, link->network->promiscuous);
+                }
+
+                r = sd_rtnl_message_link_set_flags(req, ifi_flags, ifi_change);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Could not set link flags: %m");
+
+                break;
+        }
         case SET_LINK_MTU:
                 r = sd_netlink_message_append_u32(req, IFLA_MTU, PTR_TO_UINT32(userdata));
                 if (r < 0)
@@ -164,6 +201,19 @@ static int link_request_set_link(
         return 0;
 }
 
+int link_request_to_set_flags(Link *link) {
+        assert(link);
+        assert(link->network);
+
+        if (link->network->arp < 0 &&
+            link->network->multicast < 0 &&
+            link->network->allmulticast < 0 &&
+            link->network->promiscuous < 0)
+                return 0;
+
+        return link_request_set_link(link, SET_LINK_FLAGS, link_set_flags_handler, NULL);
+}
+
 int link_request_to_set_mtu(Link *link, uint32_t mtu) {
         Request *req = NULL;  /* avoid false maybe-uninitialized warning */
         int r;
index e2d32886dbfcd8cb2dec247297730ceaa3aa814f..0e9e0d61c4ff851a84f254d99fc2aeedf2778810 100644 (file)
@@ -7,11 +7,13 @@ typedef struct Link Link;
 typedef struct Request Request;
 
 typedef enum SetLinkOperation {
+        SET_LINK_FLAGS,                   /* Setting IFF_NOARP or friends. */
         SET_LINK_MTU,                     /* Setting MTU. */
         _SET_LINK_OPERATION_MAX,
         _SET_LINK_OPERATION_INVALID = -EINVAL,
 } SetLinkOperation;
 
+int link_request_to_set_flags(Link *link);
 int link_request_to_set_mtu(Link *link, uint32_t mtu);
 
 int link_configure_mtu(Link *link);