+ 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 (!main_dev) {
+ if (add) {
+ device_add_user(&iface->main_dev, dev);
+ iface->main_dev.hotplug = true;
+ }
+ ret = 0;
+ goto out;
+ }
+
+ 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;
+}
+
+
+static int
+netifd_iface_notify_proto(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct interface *iface;