make list of steering-enabled SSIDs configurable
authorFelix Fietkau <nbd@nbd.name>
Thu, 13 May 2021 14:06:16 +0000 (16:06 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 13 May 2021 14:09:29 +0000 (16:09 +0200)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
local_node.c
node.h
openwrt/usteer/files/etc/config/usteer
openwrt/usteer/files/etc/init.d/usteer
remote.c
ubus.c
usteer.h

index 40ae8718643906f1b07a738e5c55597d56c0bb0e..788fd99d623f9f4b8d3f49a02a4c88f8bd4c06e0 100644 (file)
@@ -42,6 +42,7 @@ usteer_local_node_state_reset(struct usteer_local_node *ln)
                return;
 
        ubus_abort_request(ubus_ctx, &ln->req);
+       uloop_timeout_cancel(&ln->req_timer);
        ln->req_state = REQ_IDLE;
 }
 
@@ -58,7 +59,6 @@ usteer_free_node(struct ubus_context *ctx, struct usteer_local_node *ln)
 
        usteer_local_node_state_reset(ln);
        usteer_sta_node_cleanup(&ln->node);
-       uloop_timeout_cancel(&ln->req_timer);
        uloop_timeout_cancel(&ln->update);
        avl_delete(&local_nodes, &ln->node.avl);
        ubus_unregister_subscriber(ctx, &ln->ev);
@@ -288,7 +288,7 @@ usteer_local_node_prepare_rrm_set(struct usteer_local_node *ln)
        void *c;
 
        c = blobmsg_open_array(&b, "list");
-       avl_for_each_element(&local_nodes, node, avl)
+       for_each_local_node(node)
                usteer_add_rrm_data(ln, node);
        avl_for_each_element(&remote_nodes, rn, avl)
                usteer_add_rrm_data(ln, &rn->node);
@@ -374,7 +374,6 @@ 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);
-       uloop_timeout_set(&ln->update, 1);
        INIT_LIST_HEAD(&node->sta_info);
 
        return ln;
@@ -392,7 +391,42 @@ usteer_node_run_update_script(struct usteer_node *node)
        val = alloca(strlen(node_up_script) + strlen(ln->iface) + 8);
        sprintf(val, "%s '%s'", node_up_script, ln->iface);
        if (system(val))
-               fprintf(stderr, "failed to execute %s\n", val);
+               MSG(INFO, "failed to execute %s\n", val);
+}
+
+static void
+usteer_check_node_enabled(struct usteer_local_node *ln)
+{
+       bool ssid_disabled = config.ssid_list;
+       struct blob_attr *cur;
+       int rem;
+
+       blobmsg_for_each_attr(cur, config.ssid_list, rem) {
+               if (strcmp(blobmsg_get_string(cur), ln->node.ssid) != 0)
+                       continue;
+
+               ssid_disabled = false;
+               break;
+       }
+
+       if (ln->node.disabled == ssid_disabled)
+               return;
+
+       ln->node.disabled = ssid_disabled;
+
+       if (ssid_disabled) {
+               MSG(INFO, "Disconnecting from local node %s\n", usteer_node_name(&ln->node));
+               usteer_local_node_state_reset(ln);
+               usteer_sta_node_cleanup(&ln->node);
+               uloop_timeout_cancel(&ln->update);
+               ubus_unsubscribe(ubus_ctx, &ln->ev, ln->obj_id);
+               return;
+       }
+
+       MSG(INFO, "Connecting to local node %s\n", usteer_node_name(&ln->node));
+       ubus_subscribe(ubus_ctx, &ln->ev, ln->obj_id);
+       uloop_timeout_set(&ln->update, 1);
+       usteer_node_run_update_script(&ln->node);
 }
 
 static void
@@ -407,7 +441,7 @@ usteer_register_node(struct ubus_context *ctx, const char *name, uint32_t id)
        if (strncmp(name, "hostapd.", iface - name) != 0)
                return;
 
-       MSG(INFO, "Connecting to local node %s\n", name);
+       MSG(INFO, "Creating local node %s\n", name);
        ln = usteer_get_node(ctx, name);
        ln->obj_id = id;
        ln->iface = usteer_node_name(&ln->node) + offset;
@@ -423,8 +457,6 @@ usteer_register_node(struct ubus_context *ctx, const char *name, uint32_t id)
        blobmsg_add_u8(&b, "bss_transition", 1);
        ubus_invoke(ctx, id, "bss_mgmt_enable", b.head, NULL, NULL, 1000);
 
-       ubus_subscribe(ctx, &ln->ev, id);
-
        list_for_each_entry(h, &node_handlers, list) {
                if (!h->init_node)
                        continue;
@@ -432,7 +464,8 @@ usteer_register_node(struct ubus_context *ctx, const char *name, uint32_t id)
                h->init_node(&ln->node);
        }
 
-       usteer_node_run_update_script(&ln->node);
+       ln->node.disabled = true;
+       usteer_check_node_enabled(ln);
 }
 
 static void
@@ -492,7 +525,7 @@ void config_set_node_up_script(struct blob_attr *data)
 
        node_up_script = strdup(val);
 
-       avl_for_each_element(&local_nodes, node, avl)
+       for_each_local_node(node)
                usteer_node_run_update_script(node);
 }
 
@@ -504,6 +537,27 @@ void config_get_node_up_script(struct blob_buf *buf)
        blobmsg_add_string(buf, "node_up_script", node_up_script);
 }
 
