]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: introduce link_request_to_set_master()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 25 May 2021 06:00:33 +0000 (15:00 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 7 Jun 2021 21:33:27 +0000 (06:33 +0900)
The function will be used later.

src/network/networkd-setlink.c
src/network/networkd-setlink.h

index 89b414a321f90c043477220ee3e0e6b209f98515..0bcd2a4d95f0335960a4fd7ab32a1786d7aee711 100644 (file)
@@ -16,6 +16,7 @@ static const char *const set_link_operation_table[_SET_LINK_OPERATION_MAX] = {
         [SET_LINK_FLAGS]                   = "link flags",
         [SET_LINK_GROUP]                   = "interface group",
         [SET_LINK_MAC]                     = "MAC address",
+        [SET_LINK_MASTER]                  = "master interface",
         [SET_LINK_MTU]                     = "MTU",
 };
 
@@ -78,6 +79,10 @@ static int link_set_mac_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *l
         return set_link_handler_internal(rtnl, m, link, SET_LINK_MAC, true);
 }
 
+static int link_set_master_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+        return set_link_handler_internal(rtnl, m, link, SET_LINK_MASTER, true);
+}
+
 static int link_set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
@@ -183,6 +188,11 @@ static int link_configure(
                 if (r < 0)
                         return log_link_debug_errno(link, r, "Could not append IFLA_ADDRESS attribute: %m");
                 break;
+        case SET_LINK_MASTER:
+                r = sd_netlink_message_append_u32(req, IFLA_MASTER, PTR_TO_UINT32(userdata));
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Could not append IFLA_MASTER attribute: %m");
+                break;
         case SET_LINK_MTU:
                 r = sd_netlink_message_append_u32(req, IFLA_MTU, PTR_TO_UINT32(userdata));
                 if (r < 0)
@@ -201,16 +211,70 @@ static int link_configure(
         return 0;
 }
 
+static bool netdev_is_ready(NetDev *netdev) {
+        assert(netdev);
+
+        if (netdev->state != NETDEV_STATE_READY)
+                return false;
+        if (netdev->ifindex == 0)
+                return false;
+
+        return true;
+}
+
 static bool link_is_ready_to_call_set_link(Request *req) {
+        SetLinkOperation op;
         Link *link;
+        int r;
 
         assert(req);
 
         link = req->link;
+        op = req->set_link_operation;
 
         if (!IN_SET(link->state, LINK_STATE_INITIALIZED, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
                 return false;
 
+        switch (op) {
+        case SET_LINK_MASTER: {
+                uint32_t m = 0;
+
+                assert(link->network);
+
+                if (link->network->batadv) {
+                        if (!netdev_is_ready(link->network->batadv))
+                                return false;
+                        m = link->network->batadv->ifindex;
+                } else if (link->network->bond) {
+                        if (!netdev_is_ready(link->network->bond))
+                                return false;
+                        m = link->network->bond->ifindex;
+
+                        if (FLAGS_SET(link->flags, IFF_UP)) {
+                                /* link must be down when joining to bond master. */
+                                r = link_down(link, NULL);
+                                if (r < 0) {
+                                        link_enter_failed(link);
+                                        return false;
+                                }
+                        }
+                } else if (link->network->bridge) {
+                        if (!netdev_is_ready(link->network->bridge))
+                                return false;
+                        m = link->network->bridge->ifindex;
+                } else if (link->network->vrf) {
+                        if (!netdev_is_ready(link->network->vrf))
+                                return false;
+                        m = link->network->vrf->ifindex;
+                }
+
+                req->userdata = UINT32_TO_PTR(m);
+                break;
+        }
+        default:
+                break;
+        }
+
         return true;
 }
 
@@ -329,6 +393,12 @@ int link_request_to_set_mac(Link *link) {
         return link_request_set_link(link, SET_LINK_MAC, link_set_mac_handler, NULL);
 }
 
+int link_request_to_set_master(Link *link) {
+        assert(link);
+
+        return link_request_set_link(link, SET_LINK_MASTER, link_set_master_handler, NULL);
+}
+
 int link_request_to_set_mtu(Link *link, uint32_t mtu) {
         Request *req = NULL;  /* avoid false maybe-uninitialized warning */
         int r;
index 33f1bbd37a015717d2aad238092b2c960e8c59b7..8baf7829ed06b97b670311c2d6a2455e59f32b8b 100644 (file)
@@ -11,6 +11,7 @@ typedef enum SetLinkOperation {
         SET_LINK_FLAGS,                   /* Setting IFF_NOARP or friends. */
         SET_LINK_GROUP,                   /* Setting interface group. */
         SET_LINK_MAC,                     /* Setting MAC address. */
+        SET_LINK_MASTER,                  /* Setting IFLA_MASTER. */
         SET_LINK_MTU,                     /* Setting MTU. */
         _SET_LINK_OPERATION_MAX,
         _SET_LINK_OPERATION_INVALID = -EINVAL,
@@ -20,6 +21,7 @@ int link_request_to_set_addrgen_mode(Link *link);
 int link_request_to_set_flags(Link *link);
 int link_request_to_set_group(Link *link);
 int link_request_to_set_mac(Link *link);
+int link_request_to_set_master(Link *link);
 int link_request_to_set_mtu(Link *link, uint32_t mtu);
 
 int link_configure_mtu(Link *link);