summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface.c32
-rw-r--r--interface.h4
-rw-r--r--ubus.c57
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);
diff --git a/ubus.c b/ubus.c
index af5ba68..014a34e 100644
--- a/ubus.c
+++ b/ubus.c
@@ -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;