diff options
author | Tom Gundersen <teg@jklm.no> | 2014-01-21 21:58:08 +0100 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-01-22 17:56:49 +0100 |
commit | 52433f6b65eccd1c54606dde999610640f3458ac (patch) | |
tree | 73f12a1b4541829c00462592be6ad275cf01a032 /src/network/networkd-link.c | |
parent | 01b36069ccddbed35b82dd3b64af3e522ab305fe (diff) |
networkd: add basic bonding support
Refactor bridging support to be generic netdev support and extend it to
cover bonding as well.
Diffstat (limited to 'src/network/networkd-link.c')
-rw-r--r-- | src/network/networkd-link.c | 96 |
1 files changed, 58 insertions, 38 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 2fa77f15ff..f746f2dcc4 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -95,7 +95,7 @@ int link_add(Manager *m, struct udev_device *device, Link **ret) { Network *network; int r; uint64_t ifindex; - const char *devtype; + NetdevKind kind; assert(m); assert(device); @@ -113,9 +113,9 @@ int link_add(Manager *m, struct udev_device *device, Link **ret) { *ret = link; - devtype = udev_device_get_devtype(device); - if (streq_ptr(devtype, "bridge")) { - r = bridge_set_link(m, link); + kind = netdev_kind_from_string(udev_device_get_devtype(device)); + if (kind != _NETDEV_KIND_INVALID) { + r = netdev_set_link(m, kind, link); if (r < 0 && r != -ENOENT) return r; } @@ -729,11 +729,11 @@ static int link_up(Link *link) { return 0; } -static int link_bridge_joined(Link *link) { +static int link_enslaved(Link *link) { int r; assert(link); - assert(link->state == LINK_STATE_JOINING_BRIDGE); + assert(link->state == LINK_STATE_ENSLAVING); assert(link->network); r = link_up(link); @@ -748,67 +748,87 @@ static int link_bridge_joined(Link *link) { return 0; } -static int bridge_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { +static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { Link *link = userdata; int r; assert(link); - assert(link->state == LINK_STATE_JOINING_BRIDGE || link->state == LINK_STATE_FAILED); + assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED); assert(link->network); + link->enslaving --; + if (link->state == LINK_STATE_FAILED) return 1; r = sd_rtnl_message_get_errno(m); if (r < 0) { - log_struct_link(LOG_ERR, link, - "MESSAGE=%s: could not join bridge '%s': %s", - link->ifname, link->network->bridge->name, strerror(-r), - BRIDGE(link->network->bridge), - NULL); + log_error_link(link, "could not enslave: %s", + strerror(-r)); link_enter_failed(link); return 1; } - log_struct_link(LOG_DEBUG, link, - "MESSAGE=%s: joined bridge '%s'", - link->network->bridge->name, - BRIDGE(link->network->bridge), - NULL); + log_debug_link(link, "enslaved"); - link_bridge_joined(link); + if (link->enslaving == 0) + link_enslaved(link); return 1; } -static int link_enter_join_bridge(Link *link) { +static int link_enter_enslave(Link *link) { int r; assert(link); assert(link->network); assert(link->state == _LINK_STATE_INVALID); - link->state = LINK_STATE_JOINING_BRIDGE; + link->state = LINK_STATE_ENSLAVING; - if (!link->network->bridge) - return link_bridge_joined(link); + if (!link->network->bridge && !link->network->bond) + return link_enslaved(link); - log_struct_link(LOG_DEBUG, link, - "MESSAGE=%s: joining bridge '%s'", - link->network->bridge->name, - BRIDGE(link->network->bridge), - NULL); - log_debug_link(link, "joining bridge"); + if (link->network->bridge) { + log_struct_link(LOG_DEBUG, link, + "MESSAGE=%s: enslaving by '%s'", + link->network->bridge->name, + NETDEV(link->network->bridge), + NULL); - r = bridge_join(link->network->bridge, link, &bridge_handler); - if (r < 0) { - log_struct_link(LOG_WARNING, link, - "MESSAGE=%s: could not join bridge '%s': %s", - link->network->bridge->name, strerror(-r), - BRIDGE(link->network->bridge), + r = netdev_enslave(link->network->bridge, link, &enslave_handler); + if (r < 0) { + log_struct_link(LOG_WARNING, link, + "MESSAGE=%s: could not enslave by '%s': %s", + link->network->bridge->name, strerror(-r), + NETDEV(link->network->bridge), + NULL); + link_enter_failed(link); + return r; + } + + link->enslaving ++; + } + + if (link->network->bond) { + log_struct_link(LOG_DEBUG, link, + "MESSAGE=%s: enslaving by '%s'", + link->network->bond->name, + NETDEV(link->network->bond), NULL); - link_enter_failed(link); - return r; + + r = netdev_enslave(link->network->bond, link, &enslave_handler); + if (r < 0) { + log_struct_link(LOG_WARNING, link, + "MESSAGE=%s: could not enslave by '%s': %s", + link->network->bond->name, strerror(-r), + NETDEV(link->network->bond), + NULL); + link_enter_failed(link); + return r; + } + + link->enslaving ++; } return 0; @@ -875,7 +895,7 @@ int link_configure(Link *link) { return r; } - return link_enter_join_bridge(link); + return link_enter_enslave(link); } int link_update(Link *link, sd_rtnl_message *m) { |