diff --git a/src/Makefile b/src/Makefile index 5cb37d52ce6aa9143c5a9b18baf5dfac471d1ef6..623ad30c4257c78b064a48fd8587f47a25019482 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,8 +20,8 @@ CNTLR_OBJS = \ core/cntlr_ubus.o \ core/cntlr.o \ core/cntlr_map.o \ + core/config.o \ core/main.o - #core/config.o \ LIBS = -lubus -lubox -ljson-c -lblobmsg_json -luci -pthread LIBS += -rdynamic -ldl diff --git a/src/controller.conf b/src/controller.conf index f46ae102d9d97600b8f6a6152c29c36be181f931..c7fe7b4e36c1f6cb62a42533e86fc5537ba170d9 100644 --- a/src/controller.conf +++ b/src/controller.conf @@ -1,6 +1,6 @@ config wificntlr option enabled '1' - list registrar '5 2' #bands on which wps registrar supported + option registrar '5 2' #bands on which wps registrar supported config fh-credentials option band '5' diff --git a/src/core/config.c b/src/core/config.c index bbcbf746141a57a48b28b79d71b7f6cd19123380..1ce3210024f2bcb3c430e60313bebb634c09a18f 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -9,7 +9,11 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> +#include <netinet/in.h> +#include <arpa/inet.h> + #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif @@ -26,792 +30,315 @@ #include "debug.h" #include "utils.h" #include "config.h" -//#include "steer_rules.h" #include "comm.h" #include "msgqueue.h" #include "worker.h" #include "cntlr.h" +#include "config.h" -//TODO: remove -struct stax{ - char macstring[32]; /* ':' separated mac address string */ - struct list_head list; -}; -//////////// - -static struct netif_fhcfg *get_netif_fhcfg_by_name(struct cntlr_config *c, - const char *name) +void cntlr_config_dump(struct controller_config *c) { - struct netif_fhcfg *p; - - list_for_each_entry(p, &c->fhlist, list) { - if (!strcmp(name, p->name)) - return p; + int i; + + dbg("Controller config ---------\n"); + dbg("Enabled: %d\n", c->enabled); + dbg("Registrar @5Ghz: %d\n", c->has_registrar_5g); + dbg("Registrar @2Ghz: %d\n", c->has_registrar_2g); + + dbg("Credentials: Fronthaul\n"); + for (i = 0; i < c->num_fh; i++) { + dbg(" Band : %d\n", c->fh[i].band); + dbg(" Security: 0x%x\n", c->fh[i].sec); + dbg(" Key : \n"); + dbg(" ssid : %s\n", c->fh[i].ssid); + dbg(" vlan : %d\n\n", c->fh[i].vlanid); } - return NULL; -} - -static struct steer_policy *get_steer_policy_by_name(struct netif_fhcfg *c, - const char *name) -{ - struct steer_policy *p; - - if (!c) - return NULL; - - list_for_each_entry(p, &c->steer_policylist, list) { - if (!strcmp(name, p->name)) - return p; + dbg("Credentials: Backhaul\n"); + for (i = 0; i < c->num_bk; i++) { + dbg(" Band : %d\n", c->bk[i].band); + dbg(" Security: 0x%x\n", c->bk[i].sec); + dbg(" Key : \n"); + dbg(" ssid : %s\n", c->bk[i].ssid); + dbg(" vlan : %d\n\n", c->bk[i].vlanid); } - return NULL; + dbg("Agents policy: Default\n"); + dbg(" Id : " MACFMT "\n", MAC2STR(c->apolicy.id)); + dbg(" Steer-policy : %d\n", c->apolicy.policy); + dbg(" Util-threshold : %d\n", c->apolicy.util_threshold); + dbg(" RCPI-threshold : %d\n", c->apolicy.rcpi_threshold); + dbg(" Report scan : %d\n", c->apolicy.report_scan); + dbg(" Report assocfails : %d\n", c->apolicy.report_sta_assocfails); + dbg(" Report metric : %d\n", c->apolicy.report_metric_periodic); + dbg(" Report RCPI-thresh : %d\n", c->apolicy.report_rcpi_threshold); + dbg(" Report Util-thresh : %d\n", c->apolicy.report_util_threshold); + dbg(" Include STA stats : %d\n", c->apolicy.include_sta_stats); + dbg(" Include STA metric : %d\n", c->apolicy.include_sta_metric); + dbg(" Primary VLAN ID : %d\n", c->apolicy.pvid); + dbg(" PCP Default : %d\n", c->apolicy.pcp_default); + dbg(" Disallow bSTA P1 : %d\n", c->apolicy.disallow_bsta_p1); + dbg(" Disallow bSTA P2 : %d\n", c->apolicy.disallow_bsta_p2); + + dbg("---------------------------\n"); } -void stax_add_entry(struct list_head *h, char *sta_macstr) +int cntlr_config_defaults(struct controller *cntlr, struct controller_config *c) { - struct stax *n; + memset(c, 0, sizeof(*c)); + INIT_LIST_HEAD(&c->policylist); - n = calloc(1, sizeof(struct stax)); - if (n) { - snprintf(n->macstring, 18, "%s", sta_macstr); - list_add(&n->list, h); - } + return 0; } -void stax_del_entry(struct list_head *h, char *sta_macstr) +static int cntlr_config_get_base(struct controller_config *c, + struct uci_section *s) { - struct stax *s, *tmp; + enum { + CNTLR_ENABLED, + CNTLR_REGISTRAR, + NUM_CNTLR_ATTRS, + }; + const struct uci_parse_option opts[] = { + { .name = "enabled", .type = UCI_TYPE_STRING }, + { .name = "registrar", .type = UCI_TYPE_STRING }, + }; + struct uci_option *tb[NUM_CNTLR_ATTRS]; - list_for_each_entry_safe(s, tmp, h, list) { - if (!strncmp(s->macstring, sta_macstr, sizeof(s->macstring))) { - list_del(&s->list); - free(s); - return; - } - } -} -void cntlr_config_dump(struct cntlr_config *cfg) -{ - struct netif_fhcfg *n; - struct steer_policy *pol; - struct stax *x; - - if (!cfg) - return; - - list_for_each_entry(n, &cfg->fhlist, list) { - dbg("name: %s\n", n->name); - dbg(" enabled : %s\n", n->enabled ? "true" : "false"); - dbg(" assocctrl: %s\n", n->assoc_control ? "true" : "false"); - - dbg(" Policies -------\n"); - list_for_each_entry(pol, &n->steer_policylist, list) { - dbg(" name: %s\n", pol->name); - dbg(" enabled : %s\n", pol->enabled ? "true" : "false"); - /* if (pol->dump_config) - pol->dump_config(pol, pol->policy); */ - } + uci_parse_section(s, opts, NUM_CNTLR_ATTRS, tb); - dbg(" Steer Exclude Lists -------\n"); - list_for_each_entry(x, &n->steer_excludelist, list) { - dbg(" mac: %s\n", x->macstring); - } + if (tb[CNTLR_ENABLED]) { + const char *val = tb[CNTLR_ENABLED]->v.string; - dbg(" Steer BTM Exclude Lists -------\n"); - list_for_each_entry(x, &n->steer_btm_excludelist, list) { - dbg(" mac: %s\n", x->macstring); - } - - dbg(" Assoc Ctrl Lists -------\n"); - list_for_each_entry(x, &n->assoc_ctrllist, list) { - dbg(" mac: %s\n", x->macstring); - } + c->enabled = atoi(val) == 1 ? true : false; } -} -int cntlr_config_defaults(struct cntlr *a, struct cntlr_config *cfg) -{ - struct list_head *p, *tmp; - struct netif_fh *ifptr; - struct netif_fhcfg *new; - - if (!cfg) - return -1; + if (tb[CNTLR_REGISTRAR]) { + const char *val = tb[CNTLR_REGISTRAR]->v.string; - cfg->enabled = false; - cfg->runfreq = AGENT_RUN_AUTO; - - INIT_LIST_HEAD(&cfg->fhlist); - INIT_LIST_HEAD(&cfg->bklist); - list_for_each_entry(ifptr, &a->fhlist, list) { - /* struct list_head pollist; */ - struct steer_rule *r; - - new = calloc(1, sizeof(struct netif_fhcfg)); - if (!new) { - warn("OOM! config\n"); - goto err_alloc; - } - - snprintf(new->name, 16, "%s", ifptr->name); - new->enabled = false; - new->steer_btm_retry = STEER_BTM_RETRY; - new->steer_btm_retry_secs = STEER_BTM_RETRY_INT; - new->fallback_legacy = STEER_LEGACY_FALLBACK_INT; - new->steer_legacy_reassoc_secs = STEER_LEGACY_REASSOC_INT; - new->steer_legacy_retry_secs = STEER_LEGACY_RETRY_INT; - new->assoc_control_time = ASSOC_CONTROL_INT; - INIT_LIST_HEAD(&new->steer_policylist); - /* nrules = get_registered_steer_rules(&pollist); */ /* TODO */ - list_for_each_entry(r, ®d_steer_rules, list) { - struct steer_policy *pol; - - pol = calloc(1, sizeof(struct steer_policy)); - if (!pol) - goto err_alloc_policy; - - snprintf(pol->name, 16, "%s", r->name); - pol->enabled = false; - if (r->init_config) - r->init_config(r, &pol->policy); - list_add(&pol->list, &new->steer_policylist); - } - - INIT_LIST_HEAD(&new->steer_excludelist); - INIT_LIST_HEAD(&new->steer_btm_excludelist); - INIT_LIST_HEAD(&new->assoc_ctrllist); - - ifptr->cfg = new; - dbg("%s: %s netif_fh->cfg = %p\n", __func__, ifptr->name, ifptr->cfg); - list_add(&new->list, &cfg->fhlist); + c->has_registrar_5g = !strstr(val, "5") ? false : true; + c->has_registrar_2g = !strstr(val, "2") ? false : true; } return 0; - -err_alloc_policy: - /* TODO */ -err_alloc: - list_for_each_safe(p, tmp, &cfg->fhlist) { - list_del(p); - free(p); - } - - return -1; } -/* create fh-iface config and initialize with default values */ -struct netif_fhcfg *create_fronthaul_iface_config(struct cntlr_config *cfg, - const char *ifname) +static int cntlr_config_get_credentials(struct controller_config *c, + struct uci_section *s) { - struct netif_fhcfg *new; - struct steer_rule *r; - - if (!cfg) - return NULL; + enum { + CRED_BAND, + CRED_SSID, + CRED_SEC, + CRED_KEY, + CRED_VLAN, + NUM_CREDS, + }; + const struct uci_parse_option opts[] = { + [CRED_BAND] = { .name = "band", .type = UCI_TYPE_STRING }, + [CRED_SSID] = { .name = "ssid", .type = UCI_TYPE_STRING }, + [CRED_SEC] = { .name = "encryption", .type = UCI_TYPE_STRING }, + [CRED_KEY] = { .name = "key", .type = UCI_TYPE_STRING }, + [CRED_VLAN] = { .name = "vlan", .type = UCI_TYPE_STRING }, + }; + struct uci_option *tb[NUM_CREDS]; + struct iface_credential *cred; + + + if (!strcmp(s->type, "fh-credentials")) { + if (c->num_fh >= 2) + return -1; + + cred = &c->fh[c->num_fh++]; + } else { + if (c->num_bk >= 2) + return -1; - new = calloc(1, sizeof(struct netif_fhcfg)); - if (!new) { - warn("OOM! config\n"); - return NULL; + cred = &c->bk[c->num_bk++]; } - snprintf(new->name, 16, "%s", ifname); - new->enabled = true; - new->fallback_legacy = STEER_LEGACY_FALLBACK_INT; - new->steer_btm_retry_secs = STEER_BTM_RETRY_INT; - new->steer_legacy_reassoc_secs = STEER_LEGACY_REASSOC_INT; - new->steer_legacy_retry_secs = STEER_LEGACY_RETRY_INT; - new->assoc_control_time = ASSOC_CONTROL_INT; - INIT_LIST_HEAD(&new->steer_policylist); - /* nrules = get_registered_steer_rules(&pollist); */ /* TODO */ - list_for_each_entry(r, ®d_steer_rules, list) { - struct steer_policy *pol; - - pol = calloc(1, sizeof(struct steer_policy)); - if (!pol) { - goto err_oom; - } + uci_parse_section(s, opts, NUM_CREDS, tb); - snprintf(pol->name, 16, "%s", r->name); - pol->enabled = false; - if (r->init_config) - r->init_config(r, &pol->policy); - list_add(&pol->list, &new->steer_policylist); + if (tb[CRED_BAND]) { + if (atoi(tb[CRED_BAND]->v.string) == 5) + cred->band = WIFI_BAND_5; + else if (atoi(tb[CRED_BAND]->v.string) == 2) + cred->band = WIFI_BAND_2; } - INIT_LIST_HEAD(&new->steer_excludelist); - INIT_LIST_HEAD(&new->steer_btm_excludelist); - INIT_LIST_HEAD(&new->assoc_ctrllist); + if (tb[CRED_SSID]) + memcpy(cred->ssid, tb[CRED_SSID]->v.string, 32); - /* f->cfg = new; */ - dbg("%s: %s netif_fh->cfg = %p\n", __func__, new->name, new); + if (tb[CRED_SEC]) { + const char *sec = tb[CRED_SEC]->v.string; + + if (!strncmp(sec, "psk3", 4)) + cred->sec = WIFI_SECURITY_WPA3PSK; + else if (!strncmp(sec, "psk2", 4)) + cred->sec = WIFI_SECURITY_WPA2PSK; + else if (!strncmp(sec, "psk", 3)) + cred->sec = WIFI_SECURITY_WPAPSK; + + //TODO: ciphers (if any) + } - list_add(&new->list, &cfg->fhlist); + if (tb[CRED_KEY]) + memcpy(cred->key, tb[CRED_KEY]->v.string, 63); - return new; + if (tb[CRED_VLAN]) + cred->vlanid = atoi(tb[CRED_VLAN]->v.string); -err_oom: - list_flush(&new->steer_policylist, struct steer_policy, list); - free(new); - return NULL; + return 0; } -int cntlr_config_reload(const char *confname, struct cntlr_config *cfg) +static int cntlr_config_get_agent_policy(struct controller_config *c, + struct uci_section *s) { - struct uci_context *ctx = NULL; - struct uci_package *pkg = NULL; - struct uci_element *e; - - ctx = uci_alloc_context(); - if (ctx && uci_load(ctx, confname, &pkg) != UCI_OK) { - err("config file '%s' not found!\n", confname); - uci_free_context(ctx); - return -1; + enum { + POL_ID, + POL_STEER, + POL_UTIL_TH, + POL_RCPI_TH, + POL_RPT_SCAN, + POL_RPT_ASSOC_FAILS, + POL_RPT_METRIC_PERIODIC, + POL_RPT_RCPI_TH, + POL_RPT_UTIL_TH, + POL_INC_STA_STATS, + POL_INC_STA_METRIC, + POL_PVID, + POL_PCP_DEFAULT, + POL_DISALLOW_BSTA_P1, + POL_DISALLOW_BSTA_P2, + NUM_POLICIES, + }; + const struct uci_parse_option opts[] = { + { .name = "id", .type = UCI_TYPE_STRING }, + { .name = "steer_policy", .type = UCI_TYPE_STRING }, + { .name = "util_threshold", .type = UCI_TYPE_STRING }, + { .name = "rcpi_threshold", .type = UCI_TYPE_STRING }, + { .name = "report_scan", .type = UCI_TYPE_STRING }, + { .name = "report_sta_assocfails", .type = UCI_TYPE_STRING }, + { .name = "report_metric_periodic", .type = UCI_TYPE_STRING }, + { .name = "report_rcpi_threshold", .type = UCI_TYPE_STRING }, + { .name = "report_util_threshold", .type = UCI_TYPE_STRING }, + { .name = "include_sta_stats", .type = UCI_TYPE_STRING }, + { .name = "include_sta_metric", .type = UCI_TYPE_STRING }, + { .name = "pvid", .type = UCI_TYPE_STRING }, + { .name = "pcp_default", .type = UCI_TYPE_STRING }, + { .name = "disallow_bsta_p1", .type = UCI_TYPE_STRING }, + { .name = "disallow_bsta_p2", .type = UCI_TYPE_STRING }, + }; + struct uci_option *tb[NUM_POLICIES]; + + uci_parse_section(s, opts, NUM_POLICIES, tb); + + + if (tb[POL_ID]) { + const char *val = tb[POL_ID]->v.string; + + hwaddr_aton(val, c->apolicy.id); } - uci_foreach_element(&pkg->sections, e) { - struct uci_section *s = uci_to_section(e); + if (tb[POL_STEER]) + c->apolicy.policy = atoi(tb[POL_STEER]->v.string); - if (!strcmp(s->type, "wificntlr")) { - struct uci_element *x; - struct uci_option *op; - bool enabled = false; - - uci_foreach_element(&s->options, x) { - op = uci_to_option(x); - if (!strncmp(x->name, "enabled", 7) && - op->type == UCI_TYPE_STRING) { - dbg("wificntlr: enabled = %d\n", atoi(op->v.string)); - enabled = atoi(op->v.string) == 1 ? - true : false; - cfg->enabled = enabled; - } else if (!strncmp(x->name, "runfreq", 7) && - op->type == UCI_TYPE_STRING) { - dbg("wificntlr: speed = %s\n", op->v.string); - if (!strncasecmp(op->v.string, "auto", 4)) - cfg->runfreq = AGENT_RUN_AUTO; - else if (!strncasecmp(op->v.string, "low", 3)) - cfg->runfreq = AGENT_RUN_LOW; - else if (!strncasecmp(op->v.string, "high", 4)) - cfg->runfreq = AGENT_RUN_HIGH; - else if (!strncasecmp(op->v.string, "off", 3)) - cfg->runfreq = AGENT_RUN_OFF; - } /* else if (!strncmp(x->name, "ifname", 6) && - op->type == UCI_TYPE_LIST) { - struct uci_element *xi; - - dbg("wificntlr: ifname: "); - uci_foreach_element(&op->v.list, xi) { - dbg("%s ", xi->name); - } - dbg("\n"); - } */ - } - } else if (!strcmp(s->type, "fh-iface")) { - struct uci_element *x; - struct uci_option *op; - bool disabled = false; - unsigned int steer_btm_retry = STEER_BTM_RETRY; - unsigned int steer_btm_retry_secs = STEER_BTM_RETRY_INT; - unsigned int legacy = STEER_LEGACY_FALLBACK_INT; - unsigned int steer_legacy_reassoc_secs = STEER_LEGACY_REASSOC_INT; - unsigned int steer_legacy_retry_secs = STEER_LEGACY_RETRY_INT; - unsigned int assoc_ctrl_secs = ASSOC_CONTROL_INT; - struct netif_fhcfg *ifcfg = NULL; - - uci_foreach_element(&s->options, x) { - op = uci_to_option(x); - if (!strncmp(x->name, "disabled", 8) && - op->type == UCI_TYPE_STRING) { - dbg("wificntlr: disabled = %d\n", atoi(op->v.string)); - disabled = atoi(op->v.string) == 1 ? - true : false; - } else if (!strncmp(x->name, "ifname", 6) && - op->type == UCI_TYPE_STRING) { - /* struct uci_element *xi; */ - - ifcfg = get_netif_fhcfg_by_name(cfg, op->v.string); - if (!ifcfg) { - ifcfg = create_fronthaul_iface_config(cfg, op->v.string); - if (!ifcfg) { - warn("%s: OOM!\n", __func__); - break; - } - } else { - warn("Duplicate 'fh-iface %s' config!! ignore\n", - op->v.string); - } - - list_flush(&ifcfg->steer_excludelist, struct stax, list); - list_flush(&ifcfg->steer_btm_excludelist, struct stax, list); - list_flush(&ifcfg->assoc_ctrllist, struct stax, list); - - } else if (!strncmp(x->name, "btm_retry", 9) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: btm_retry = %d\n", - atoi(op->v.string)); - if (atoi(op->v.string) >= 0) - steer_btm_retry = atoi(op->v.string); - } else if (!strncmp(x->name, "btm_retry_secs", 14) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: btm_retry_secs = %d\n", - atoi(op->v.string)); - if (atoi(op->v.string) >= 0) - steer_btm_retry_secs = atoi(op->v.string); - } else if (!strncmp(x->name, "fallback_legacy", 15) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: legacy = %d\n", - atoi(op->v.string)); - if (atoi(op->v.string) >= 0) - legacy = atoi(op->v.string); - } else if (!strncmp(x->name, "steer_legacy_reassoc_secs", 25) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: steer_legacy_rassoc_secs = %d\n", - atoi(op->v.string)); - steer_legacy_reassoc_secs = atoi(op->v.string); - } else if (!strncmp(x->name, "steer_legacy_retry_secs", 23) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: steer_legacy_retry_secs = %d\n", - atoi(op->v.string)); - steer_legacy_retry_secs = atoi(op->v.string); - } else if (!strncmp(x->name, "assoc_ctrl", 10) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: assoc_ctlr = %d\n", - atoi(op->v.string)); - if (atoi(op->v.string) >= 0) - assoc_ctrl_secs = atoi(op->v.string); - } else if (!strncmp(x->name, "steer", 5) && - op->type == UCI_TYPE_LIST) { - struct uci_element *xi; - - dbg("Steer: param: "); - uci_foreach_element(&op->v.list, xi) { - struct steer_policy *p = NULL; - struct steer_rule *r; - - dbg("%s ", xi->name); - p = get_steer_policy_by_name(ifcfg, xi->name); - if (!p) { - /* TODO? */ - dbg("TODO!! steer before ifname\n"); - continue; - } - p->enabled = true; - r = get_steer_rule_by_name(xi->name); - if (r) - r->enabled = true; - } - dbg("\n"); - } else if (!strncmp(x->name, "exclude_btm", 11) && - op->type == UCI_TYPE_LIST) { - struct uci_element *xi; - - dbg("Steer: exclude_btm: "); - uci_foreach_element(&op->v.list, xi) { - dbg("%s ", xi->name); - stax_add_entry(&ifcfg->steer_btm_excludelist, xi->name); - } - dbg("\n"); - } else if (!strncmp(x->name, "exclude", 7) && - op->type == UCI_TYPE_LIST) { - struct uci_element *xi; - - dbg("Steer: exclude: "); - uci_foreach_element(&op->v.list, xi) { - dbg("%s ", xi->name); - stax_add_entry(&ifcfg->steer_excludelist, xi->name); - } - dbg("\n"); - } - } - if (ifcfg) { - ifcfg->enabled = !disabled; - ifcfg->steer_btm_retry = steer_btm_retry; - ifcfg->steer_btm_retry_secs = steer_btm_retry_secs; - if (legacy) { - /* wait atleast these many secs before - * falling to legacy steering. - */ - ifcfg->fallback_legacy = 1 + - steer_btm_retry * steer_btm_retry_secs + - legacy; - } - ifcfg->steer_legacy_reassoc_secs = steer_legacy_reassoc_secs; - ifcfg->steer_legacy_retry_secs = steer_legacy_retry_secs; - ifcfg->assoc_control_time = assoc_ctrl_secs; - } - } -#if 0 - else if (!strcmp(s->type, "steer")) { - struct uci_element *x, *tmp; - struct uci_option *op; - bool enabled = false; - unsigned int legacy = STEER_LEGACY_FALLBACK_INT; - unsigned int steer_legacy_reassoc_secs = STEER_LEGACY_REASSOC_INT; - unsigned int steer_legacy_retry_secs = STEER_LEGACY_RETRY_INT; - unsigned int steer_btm_retry = STEER_BTM_RETRY; - unsigned int steer_btm_retry_secs = STEER_BTM_RETRY_INT; - struct netif_fhcfg *ifcfg = NULL; - - uci_foreach_element_safe(&s->options, tmp, x) { - op = uci_to_option(x); - if (!strncmp(x->name, "enabled", 7) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: enabled = %d\n", atoi(op->v.string)); - enabled = atoi(op->v.string) == 1 ? - true : false; - } else if (!strncmp(x->name, "btm_retry", 9) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: btm_retry = %d\n", - atoi(op->v.string)); - if (atoi(op->v.string) >= 0) - steer_btm_retry = atoi(op->v.string); - } else if (!strncmp(x->name, "btm_retry_secs", 14) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: btm_retry_secs = %d\n", - atoi(op->v.string)); - if (atoi(op->v.string) >= 0) - steer_btm_retry_secs = atoi(op->v.string); - } else if (!strncmp(x->name, "fallback_legacy", 15) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: legacy = %d\n", - atoi(op->v.string)); - if (atoi(op->v.string) >= 0) - legacy = atoi(op->v.string); - } else if (!strncmp(x->name, "steer_legacy_reassoc_secs", 25) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: steer_legacy_rassoc_secs = %d\n", - atoi(op->v.string)); - steer_legacy_reassoc_secs = atoi(op->v.string); - } else if (!strncmp(x->name, "steer_legacy_retry_secs", 23) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: steer_legacy_retry_secs = %d\n", - atoi(op->v.string)); - steer_legacy_retry_secs = atoi(op->v.string); - } else if (!strncmp(x->name, "ifname", 6) && - op->type == UCI_TYPE_STRING) { - dbg("Steer: ifname = %s\n", op->v.string); - ifcfg = get_netif_fhcfg_by_name(cfg, op->v.string); - if (!ifcfg) { - warn("stale config for '%s'\n", op->v.string); - break; - } - - list_flush(&ifcfg->steer_excludelist, struct stax, list); - list_flush(&ifcfg->steer_btm_excludelist, struct stax, list); - list_flush(&ifcfg->assoc_ctrllist, struct stax, list); - } else if (!strncmp(x->name, "param", 5) && - op->type == UCI_TYPE_LIST) { - struct uci_element *xi; - - dbg("Steer: param: "); - uci_foreach_element(&op->v.list, xi) { - struct steer_policy *p = NULL; - struct steer_rule *r; - - dbg("%s ", xi->name); - p = get_steer_policy_by_name(ifcfg, xi->name); - if (!p) { - dbg("TODO ?"); - continue; - } - p->enabled = enabled; - r = get_steer_rule_by_name(xi->name); - if (r) - r->enabled = enabled; - } - dbg("\n"); - } else if (!strncmp(x->name, "exclude_btm", 11) && - op->type == UCI_TYPE_LIST) { - struct uci_element *xi; - - dbg("Steer: exclude_btm: "); - uci_foreach_element(&op->v.list, xi) { - dbg("%s ", xi->name); - stax_add_entry(&ifcfg->steer_btm_excludelist, xi->name); - } - dbg("\n"); - } else if (!strncmp(x->name, "exclude", 7) && - op->type == UCI_TYPE_LIST) { - struct uci_element *xi; - - dbg("Steer: exclude: "); - uci_foreach_element(&op->v.list, xi) { - dbg("%s ", xi->name); - stax_add_entry(&ifcfg->steer_excludelist, xi->name); - } - dbg("\n"); - } - } - - if (ifcfg) { - ifcfg->enabled = enabled; - ifcfg->steer_btm_retry = steer_btm_retry; - ifcfg->steer_btm_retry_secs = steer_btm_retry_secs; - if (legacy) { - /* wait atleast these many secs before - * falling to legacy steering. - */ - ifcfg->fallback_legacy = 1 + - steer_btm_retry * steer_btm_retry_secs + - legacy; - } - ifcfg->steer_legacy_reassoc_secs = steer_legacy_reassoc_secs; - ifcfg->steer_legacy_retry_secs = steer_legacy_retry_secs; - } - } -#endif - else if (!strcmp(s->type, "steer-param")) { - /* For every steer-param name, find matching rule - * module. If one is available, then the rule module - * takes care of handling the get/set config for this - * parameter specific optins. - */ - struct steer_rule *r; - - dbg("Steer-param: %s\n", s->e.name); - r = get_steer_rule_by_name(s->e.name); - if (r) { - dbg("Rule to handle steer-param '%s' available\n", s->e.name); - r->config(r, cfg, s); - } - } else if (!strncmp(s->type, "wifi-iface", 10)) { - struct uci_element *x; - int mob_id = 500; - - uci_foreach_element(&s->options, x) { - struct uci_option *op; - - op = uci_to_option(x); - if (!strncmp(x->name, "mobility_domain", 7) && - op->type == UCI_TYPE_STRING) - mob_id = atoi(op->v.string); - } - - dbg("wireless: mobility_domain = %d\n", mob_id); - memcpy(cfg->mobility_domain, &mob_id, 2); - dbg("wireless: mobility_domain hex = %02x:%02x\n", - cfg->mobility_domain[0], - cfg->mobility_domain[1]); - - break; - } - } + if (tb[POL_UTIL_TH]) + c->apolicy.util_threshold = atoi(tb[POL_UTIL_TH]->v.string); - uci_unload(ctx, pkg); - uci_free_context(ctx); - return 0; -} + if (tb[POL_RCPI_TH]) + c->apolicy.rcpi_threshold = atoi(tb[POL_RCPI_TH]->v.string); -static void config_update_entry(struct uci_context *ctx, struct uci_package *p, - struct uci_section *s, const char *optname, - int add, void *val, int len) -{ - struct uci_ptr ptr; - - memset(&ptr, 0, sizeof(struct uci_ptr)); - ptr.p = p; - ptr.s = s; - ptr.package = p->e.name; - ptr.section = s->e.name; - ptr.option = optname; - ptr.target = UCI_TYPE_OPTION; - ptr.flags |= UCI_LOOKUP_EXTENDED; - ptr.value = (char *)val; - - if (add) { - dbg("config: add list option: %s\n", (char *)val); - uci_add_list(ctx, &ptr); - } else { - dbg("config: del list option: %s\n", (char *)val); - uci_del_list(ctx, &ptr); + if (tb[POL_RPT_SCAN]) { + c->apolicy.report_scan = + atoi(tb[POL_RPT_SCAN]->v.string) == 1 ? true : false; } - uci_commit(ctx, &p, false); -} -int config_update(const char *confname, struct cntlr_config *cfg, - const char *section, const char *option, - int add, - void *value, int len) -{ - struct uci_context *ctx = NULL; - struct uci_package *pkg = NULL; - struct uci_element *e; + if (tb[POL_RPT_ASSOC_FAILS]) { + c->apolicy.report_sta_assocfails = + atoi(tb[POL_RPT_ASSOC_FAILS]->v.string) == 1 ? + true : false; + } - ctx = uci_alloc_context(); - if (ctx && uci_load(ctx, confname, &pkg) != UCI_OK) { - dbg("config file '%s' not found!\n", confname); - free(ctx); - return -1; + if (tb[POL_RPT_METRIC_PERIODIC]) { + c->apolicy.report_metric_periodic = + atoi(tb[POL_RPT_METRIC_PERIODIC]->v.string); } - uci_foreach_element(&pkg->sections, e) { - struct uci_section *s = uci_to_section(e); - struct uci_element *x, *tmp; - struct uci_option *op; - - if (strcmp(s->type, section)) - continue; - - /* iter through matched 'section' for the 'option' */ - uci_foreach_element_safe(&s->options, tmp, x) { - if (strcmp(x->name, option)) - continue; - - op = uci_to_option(x); - if (op->type == UCI_TYPE_LIST) { - uci_foreach_element(&op->v.list, x) { - if (!strncmp(x->name, value, len)) { - if (!add) - config_update_entry(ctx, - pkg, s, option, 0, value, len); - - goto out_exit; - } - } - /* add new exclude at end of list */ - if (add) - config_update_entry(ctx, pkg, s, option, 1, value, len); - - goto out_exit; - } - } - /* 'option' name not present in 'section' - * Create a new one at end of 'section'. - */ - if (add) - config_update_entry(ctx, pkg, s, option, 1, value, len); + if (tb[POL_RPT_RCPI_TH]) { + c->apolicy.report_rcpi_threshold = + atoi(tb[POL_RPT_RCPI_TH]->v.string); + } - goto out_exit; + if (tb[POL_RPT_UTIL_TH]) { + c->apolicy.report_util_threshold = + atoi(tb[POL_RPT_UTIL_TH]->v.string); } -out_exit: - uci_free_context(ctx); - return 0; -} -int config_update2(const char *confname, struct cntlr_config *cfg, - const char *section_type, - const char *match_option, - const char *match_option_value, - const char *option, - int add, - void *value, int len) -{ - struct uci_context *ctx = NULL; - struct uci_package *pkg = NULL; - struct uci_element *e; + if (tb[POL_INC_STA_STATS]) { + c->apolicy.include_sta_stats = + atoi(tb[POL_INC_STA_STATS]->v.string) == 1 ? + true : false; + } - ctx = uci_alloc_context(); - if (ctx && uci_load(ctx, confname, &pkg) != UCI_OK) { - dbg("config file '%s' not found!\n", confname); - free(ctx); - return -1; + if (tb[POL_INC_STA_METRIC]) { + c->apolicy.include_sta_metric = + atoi(tb[POL_INC_STA_METRIC]->v.string) == 1 ? + true : false; } - uci_foreach_element(&pkg->sections, e) { - struct uci_section *s = uci_to_section(e); - struct uci_element *x, *tmp; - struct uci_option *op; - const char *optstring; + if (tb[POL_PVID]) + c->apolicy.pvid = atoi(tb[POL_PVID]->v.string); - if (strcmp(s->type, section_type)) - continue; + if (tb[POL_PCP_DEFAULT]) + c->apolicy.pcp_default = atoi(tb[POL_PCP_DEFAULT]->v.string); - if (match_option && match_option_value) { - optstring = uci_lookup_option_string(ctx, s, match_option); - if (!optstring || strcmp(optstring, match_option_value)) - continue; - } - /* iter through matched 'section' for the 'option' */ - uci_foreach_element_safe(&s->options, tmp, x) { - if (strcmp(x->name, option)) - continue; - - op = uci_to_option(x); - if (op->type == UCI_TYPE_LIST) { - uci_foreach_element(&op->v.list, x) { - if (!strncmp(x->name, value, len)) { - if (!add) { - config_update_entry(ctx, - pkg, s, option, - 0, value, len); - } - - goto out_exit; - } - } - /* add new 'option' at end of list */ - if (add) { - config_update_entry(ctx, pkg, s, option, - 1, value, len); - } - - goto out_exit; - } - } - /* 'option' name not present in 'section' - * Create a new one at end of 'section'. - */ - if (add) - config_update_entry(ctx, pkg, s, option, - 1, value, len); - - goto out_exit; + if (tb[POL_DISALLOW_BSTA_P1]) { + c->apolicy.disallow_bsta_p1 = + atoi(tb[POL_DISALLOW_BSTA_P1]->v.string) == 1 ? + true : false; } -out_exit: - uci_free_context(ctx); - return 0; -} + if (tb[POL_DISALLOW_BSTA_P2]) { + c->apolicy.disallow_bsta_p2 = + atoi(tb[POL_DISALLOW_BSTA_P2]->v.string) == 1 ? + true : false; + } -#if 0 -struct config uci_config = { - .name = "uci", - .priv = uci_ctx; - .get = uci_get_config, - .set = uci_set_config, - .init = uci_setup, - .exit = uci_exit, -}; -#define priv_get_config(priv) container_of(priv, struct config, priv) + return 0; +} -void register_config(struct config *c) +int cntlr_config_reload(struct controller_config *cfg) { - static struct uci_context *ctx; - static struct uci_package *pkg; + struct uci_context *ctx; + struct uci_package *pkg; struct uci_element *e; - int ret = 0; - - if (uci_ctx) - return priv_get_config(uci_ctx); ctx = uci_alloc_context(); - if (ctx) { - uci_ctx = ctx; - memcpy(c, &uci_config, sizeof(*cfg)); - } - if (uci_load(ctx, "wificntlr", &pkg)) + if (!ctx) return -1; + if (uci_load(ctx, "controller", &pkg)) { + uci_free_context(ctx); + return -1; + } + uci_foreach_element(&pkg->sections, e) { struct uci_section *s = uci_to_section(e); - const char *option_val; - - if (strcmp(s->type, "wificntlr")) - continue; - option_val = uci_lookup_option_string(ctx, s, name); - if (option_val) - sprintf(val, "%s", option_val); - else - ret = -1; + if (!strcmp(s->type, "wificntlr")) { + cntlr_config_get_base(cfg, s); + } else if (!strcmp(s->type, "fh-credentials") || + !strcmp(s->type, "bk-credentials")) { + cntlr_config_get_credentials(cfg, s); + } else if (!strcmp(s->type, "agent-policy")) { + cntlr_config_get_agent_policy(cfg, s); + } } - uci_free_context(ctx); - return ret; + uci_free_context(ctx); + return 0; } -#endif diff --git a/src/core/config.h b/src/core/config.h index e9c6a9b93c330adc88143f3bc51c2dc0944a9af9..d8270878f362057d76358755595e91a9ff02f974 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -11,6 +11,7 @@ #define CONFIG_H +// TODO: use wifi.h definitions?? enum wifi_band { WIFI_BAND_NONE, WIFI_BAND_2 = 1 << 0, /**< 0x1 for 2.4Ghz band. */ @@ -19,13 +20,28 @@ enum wifi_band { WIFI_BAND_6 = 1 << 3, /**< 0x8 for 6Ghz */ }; +// TODO: use wifi.h definitions?? +enum wifi_security { + WIFI_SECURITY_NONE, + WIFI_SECURITY_WEP64, + WIFI_SECURITY_WEP128, + WIFI_SECURITY_WPAPSK, + WIFI_SECURITY_WPA2PSK, + WIFI_SECURITY_WPA3PSK, + WIFI_SECURITY_WPA3PSK_T, + WIFI_SECURITY_WPA, + WIFI_SECURITY_WPA2, + WIFI_SECURITY_WPA3, +}; + + struct iface_credential { - uint8_t band; + enum wifi_band band; + enum wifi_security sec; + uint8_t key[64]; uint8_t bssid[6]; uint8_t ssid[33]; - char encryption[64]; - uint8_t key[64]; - uint16_t vlan_id; + uint16_t vlanid; }; enum agent_steer_policy { @@ -35,7 +51,7 @@ enum agent_steer_policy { }; struct agent_policy { - uint8_t alid[6]; /* ieee1905 AL macaddress */ + uint8_t id[6]; /* ieee1905 AL macaddress */ enum agent_steer_policy policy; /* 0, 1, 2 - see MultiAP specs */ uint8_t util_threshold; /* utilization as in BSS load IE */ uint8_t rcpi_threshold; /* 0 - 220 */ @@ -52,35 +68,29 @@ struct agent_policy { bool disallow_bsta_p2; /* disallow profile2 bSTA link */ struct list_head list; /* link to next policy */ + + /* custom policies follow */ + struct list_head steer_exlist; /* exclude stas from steering */ + struct list_head btmsteer_exlist; /* exclude stas from BTM steering */ }; struct controller_config { bool enabled; - uint8_t wps_supp_bands; /* WPS registrar supported bands */ - - struct iface_credential fh5; - struct iface_credential fh2; - - struct iface_credential bk5; - struct iface_credential bk2; - - struct list_head policylist; /* list of struct agent_policy */ + bool has_registrar_5g; + bool has_registrar_2g; + int num_fh; + int num_bk; + struct iface_credential fh[2]; + struct iface_credential bk[2]; + struct agent_policy apolicy; + + struct list_head policylist; /* custom list of agent_policy */ }; struct controller; -int cntlr_config_reload(const char *confname, struct controller_config *cfg); +int cntlr_config_reload(struct controller_config *cfg); int cntlr_config_defaults(struct controller *c, struct controller_config *cfg); void cntlr_config_dump(struct controller_config *cfg); -int config_update(const char *confname, struct controller_config *cfg, - const char *section, const char *option, int add, - void *value, int len); - - -int config_update2(const char *confname, struct controller_config *cfg, - const char *section_type, - const char *match_option, const char *match_option_value, - const char *option, int add, void *value, int len); - #endif diff --git a/src/utils/utils.h b/src/utils/utils.h index 6b00df0f734eecd8dba6463f76019660f8d97dca..465032f3b6d109489149d96a404048d7cd9f827b 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -20,6 +20,14 @@ #define hwaddr_hash(a) (a[0] ^ a[1] ^ a[2] ^ a[3] ^ a[4] ^ a[5]) +#ifndef MACFMT +#define MACFMT "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + +#ifndef MAC2STR +#define MAC2STR(_m) (_m)[0], (_m)[1], (_m)[2], (_m)[3], (_m)[4], (_m)[5] +#endif + bool match_oui0(unsigned char *oui, unsigned char *hwaddr, int ouis); unsigned char *hwaddr_aton(const char *macstr, unsigned char *mac);