From: Felix Fietkau Date: Tue, 6 Jul 2021 08:29:20 +0000 (+0200) Subject: ubus: add api for modifying node script data X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=831b46a7054d8ba77f6a266a8f6d0ef3eff7bbe7;p=project%2Fusteer.git ubus: add api for modifying node script data This is replicated across nodes Signed-off-by: Felix Fietkau --- diff --git a/local_node.c b/local_node.c index 31c3377..f1bc385 100644 --- a/local_node.c +++ b/local_node.c @@ -62,6 +62,7 @@ usteer_free_node(struct ubus_context *ctx, struct usteer_local_node *ln) uloop_timeout_cancel(&ln->update); avl_delete(&local_nodes, &ln->node.avl); ubus_unregister_subscriber(ctx, &ln->ev); + kvlist_free(&ln->script_data); free(ln); } @@ -374,6 +375,7 @@ usteer_get_node(struct ubus_context *ctx, const char *name) ln->req_timer.cb = usteer_local_node_state_next; ubus_register_subscriber(ctx, &ln->ev); avl_insert(&local_nodes, &node->avl); + kvlist_init(&ln->script_data, kvlist_blob_len); INIT_LIST_HEAD(&node->sta_info); return ln; @@ -504,6 +506,23 @@ node_list_cb(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv) usteer_register_node(ctx, obj->path, obj->id); } +void usteer_local_node_update_script_data(struct usteer_local_node *ln) +{ + struct blob_attr *val; + const char *name; + + blob_buf_init(&b, 0); + kvlist_for_each(&ln->script_data, name, val) + blobmsg_add_field(&b, blobmsg_type(val), name, + blobmsg_data(val), blobmsg_len(val)); + + val = b.head; + if (!blobmsg_len(val)) + val = NULL; + + usteer_node_set_blob(&ln->node.script_data, val); +} + void config_set_node_up_script(struct blob_attr *data) { const char *val; diff --git a/node.h b/node.h index 34b030a..7d60528 100644 --- a/node.h +++ b/node.h @@ -51,6 +51,8 @@ struct usteer_local_node { uint64_t time, time_busy; + struct kvlist script_data; + struct { bool present; struct uloop_timeout update; diff --git a/ubus.c b/ubus.c index 8c6711a..7abc7dc 100644 --- a/ubus.c +++ b/ubus.c @@ -323,6 +323,79 @@ usteer_ubus_remote_info(struct ubus_context *ctx, struct ubus_object *obj, return 0; } +enum { + NODE_DATA_NODE, + NODE_DATA_VALUES, + __NODE_DATA_MAX, +}; + +static const struct blobmsg_policy set_node_data_policy[] = { + [NODE_DATA_NODE] = { "node", BLOBMSG_TYPE_STRING }, + [NODE_DATA_VALUES] = { "data", BLOBMSG_TYPE_TABLE }, +}; + +static const struct blobmsg_policy del_node_data_policy[] = { + [NODE_DATA_NODE] = { "node", BLOBMSG_TYPE_STRING }, + [NODE_DATA_VALUES] = { "names", BLOBMSG_TYPE_ARRAY }, +}; + +static void +__usteer_ubus_update_node_data(struct usteer_local_node *ln, struct blob_attr *data, + bool delete) +{ + struct blob_attr *cur; + int rem; + + blobmsg_for_each_attr(cur, data, rem) { + if (delete) + kvlist_delete(&ln->script_data, blobmsg_get_string(cur)); + else + kvlist_set(&ln->script_data, blobmsg_name(cur), cur); + } + + usteer_local_node_update_script_data(ln); +} + +static int +usteer_ubus_update_node_data(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + const struct blobmsg_policy *policy; + struct blob_attr *tb[__NODE_DATA_MAX]; + struct usteer_local_node *ln; + struct blob_attr *val; + const char *name; + bool delete; + + delete = !strncmp(method, "del", 3); + policy = delete ? del_node_data_policy : set_node_data_policy; + + blobmsg_parse(policy, __NODE_DATA_MAX, tb, blob_data(msg), blob_len(msg)); + if (!tb[NODE_DATA_NODE] || !tb[NODE_DATA_VALUES]) + return UBUS_STATUS_INVALID_ARGUMENT; + + name = blobmsg_get_string(tb[NODE_DATA_NODE]); + val = tb[NODE_DATA_VALUES]; + if (delete && blobmsg_check_array(val, BLOBMSG_TYPE_STRING) < 0) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (strcmp(name, "*") != 0) { + ln = avl_find_element(&local_nodes, name, ln, node.avl); + if (!ln) + return UBUS_STATUS_NOT_FOUND; + + __usteer_ubus_update_node_data(ln, val, delete); + + return 0; + } + + avl_for_each_element(&local_nodes, ln, node.avl) + __usteer_ubus_update_node_data(ln, val, delete); + + return 0; +} + static const struct ubus_method usteer_methods[] = { UBUS_METHOD_NOARG("local_info", usteer_ubus_local_info), UBUS_METHOD_NOARG("remote_info", usteer_ubus_remote_info), @@ -331,6 +404,8 @@ static const struct ubus_method usteer_methods[] = { UBUS_METHOD_NOARG("get_config", usteer_ubus_get_config), UBUS_METHOD("set_config", usteer_ubus_set_config, config_policy), UBUS_METHOD("update_config", usteer_ubus_set_config, config_policy), + UBUS_METHOD("set_node_data", usteer_ubus_update_node_data, set_node_data_policy), + UBUS_METHOD("delete_node_data", usteer_ubus_update_node_data, del_node_data_policy), }; static struct ubus_object_type usteer_obj_type = diff --git a/usteer.h b/usteer.h index b3c2b99..c28fac0 100644 --- a/usteer.h +++ b/usteer.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "utils.h" #include "timeout.h" @@ -229,6 +230,7 @@ bool usteer_handle_sta_event(struct usteer_node *node, const uint8_t *addr, void usteer_local_nodes_init(struct ubus_context *ctx); void usteer_local_node_kick(struct usteer_local_node *ln); +void usteer_local_node_update_script_data(struct usteer_local_node *ln); void usteer_ubus_init(struct ubus_context *ctx); void usteer_ubus_kick_client(struct sta_info *si);