X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fnetwork%2Fnetworkd-netdev.c;h=36decf459a5cc71651120a0fe9448573ac6dac82;hb=370e9930c3260cc58984ec70e44b1e2ab7676496;hp=5ee257f984b815a97e3a2a4896acccf8fc200e13;hpb=b226d99b044222739dccfa9cf9f7a9d79576c407;p=elogind.git diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 5ee257f98..36decf459 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -48,16 +48,35 @@ static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = { DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode); DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode"); -static void netdev_free(NetDev *netdev) { +static void netdev_cancel_callbacks(NetDev *netdev) { + _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; netdev_enslave_callback *callback; if (!netdev) return; + rtnl_message_new_synthetic_error(-ENODEV, 0, &m); + while ((callback = netdev->callbacks)) { + if (m) { + assert(callback->link); + assert(callback->callback); + assert(netdev->manager); + assert(netdev->manager->rtnl); + + callback->callback(netdev->manager->rtnl, m, link); + } + LIST_REMOVE(callbacks, netdev->callbacks, callback); free(callback); } +} + +static void netdev_free(NetDev *netdev) { + if (!netdev) + return; + + netdev_cancel_callbacks(netdev); if (netdev->name) hashmap_remove(netdev->manager->netdevs, netdev->name); @@ -89,6 +108,21 @@ NetDev *netdev_ref(NetDev *netdev) { return netdev; } +void netdev_drop(NetDev *netdev) { + if (!netdev || netdev->state == NETDEV_STATE_LINGER) + return; + + netdev->state = NETDEV_STATE_LINGER; + + log_debug_netdev(netdev, "dropped"); + + netdev_cancel_callbacks(netdev); + + netdev_unref(netdev); + + return; +} + int netdev_get(Manager *manager, const char *name, NetDev **ret) { NetDev *netdev;