summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorDaniel Mack <github@zonque.org>2015-07-01 19:26:01 -0400
committerDaniel Mack <github@zonque.org>2015-07-01 19:26:01 -0400
commit138879ccad87148cc5d805471183789a6ad688c6 (patch)
tree67991a36b23a7f55157ee6b0a1c31c502605160b /src/network
parentc9b9e8e9e2fa14fc3d4dd93240eb7d0b3df8732e (diff)
parent62e2d5bbabf0e6a5a262e9e1bed184552d98b0d9 (diff)
Merge pull request #409 from teg/networkd-enslave-segfault
fix segfault when cancelling enslaving of links by netdevs
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-link.c3
-rw-r--r--src/network/networkd-netdev.c13
2 files changed, 13 insertions, 3 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 16243a5352..dff81a5cf0 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1360,8 +1360,7 @@ static int link_joined(Link *link) {
return link_enter_set_addresses(link);
}
-static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m,
- void *userdata) {
+static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
int r;
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index ece9ecc251..6949b403c8 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -92,10 +92,11 @@ static void netdev_cancel_callbacks(NetDev *netdev) {
assert(netdev->manager);
assert(netdev->manager->rtnl);
- callback->callback(netdev->manager->rtnl, m, link);
+ callback->callback(netdev->manager->rtnl, m, callback->link);
}
LIST_REMOVE(callbacks, netdev->callbacks, callback);
+ link_unref(callback->link);
free(callback);
}
}
@@ -177,6 +178,8 @@ int netdev_get(Manager *manager, const char *name, NetDev **ret) {
static int netdev_enter_failed(NetDev *netdev) {
netdev->state = NETDEV_STATE_FAILED;
+ netdev_cancel_callbacks(netdev);
+
return 0;
}
@@ -266,12 +269,20 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t call
int r;
assert(netdev);
+ assert(netdev->manager);
+ assert(netdev->manager->rtnl);
assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
if (netdev->state == NETDEV_STATE_READY) {
r = netdev_enslave_ready(netdev, link, callback);
if (r < 0)
return r;
+ } else if (IN_SET(netdev->state, NETDEV_STATE_LINGER, NETDEV_STATE_FAILED)) {
+ _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL;
+
+ r = rtnl_message_new_synthetic_error(-ENODEV, 0, &m);
+ if (r >= 0)
+ callback(netdev->manager->rtnl, m, link);
} else {
/* the netdev is not yet read, save this request for when it is */
netdev_join_callback *cb;