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);
return netdev;
}
+void netdev_drop(NetDev *netdev) {
+ if (!netdev || netdev->state == NETDEV_STATE_LINGER)
+ return;
+
+ netdev->state = NETDEV_STATE_LINGER;
+
+ netdev_cancel_callbacks(netdev);
+
+ netdev_unref(netdev);
+
+ return;
+}
+
int netdev_get(Manager *manager, const char *name, NetDev **ret) {
NetDev *netdev;
log_info_netdev(netdev, "netdev ready");
LIST_FOREACH(callbacks, callback, netdev->callbacks) {
- /* enslave the links that were attempted to be enslaved befor the
+ /* enslave the links that were attempted to be enslaved before the
* link was ready */
netdev_enslave_ready(netdev, callback->link, callback->callback);
}
}
int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
+ int r;
+
if (netdev->kind == NETDEV_KIND_VLAN || netdev->kind == NETDEV_KIND_MACVLAN)
return netdev_create(netdev, link, callback);
if (netdev->state == NETDEV_STATE_READY) {
- netdev_enslave_ready(netdev, link, callback);
+ 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;