chiark / gitweb /
networkd: netdev - split out bridge creation
[elogind.git] / src / network / networkd-netdev.c
index a8c1ea3b44a7e3b24f4409c66a2069298611fc46..0a2e319db17121641d127637eadc678348b96dfd 100644 (file)
@@ -48,9 +48,10 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
 DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
 
+
 static void netdev_cancel_callbacks(NetDev *netdev) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
-        netdev_enslave_callback *callback;
+        netdev_join_callback *callback;
 
         if (!netdev)
                 return;
@@ -160,6 +161,7 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_rtnl_message_hand
         assert(netdev->state == NETDEV_STATE_READY);
         assert(netdev->manager);
         assert(netdev->manager->rtnl);
+        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
         assert(link);
         assert(callback);
 
@@ -196,7 +198,7 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_rtnl_message_hand
 }
 
 static int netdev_enter_ready(NetDev *netdev) {
-        netdev_enslave_callback *callback, *callback_next;
+        netdev_join_callback *callback, *callback_next;
         int r;
 
         assert(netdev);
@@ -244,109 +246,38 @@ static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda
         return 1;
 }
 
-static int netdev_create(NetDev *netdev) {
-        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
-        const char *kind;
+static int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
         int r;
 
         assert(netdev);
-        assert(netdev->ifname);
-        assert(netdev->manager);
-        assert(netdev->manager->rtnl);
-
-        r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, 0);
-        if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not allocate RTM_NEWLINK message: %s",
-                                 strerror(-r));
-                return r;
-        }
+        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
 
-        r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname);
-        if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not append IFLA_IFNAME attribute: %s",
-                                 strerror(-r));
-                return r;
-        }
-
-        if (netdev->mtu) {
-                r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu);
-                if (r < 0) {
-                        log_error_netdev(netdev,
-                                         "Could not append IFLA_MTU attribute: %s",
-                                         strerror(-r));
+        if (netdev->state == NETDEV_STATE_READY) {
+                r = netdev_enslave_ready(netdev, link, callback);
+                if (r < 0)
                         return r;
-                }
-        }
-
-        if (netdev->mac) {
-                r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac);
-                if (r < 0) {
-                        log_error_netdev(netdev,
-                                         "Colud not append IFLA_ADDRESS attribute: %s",
-                                         strerror(-r));
-                    return r;
-                }
-        }
-
-        r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
-        if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not open IFLA_LINKINFO container: %s",
-                                 strerror(-r));
-                return r;
-        }
-
-        kind = netdev_kind_to_string(netdev->kind);
-        if (!kind) {
-                log_error_netdev(netdev, "Invalid kind");
-                return -EINVAL;
-        }
-
-        r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, kind);
-        if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not open IFLA_INFO_DATA container: %s",
-                                  strerror(-r));
-                return r;
-        }
+        } else {
+                /* the netdev is not yet read, save this request for when it is*/
+                netdev_join_callback *cb;
 
-        r = sd_rtnl_message_close_container(req);
-        if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not close IFLA_INFO_DATA container %s",
-                                 strerror(-r));
-                return r;
-        }
+                cb = new0(netdev_join_callback, 1);
+                if (!cb)
+                        return log_oom();
 
-        r = sd_rtnl_message_close_container(req);
-        if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not close IFLA_LINKINFO container %s",
-                                 strerror(-r));
-                return r;
-        }
+                cb->callback = callback;
+                cb->link = link;
+                link_ref(link);
 
-        r = sd_rtnl_call_async(netdev->manager->rtnl, req, &netdev_create_handler, netdev, 0, NULL);
-        if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not send rtnetlink message: %s", strerror(-r));
-                return r;
+                LIST_PREPEND(callbacks, netdev->callbacks, cb);
         }
 
-        netdev_ref(netdev);
-
-        log_debug_netdev(netdev, "creating netdev");
-
-        netdev->state = NETDEV_STATE_CREATING;
-
         return 0;
 }
 
 /* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
-int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
-        int r;
+int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
+
+        assert(netdev);
 
         switch(netdev->kind) {
         case NETDEV_KIND_VLAN:
@@ -360,27 +291,11 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callbac
         case NETDEV_KIND_SIT:
         case NETDEV_KIND_VTI:
                 return netdev_create_tunnel(netdev, link, callback);
+        case NETDEV_KIND_BRIDGE:
+        case NETDEV_KIND_BOND:
+                return netdev_enslave(netdev, link, callback);
         default:
-                break;
-        }
-
-        if (netdev->state == NETDEV_STATE_READY) {
-                r = netdev_enslave_ready(netdev, link, callback);
-                if (r < 0)
-                        return r;
-        } else {
-                /* the netdev is not yet read, save this request for when it is*/
-                netdev_enslave_callback *cb;
-
-                cb = new0(netdev_enslave_callback, 1);
-                if (!cb)
-                        return log_oom();
-
-                cb->callback = callback;
-                cb->link = link;
-                link_ref(link);
-
-                LIST_PREPEND(callbacks, netdev->callbacks, cb);
+                assert_not_reached("Enslaving by invalid netdev kind");
         }
 
         return 0;
@@ -565,13 +480,14 @@ static int netdev_load_one(Manager *manager, const char *filename) {
         netdev->state = _NETDEV_STATE_INVALID;
         netdev->kind = _NETDEV_KIND_INVALID;
         netdev->macvlan_mode = _NETDEV_MACVLAN_MODE_INVALID;
+        netdev->bond_mode = _NETDEV_BOND_MODE_INVALID;
         netdev->vlanid = VLANID_MAX + 1;
         netdev->vxlanid = VXLAN_VID_MAX + 1;
         netdev->tunnel_pmtudisc = true;
         netdev->learning = true;
 
         r = config_parse(NULL, filename, file,
-                         "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0Tun\0Tap\0",
+                         "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0Tun\0Tap\0Bond\0",
                          config_item_perf_lookup, (void*) network_netdev_gperf_lookup,
                          false, false, netdev);
         if (r < 0) {
@@ -694,19 +610,15 @@ static int netdev_load_one(Manager *manager, const char *filename) {
 
                 break;
         case NETDEV_KIND_BRIDGE:
-        case NETDEV_KIND_BOND:
-                r = netdev_create(netdev);
+                r = netdev_create_bridge(netdev, netdev_create_handler);
                 if (r < 0)
                         return r;
                 break;
-
-        case NETDEV_KIND_TUN:
-        case NETDEV_KIND_TAP:
-                r = netdev_create_tuntap(netdev);
+        case NETDEV_KIND_BOND:
+                r = netdev_create_bond(netdev, netdev_create_handler);
                 if (r < 0)
                         return r;
                 break;
-
         default:
                 break;
         }