disable ipv6 for bridge member interfaces
[project/netifd.git] / ubus.c
diff --git a/ubus.c b/ubus.c
index ba9fb9e..5529e59 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -11,6 +11,7 @@
 
 static struct ubus_context *ctx = NULL;
 static struct blob_buf b;
+static struct netifd_fd ubus_fd;
 
 /* global object */
 
@@ -79,8 +80,57 @@ netifd_dev_status(struct ubus_context *ctx, struct ubus_object *obj,
        return 0;
 }
 
+enum {
+       ALIAS_ATTR_ALIAS,
+       ALIAS_ATTR_DEV,
+       __ALIAS_ATTR_MAX,
+};
+
+static const struct blobmsg_policy alias_attrs[__ALIAS_ATTR_MAX] = {
+       [ALIAS_ATTR_ALIAS] = { "alias", BLOBMSG_TYPE_ARRAY },
+       [ALIAS_ATTR_DEV] = { "device", BLOBMSG_TYPE_STRING },
+};
+
+static int
+netifd_handle_alias(struct ubus_context *ctx, struct ubus_object *obj,
+                   struct ubus_request_data *req, const char *method,
+                   struct blob_attr *msg)
+{
+       struct device *dev = NULL;
+       struct blob_attr *tb[__ALIAS_ATTR_MAX];
+       struct blob_attr *cur;
+       int rem;
+
+       blobmsg_parse(alias_attrs, __ALIAS_ATTR_MAX, tb, blob_data(msg), blob_len(msg));
+
+       if (!tb[ALIAS_ATTR_ALIAS])
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if ((cur = tb[ALIAS_ATTR_DEV]) != NULL) {
+               dev = device_get(blobmsg_data(cur), true);
+               if (!dev)
+                       return UBUS_STATUS_NOT_FOUND;
+       }
+
+       blobmsg_for_each_attr(cur, tb[ALIAS_ATTR_ALIAS], rem) {
+               if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
+                       goto error;
+
+               if (!blobmsg_check_attr(cur, NULL))
+                       goto error;
+
+               alias_notify_device(blobmsg_data(cur), dev);
+       }
+       return 0;
+
+error:
+       device_free_unused(dev);
+       return UBUS_STATUS_INVALID_ARGUMENT;
+}
+
 static struct ubus_method dev_object_methods[] = {
-       UBUS_METHOD("status", netifd_dev_status, dev_policy)
+       UBUS_METHOD("status", netifd_dev_status, dev_policy),
+       UBUS_METHOD("set_alias", netifd_handle_alias, alias_attrs),
 };
 
 static struct ubus_object_type dev_object_type =
@@ -105,6 +155,8 @@ netifd_ubus_init(const char *path)
        DPRINTF("connected as %08x\n", ctx->local_id);
        uloop_init();
        ubus_add_uloop(ctx);
+       ubus_fd.fd = ctx->sock.fd;
+       netifd_fd_add(&ubus_fd);
 
        ret = ubus_add_object(ctx, &main_object);
        if (ret)
@@ -196,24 +248,11 @@ netifd_handle_status(struct ubus_context *ctx, struct ubus_object *obj,
        if (iface->state == IFS_UP) {
                time_t cur = system_get_rtime();
                blobmsg_add_u32(&b, "uptime", cur - iface->start_time);
+               blobmsg_add_string(&b, "l3_device", iface->l3_dev->dev->ifname);
        }
 
-       if (iface->main_dev.dev) {
-               struct device *dev = iface->main_dev.dev;
-               const char *field;
-               void *devinfo;
-
-               /* use a different field for virtual devices */
-               if (dev->avl.key)
-                       field = "device";
-               else
-                       field = "link";
-
-               devinfo = blobmsg_open_table(&b, field);
-               blobmsg_add_string(&b, "name", dev->ifname);
-
-               blobmsg_close_table(&b, devinfo);
-       }
+       if (!(iface->proto_handler->flags & PROTO_FLAG_NODEV))
+               blobmsg_add_string(&b, "device", iface->main_dev.dev->ifname);
 
        if (!list_is_empty(&iface->errors))
                netifd_add_interface_errors(&b, iface);