X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=ubus.c;h=af5ba6815d5c5dca60d65cff5a7072a97de47720;hp=a9b0057769cec817cee370042a84f2443b7c3044;hb=f5ca090c260a74fd3576f79ffb8799e8c20e3878;hpb=ccca61c97d460d73f29750abdf38cea20ac440f3;ds=sidebyside diff --git a/ubus.c b/ubus.c index a9b0057..af5ba68 100644 --- a/ubus.c +++ b/ubus.c @@ -284,28 +284,34 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, return UBUS_STATUS_INVALID_ARGUMENT; devname = blobmsg_data(tb[DEV_NAME]); - dev = iface->main_dev.dev; - if (iface->hotplug_dev && dev && !add) { - if (strcmp(dev->ifname, devname) != 0) - return UBUS_STATUS_INVALID_ARGUMENT; - } - if (iface->hotplug_dev) { - if (iface->main_dev.dev) { + 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); - if (!dev) - return UBUS_STATUS_NOT_FOUND; + dev = device_get(blobmsg_data(tb[DEV_NAME]), add ? 2 : 0); + if (!dev && (main_dev || add)) { + ret = UBUS_STATUS_NOT_FOUND; + goto out; + } if (!main_dev) { if (add) { device_add_user(&iface->main_dev, dev); - iface->hotplug_dev = true; + iface->main_dev.hotplug = true; } ret = 0; goto out; @@ -328,8 +334,7 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, } out: - if (add) - device_free_unused(dev); + device_unlock(); return ret; } @@ -375,10 +380,32 @@ netifd_iface_remove(struct ubus_context *ctx, struct ubus_object *obj, return 0; } +static int +netifd_handle_iface_prepare(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; + const struct device_hotplug_ops *ops; + + iface = container_of(obj, struct interface, ubus); + dev = iface->main_dev.dev; + if (!dev) + return 0; + + ops = dev->hotplug_ops; + if (!ops) + return 0; + + return ops->prepare(dev); +} + static struct ubus_method iface_object_methods[] = { { .name = "up", .handler = netifd_handle_up }, { .name = "down", .handler = netifd_handle_down }, { .name = "status", .handler = netifd_handle_status }, + { .name = "prepare", .handler = netifd_handle_iface_prepare }, UBUS_METHOD("add_device", netifd_iface_handle_device, dev_policy ), UBUS_METHOD("remove_device", netifd_iface_handle_device, dev_policy ), { .name = "notify_proto", .handler = netifd_iface_notify_proto },