X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=ubus.c;h=794444e8102896173cb42b100d8f0dfe801ba926;hp=90636804bb6d61fb45649ddce18bf1114569d03c;hb=e6e1fd184841552bd343ef2b92378c1d84cb79f4;hpb=2fe499798dd5c80f0af27cdd53dc52260002c320 diff --git a/ubus.c b/ubus.c index 9063680..794444e 100644 --- a/ubus.c +++ b/ubus.c @@ -22,8 +22,9 @@ #include "proto.h" #include "ubus.h" #include "system.h" +#include "wireless.h" -static struct ubus_context *ctx = NULL; +struct ubus_context *ubus_ctx = NULL; static struct blob_buf b; static const char *ubus_path; @@ -319,8 +320,8 @@ static struct ubus_object dev_object = { static void netifd_ubus_add_fd(void) { - ubus_add_uloop(ctx); - system_fd_set_cloexec(ctx->sock.fd); + ubus_add_uloop(ubus_ctx); + system_fd_set_cloexec(ubus_ctx->sock.fd); } static void @@ -331,13 +332,13 @@ netifd_ubus_reconnect_timer(struct uloop_timeout *timeout) }; int t = 2; - if (ubus_reconnect(ctx, ubus_path) != 0) { + if (ubus_reconnect(ubus_ctx, ubus_path) != 0) { DPRINTF("failed to reconnect, trying again in %d seconds\n", t); uloop_timeout_set(&retry, t * 1000); return; } - DPRINTF("reconnected to ubus, new id: %08x\n", ctx->local_id); + DPRINTF("reconnected to ubus, new id: %08x\n", ubus_ctx->local_id); netifd_ubus_add_fd(); } @@ -441,6 +442,9 @@ interface_ip_dump_address_list(struct interface_ip_settings *ip, bool v6, if (addr->valid_until) blobmsg_add_u32(&b, "valid", addr->valid_until - now); + if (addr->pclass) + blobmsg_add_string(&b, "class", addr->pclass); + blobmsg_close_table(&b, a); } } @@ -655,6 +659,10 @@ netifd_dump_status(struct interface *iface) blobmsg_add_string(&b, "device", dev->ifname); if (iface->state == IFS_UP) { + if (iface->ip4table) + blobmsg_add_u32(&b, "ip4table", iface->ip4table); + if (iface->ip6table) + blobmsg_add_u32(&b, "ip6table", iface->ip6table); blobmsg_add_u32(&b, "metric", iface->metric); blobmsg_add_u8(&b, "delegation", !iface->proto_ip.no_delegation); a = blobmsg_open_array(&b, "ipv4-address"); @@ -882,7 +890,7 @@ static struct ubus_object iface_object = { static void netifd_add_object(struct ubus_object *obj) { - int ret = ubus_add_object(ctx, obj); + int ret = ubus_add_object(ubus_ctx, obj); if (ret != 0) fprintf(stderr, "Failed to publish object '%s': %s\n", obj->name, ubus_strerror(ret)); @@ -943,22 +951,150 @@ static void netifd_add_iface_object(void) netifd_add_object(&iface_object); } +static struct wireless_device * +get_wdev(struct blob_attr *msg, int *ret) +{ + struct blobmsg_policy wdev_policy = { + .name = "device", + .type = BLOBMSG_TYPE_STRING, + }; + struct blob_attr *dev_attr; + struct wireless_device *wdev = NULL; + + + blobmsg_parse(&wdev_policy, 1, &dev_attr, blob_data(msg), blob_len(msg)); + if (!dev_attr) { + *ret = UBUS_STATUS_INVALID_ARGUMENT; + return NULL; + } + + wdev = vlist_find(&wireless_devices, blobmsg_data(dev_attr), wdev, node); + if (!wdev) { + *ret = UBUS_STATUS_NOT_FOUND; + return NULL; + } + + *ret = 0; + return wdev; +} + +static int +netifd_handle_wdev_up(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct wireless_device *wdev; + int ret; + + wdev = get_wdev(msg, &ret); + if (ret == UBUS_STATUS_NOT_FOUND) + return ret; + + if (wdev) { + wireless_device_set_up(wdev); + } else { + vlist_for_each_element(&wireless_devices, wdev, node) + wireless_device_set_up(wdev); + } + + return 0; +} + +static int +netifd_handle_wdev_down(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct wireless_device *wdev; + int ret; + + wdev = get_wdev(msg, &ret); + if (ret == UBUS_STATUS_NOT_FOUND) + return ret; + + if (wdev) { + wireless_device_set_down(wdev); + } else { + vlist_for_each_element(&wireless_devices, wdev, node) + wireless_device_set_down(wdev); + } + + return 0; +} + +static int +netifd_handle_wdev_status(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct wireless_device *wdev; + int ret; + + wdev = get_wdev(msg, &ret); + if (ret == UBUS_STATUS_NOT_FOUND) + return ret; + + blob_buf_init(&b, 0); + if (wdev) { + wireless_device_status(wdev, &b); + } else { + vlist_for_each_element(&wireless_devices, wdev, node) + wireless_device_status(wdev, &b); + } + ubus_send_reply(ctx, req, b.head); + return 0; +} + +static int +netifd_handle_wdev_notify(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct wireless_device *wdev; + int ret; + + wdev = get_wdev(msg, &ret); + if (!wdev) + return ret; + + return wireless_device_notify(wdev, msg, req); +} + +static struct ubus_method wireless_object_methods[] = { + { .name = "up", .handler = netifd_handle_wdev_up }, + { .name = "down", .handler = netifd_handle_wdev_down }, + { .name = "status", .handler = netifd_handle_wdev_status }, + { .name = "notify", .handler = netifd_handle_wdev_notify }, +}; + +static struct ubus_object_type wireless_object_type = + UBUS_OBJECT_TYPE("netifd_iface", wireless_object_methods); + + +static struct ubus_object wireless_object = { + .name = "network.wireless", + .type = &wireless_object_type, + .methods = wireless_object_methods, + .n_methods = ARRAY_SIZE(wireless_object_methods), +}; + int netifd_ubus_init(const char *path) { uloop_init(); ubus_path = path; - ctx = ubus_connect(path); - if (!ctx) + ubus_ctx = ubus_connect(path); + if (!ubus_ctx) return -EIO; - DPRINTF("connected as %08x\n", ctx->local_id); - ctx->connection_lost = netifd_ubus_connection_lost; + DPRINTF("connected as %08x\n", ubus_ctx->local_id); + ubus_ctx->connection_lost = netifd_ubus_connection_lost; netifd_ubus_add_fd(); netifd_add_object(&main_object); netifd_add_object(&dev_object); + netifd_add_object(&wireless_object); netifd_add_iface_object(); return 0; @@ -967,7 +1103,7 @@ netifd_ubus_init(const char *path) void netifd_ubus_done(void) { - ubus_free(ctx); + ubus_free(ubus_ctx); } void @@ -976,7 +1112,7 @@ netifd_ubus_interface_event(struct interface *iface, bool up) blob_buf_init(&b, 0); blobmsg_add_string(&b, "action", up ? "ifup" : "ifdown"); blobmsg_add_string(&b, "interface", iface->name); - ubus_send_event(ctx, "network.interface", b.head); + ubus_send_event(ubus_ctx, "network.interface", b.head); } void @@ -986,8 +1122,8 @@ netifd_ubus_interface_notify(struct interface *iface, bool up) blob_buf_init(&b, 0); blobmsg_add_string(&b, "interface", iface->name); netifd_dump_status(iface); - ubus_notify(ctx, &iface_object, event, b.head, -1); - ubus_notify(ctx, &iface->ubus, event, b.head, -1); + ubus_notify(ubus_ctx, &iface_object, event, b.head, -1); + ubus_notify(ubus_ctx, &iface->ubus, event, b.head, -1); } void @@ -1003,7 +1139,7 @@ netifd_ubus_add_interface(struct interface *iface) obj->type = &iface_object_type; obj->methods = iface_object_methods; obj->n_methods = ARRAY_SIZE(iface_object_methods); - if (ubus_add_object(ctx, &iface->ubus)) { + if (ubus_add_object(ubus_ctx, &iface->ubus)) { DPRINTF("failed to publish ubus object for interface '%s'\n", iface->name); free(name); obj->name = NULL; @@ -1016,6 +1152,6 @@ netifd_ubus_remove_interface(struct interface *iface) if (!iface->ubus.name) return; - ubus_remove_object(ctx, &iface->ubus); + ubus_remove_object(ubus_ctx, &iface->ubus); free((void *) iface->ubus.name); }