diff options
-rw-r--r-- | interface.c | 32 | ||||
-rw-r--r-- | interface.h | 4 | ||||
-rw-r--r-- | ubus.c | 57 |
3 files changed, 32 insertions, 61 deletions
diff --git a/interface.c b/interface.c index 3dceef0..2404878 100644 --- a/interface.c +++ b/interface.c @@ -351,17 +351,22 @@ interface_add(struct interface *iface, struct blob_attr *config) vlist_add(&interfaces, &iface->node); } -void +int interface_remove_link(struct interface *iface, struct device *dev) { struct device *mdev = iface->main_dev.dev; - if (mdev && mdev->hotplug_ops) { - mdev->hotplug_ops->del(mdev, dev); - return; - } + if (mdev && mdev->hotplug_ops) + return mdev->hotplug_ops->del(mdev, dev); + + if (!iface->main_dev.hotplug) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (dev != iface->main_dev.dev) + return UBUS_STATUS_INVALID_ARGUMENT; device_remove_user(&iface->main_dev); + return 0; } int @@ -369,14 +374,21 @@ interface_add_link(struct interface *iface, struct device *dev) { struct device *mdev = iface->main_dev.dev; - if (mdev && mdev->hotplug_ops) - return mdev->hotplug_ops->add(mdev, dev); + if (mdev == dev) + return 0; - if (iface->main_dev.dev) - interface_remove_link(iface, NULL); + if (iface->main_dev.hotplug) + device_remove_user(&iface->main_dev); - device_add_user(&iface->main_dev, dev); + if (mdev) { + if (mdev->hotplug_ops) + return mdev->hotplug_ops->add(mdev, dev); + else + return UBUS_STATUS_NOT_SUPPORTED; + } + device_add_user(&iface->main_dev, dev); + iface->main_dev.hotplug = true; return 0; } diff --git a/interface.h b/interface.h index 4580c5b..750c0f2 100644 --- a/interface.h +++ b/interface.h @@ -113,8 +113,8 @@ void __interface_set_down(struct interface *iface, bool force); void interface_add_user(struct interface_user *dep, struct interface *iface); void interface_remove_user(struct interface_user *dep); -int interface_add_link(struct interface *iface, struct device *llif); -void interface_remove_link(struct interface *iface, struct device *llif); +int interface_add_link(struct interface *iface, struct device *dev); +int interface_remove_link(struct interface *iface, struct device *dev); void interface_add_error(struct interface *iface, const char *subsystem, const char *code, const char **data, int n_data); @@ -269,11 +269,10 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { - struct interface *iface; - struct device *dev, *main_dev = NULL; struct blob_attr *tb[__DEV_MAX]; + struct interface *iface; + struct device *dev; bool add = !strncmp(method, "add", 3); - const char *devname; int ret; iface = container_of(obj, struct interface, ubus); @@ -283,57 +282,17 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, if (!tb[DEV_NAME]) return UBUS_STATUS_INVALID_ARGUMENT; - devname = blobmsg_data(tb[DEV_NAME]); - device_lock(); - if (iface->main_dev.hotplug) { - dev = iface->main_dev.dev; - - if (dev) { - if (!add && strcmp(dev->ifname, devname) != 0) { - ret = UBUS_STATUS_INVALID_ARGUMENT; - goto out; - } - - interface_set_available(iface, false); - device_remove_user(&iface->main_dev); - } - } else - main_dev = iface->main_dev.dev; - dev = device_get(blobmsg_data(tb[DEV_NAME]), add ? 2 : 0); - if (!dev && (main_dev || add)) { - ret = UBUS_STATUS_NOT_FOUND; - goto out; - } + if (add && !dev) + return UBUS_STATUS_NOT_FOUND; - if (!main_dev) { - if (add) { - device_add_user(&iface->main_dev, dev); - iface->main_dev.hotplug = true; - } - ret = 0; - goto out; - } + if (add) + return interface_add_link(iface, dev); + else + return interface_remove_link(iface, dev); - if (!main_dev->hotplug_ops) { - ret = UBUS_STATUS_NOT_SUPPORTED; - goto out; - } - - if (main_dev != dev) { - if (add) - ret = main_dev->hotplug_ops->add(main_dev, dev); - else - ret = main_dev->hotplug_ops->del(main_dev, dev); - if (ret) - ret = UBUS_STATUS_UNKNOWN_ERROR; - } else { - ret = UBUS_STATUS_INVALID_ARGUMENT; - } - -out: device_unlock(); return ret; |