Newer
Older
/*
* config.c - controller configuration handling
*
* Copyright (C) 2020 IOPSYS Software Solutions AB. All rights reserved.
*
* Author: anjan.chanda@iopsys.eu
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <json-c/json.h>
#include <libubox/blobmsg.h>
#include <libubox/blobmsg_json.h>
#include <libubox/uloop.h>
#include <libubox/ustream.h>
#include <libubox/utils.h>
#include <libubus.h>
#include <uci.h>
#include <easy/easy.h> // TODO: remove wifi.h
#include <wifi.h> // TODO: remove wifi.h
#include "debug.h"
#include "utils.h"
#include "config.h"
#include "comm.h"
#include "msgqueue.h"
#include "worker.h"
#include "cntlr.h"
void cntlr_config_dump(struct controller_config *c)
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);
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);
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");
int cntlr_config_defaults(struct controller *cntlr, struct controller_config *c)
memset(c, 0, sizeof(*c));
INIT_LIST_HEAD(&c->policylist);
static int cntlr_config_get_base(struct controller_config *c,
struct uci_section *s)
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 },
{ .name = "debug", .type = UCI_TYPE_STRING },
};
struct uci_option *tb[NUM_CNTLR_ATTRS];
uci_parse_section(s, opts, NUM_CNTLR_ATTRS, tb);
if (tb[CNTLR_ENABLED]) {
const char *val = tb[CNTLR_ENABLED]->v.string;
if (tb[CNTLR_REGISTRAR]) {
const char *val = tb[CNTLR_REGISTRAR]->v.string;
c->has_registrar_5g = !strstr(val, "5") ? false : true;
c->has_registrar_2g = !strstr(val, "2") ? false : true;
if (tb[CNTLR_ENABLED]) {
const char *debug = tb[CNTLR_DEBUG]->v.string;
c->debug_level = atoi(debug);
}
static int cntlr_config_get_credentials(struct controller_config *c,
struct uci_section *s)
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
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;
if (tb[CRED_BAND]) {
if (atoi(tb[CRED_BAND]->v.string) == 5)
cred->band = BAND_5;
cred->band = BAND_2;
if (tb[CRED_SSID])
memcpy(cred->ssid, tb[CRED_SSID]->v.string, 32);
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)
}
if (tb[CRED_KEY])
memcpy(cred->key, tb[CRED_KEY]->v.string, 63);
if (tb[CRED_VLAN])
cred->vlanid = atoi(tb[CRED_VLAN]->v.string);
static int cntlr_config_get_agent_policy(struct controller_config *c,
struct uci_section *s)
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
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);
if (tb[POL_STEER])
c->apolicy.policy = atoi(tb[POL_STEER]->v.string);
if (tb[POL_UTIL_TH])
c->apolicy.util_threshold = atoi(tb[POL_UTIL_TH]->v.string);
if (tb[POL_RCPI_TH])
c->apolicy.rcpi_threshold = atoi(tb[POL_RCPI_TH]->v.string);
if (tb[POL_RPT_SCAN]) {
c->apolicy.report_scan =
atoi(tb[POL_RPT_SCAN]->v.string) == 1 ? true : false;
if (tb[POL_RPT_ASSOC_FAILS]) {
c->apolicy.report_sta_assocfails =
atoi(tb[POL_RPT_ASSOC_FAILS]->v.string) == 1 ?
true : false;
}
if (tb[POL_RPT_METRIC_PERIODIC]) {
c->apolicy.report_metric_periodic =
atoi(tb[POL_RPT_METRIC_PERIODIC]->v.string);
if (tb[POL_RPT_RCPI_TH]) {
c->apolicy.report_rcpi_threshold =
atoi(tb[POL_RPT_RCPI_TH]->v.string);
}
if (tb[POL_RPT_UTIL_TH]) {
c->apolicy.report_util_threshold =
atoi(tb[POL_RPT_UTIL_TH]->v.string);
if (tb[POL_INC_STA_STATS]) {
c->apolicy.include_sta_stats =
atoi(tb[POL_INC_STA_STATS]->v.string) == 1 ?
true : false;
}
if (tb[POL_INC_STA_METRIC]) {
c->apolicy.include_sta_metric =
atoi(tb[POL_INC_STA_METRIC]->v.string) == 1 ?
true : false;
if (tb[POL_PVID])
c->apolicy.pvid = atoi(tb[POL_PVID]->v.string);
if (tb[POL_PCP_DEFAULT])
c->apolicy.pcp_default = atoi(tb[POL_PCP_DEFAULT]->v.string);
if (tb[POL_DISALLOW_BSTA_P1]) {
c->apolicy.disallow_bsta_p1 =
atoi(tb[POL_DISALLOW_BSTA_P1]->v.string) == 1 ?
true : false;
if (tb[POL_DISALLOW_BSTA_P2]) {
c->apolicy.disallow_bsta_p2 =
atoi(tb[POL_DISALLOW_BSTA_P2]->v.string) == 1 ?
true : false;
}
int cntlr_config_reload(struct controller_config *cfg)
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_element *e;
ctx = uci_alloc_context();
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);
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);
}