+void config_set_ssid_list(struct blob_attr *data)
+{
+       struct usteer_local_node *ln;
+
+       free(config.ssid_list);
+
+       if (data)
+               config.ssid_list = blob_memdup(data);
+       else
+               config.ssid_list = NULL;
+
+       avl_for_each_element(&local_nodes, ln, node.avl)
+               usteer_check_node_enabled(ln);
+}
+
+void config_get_ssid_list(struct blob_buf *buf)
+{
+       if (config.ssid_list)
+               blobmsg_add_blob(buf, config.ssid_list);
+}
+
 void
 usteer_local_nodes_init(struct ubus_context *ctx)
 {
diff --git a/node.h b/node.h
index efe9e1cb64f714a6dcaf7fc1d829e09e9f9082cf..34b030ae7c6be45978283b5bb1e66901f874da60 100644 (file)
--- a/node.h
+++ b/node.h
@@ -76,4 +76,9 @@ struct usteer_remote_node {
 extern struct avl_tree local_nodes;
 extern struct avl_tree remote_nodes;
 
+#define for_each_local_node(node)                      \
+       avl_for_each_element(&local_nodes, node, avl)   \
+               if (!node->disabled)
+
+
 #endif
index 47e6d523fd1c94a32fef851f1ac007a8afe58939..cb6ac4b6372ec642c02176ef873196f9c7619ecd 100644 (file)
@@ -106,3 +106,6 @@ config usteer
        # - load_kick_client
        # - signal_kick
        #option event_log_types ''
+
+       # List of SSIDs to enable steering on
+       #list ssid_list ''
index f89751147c9a813c0ba642aeabd05ed67f811a5c..8f953a7a247603596758e12377c507508d07ba1d 100755 (executable)
@@ -21,6 +21,19 @@ load_ifaces() {
        done
 }
 
+_add_string() {
+       json_add_string "" "$1"
+}
+
+uci_option_to_json_string_array() {
+       local cfg="$1"
+       local option="$2"
+
+       json_add_array "$option"
+       config_list_foreach "$cfg" "$option" _add_string
+       json_close_array
+}
+
 uci_option_to_json_bool() {
        local cfg="$1"
        local option="$2"
@@ -55,6 +68,7 @@ uci_usteer() {
        uci_option_to_json_bool "$cfg" load_kick_enabled
        uci_option_to_json_bool "$cfg" assoc_steering
        uci_option_to_json_string "$cfg" node_up_script
+       uci_option_to_json_string_array "$cfg" ssid_list
 
        for opt in \
                debug_level \
index fe412b09cc37c5f0d3c47222f6201d1637b7ffe1..5cd45b3e272aca1aa77cbde582c4e4c8ad05f83b 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -492,7 +492,7 @@ usteer_send_update_timer(struct uloop_timeout *t)
        uloop_timeout_set(t, config.remote_update_interval);
 
        c = usteer_update_init();
-       avl_for_each_element(&local_nodes, node, avl)
+       for_each_local_node(node)
                usteer_send_node(node, NULL);
 
        usteer_update_send(c);
diff --git a/ubus.c b/ubus.c
index 7ec724f7c13600de4eb29ab987f744a3d6237838..ef448917de2847078f3cab5f6dd6377bf60d2d71 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -167,7 +167,8 @@ struct cfg_item {
        _cfg(U32, load_kick_reason_code), \
        _cfg(ARRAY_CB, interfaces), \
        _cfg(STRING_CB, node_up_script), \
-       _cfg(ARRAY_CB, event_log_types)
+       _cfg(ARRAY_CB, event_log_types), \
+       _cfg(ARRAY_CB, ssid_list)
 
 enum cfg_items {
 #define _cfg(_type, _name) CFG_##_name
@@ -292,7 +293,7 @@ usteer_ubus_local_info(struct ubus_context *ctx, struct ubus_object *obj,
 
        blob_buf_init(&b, 0);
 
-       avl_for_each_element(&local_nodes, node, avl)
+       for_each_local_node(node)
                usteer_dump_node_info(node);
 
        ubus_send_reply(ctx, req, b.head);
@@ -375,7 +376,7 @@ int usteer_ubus_notify_client_disassoc(struct sta_info *si)
        blobmsg_printf(&b, "addr", MAC_ADDR_FMT, MAC_ADDR_DATA(si->sta->addr));
        blobmsg_add_u32(&b, "duration", config.roam_kick_delay);
        c = blobmsg_open_array(&b, "neighbors");
-       avl_for_each_element(&local_nodes, node, avl)
+       for_each_local_node(node)
                usteer_add_nr_entry(si->node, node);
        avl_for_each_element(&remote_nodes, rn, avl)
                usteer_add_nr_entry(si->node, &rn->node);
index 4306873f8550ad1a82939ce82313e44b00eaf164..b3c2b99b5fb2281cd585cfcf85a7ffd99821b39a 100644 (file)
--- a/usteer.h
+++ b/usteer.h
@@ -63,6 +63,7 @@ struct usteer_node {
        struct blob_attr *script_data;
        char ssid[33];
 
+       bool disabled;
        int freq;
        int noise;
        int n_assoc;
@@ -157,6 +158,8 @@ struct usteer_config {
 
        const char *node_up_script;
        uint32_t event_log_mask;
+
+       struct blob_attr *ssid_list;
 };
 
 struct sta_info_stats {
@@ -252,6 +255,9 @@ void config_get_interfaces(struct blob_buf *buf);
 void config_set_node_up_script(struct blob_attr *data);
 void config_get_node_up_script(struct blob_buf *buf);
 
+void config_set_ssid_list(struct blob_attr *data);
+void config_get_ssid_list(struct blob_buf *buf);
+
 int usteer_interface_init(void);
 void usteer_interface_add(const char *name);
 void usteer_sta_node_cleanup(struct usteer_node *node);