DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode);
DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
-void netdev_free(NetDev *netdev) {
+static void netdev_free(NetDev *netdev) {
netdev_enslave_callback *callback;
if (!netdev)
free(netdev);
}
+NetDev *netdev_unref(NetDev *netdev) {
+ if (netdev && (-- netdev->n_ref <= 0))
+ netdev_free(netdev);
+
+ return NULL;
+}
+
+NetDev *netdev_ref(NetDev *netdev) {
+ if (netdev)
+ assert_se(++ netdev->n_ref >= 2);
+
+ return netdev;
+}
+
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;
}
static int netdev_load_one(Manager *manager, const char *filename) {
- _cleanup_netdev_free_ NetDev *netdev = NULL;
+ _cleanup_netdev_unref_ NetDev *netdev = NULL;
_cleanup_fclose_ FILE *file = NULL;
int r;
if (!netdev)
return log_oom();
+ netdev->n_ref = 1;
netdev->manager = manager;
netdev->state = _NETDEV_STATE_INVALID;
netdev->kind = _NETDEV_KIND_INVALID;
assert(manager);
while ((netdev = hashmap_first(manager->netdevs)))
- netdev_free(netdev);
+ netdev_unref(netdev);
r = conf_files_list_strv(&files, ".netdev", NULL, network_dirs);
if (r < 0) {