X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=ubus.c;h=794444e8102896173cb42b100d8f0dfe801ba926;hp=513b40cc25ccd988ff28d87462b2548bf7c39856;hb=e6e1fd184841552bd343ef2b92378c1d84cb79f4;hpb=e93c42c036c4b4df1f65f261def31cf1a429e942 diff --git a/ubus.c b/ubus.c index 513b40c..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; @@ -135,11 +136,11 @@ netifd_add_dynamic(struct ubus_context *ctx, struct ubus_object *obj, const char *name = blobmsg_get_string(tb[DI_NAME]); - iface = calloc(1, sizeof(*iface)); + iface = interface_alloc(name, msg); if (!iface) return UBUS_STATUS_UNKNOWN_ERROR; - interface_init(iface, name, msg, true); + interface_set_dynamic(iface); iface->device_config = true; config = blob_memdup(msg); @@ -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,7 +659,12 @@ 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"); interface_ip_dump_address_list(&iface->config_ip, false, true); interface_ip_dump_address_list(&iface->proto_ip, false, true); @@ -762,9 +771,7 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, { struct blob_attr *tb[__DEV_MAX]; struct interface *iface; - struct device *dev; bool add = !strncmp(method, "add", 3); - int ret; iface = container_of(obj, struct interface, ubus); @@ -773,29 +780,7 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj, if (!tb[DEV_NAME]) return UBUS_STATUS_INVALID_ARGUMENT; - device_lock(); - - dev = device_get(blobmsg_data(tb[DEV_NAME]), add ? 2 : 0); - if (!dev) { - ret = UBUS_STATUS_NOT_FOUND; - goto out; - } - - if (add) { - device_set_present(dev, true); - if (iface->device_config) - device_set_config(dev, &simple_device_type, iface->config); - - system_if_apply_settings(dev, &dev->settings); - ret = interface_add_link(iface, dev); - } else { - ret = interface_remove_link(iface, dev); - } - -out: - device_unlock(); - - return ret; + return interface_handle_link(iface, blobmsg_data(tb[DEV_NAME]), add); } @@ -905,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)); @@ -966,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; @@ -990,7 +1103,7 @@ netifd_ubus_init(const char *path) void netifd_ubus_done(void) { - ubus_free(ctx); + ubus_free(ubus_ctx); } void @@ -999,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 @@ -1009,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 @@ -1026,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; @@ -1039,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); }