diff --git a/gitlab-ci/install-dependencies.sh b/gitlab-ci/install-dependencies.sh index eaf28997e2cae200e021364fe6a82ee05fcc649d..526ab0bf344a989a2075ff8942f7b0c748a7609a 100755 --- a/gitlab-ci/install-dependencies.sh +++ b/gitlab-ci/install-dependencies.sh @@ -160,5 +160,104 @@ config rule-custom echo " config wificntlr option enabled '1' + option registrar '5 2' #bands on which wps registrar supported option debug '6' + +config fh-credentials 'map-net55' + option band '5' + option encryption 'psk2' + option key '1234567890' + option ssid 'map-net5' + option vlan '101' + option multi_ap '128' # TODO: should mode 1/2/3 be added? + +config fh-credentials 'map-net55' + option band '5' + option encryption 'psk2' + option key '1234567890' + option ssid 'map-net55' + option vlan '0' # 0 - 2 rsvd, 3 - 4094 => vlan id + +config bk-credentials + option band '5' + option encryption 'psk2' + option key '5555555555' + option ssid 'map-bkhaul-5' + +config bk-credentials + option band '2' + option encryption 'psk2' + option key '2222222222' + option ssid 'map-bkhaul-2' + +config agent-policy + option agent_id '00:22:07:7E:9C:D6' # 1905al macaddress of agent + list steer_exclude '00:11:22:33:44:55' + list steer_exclude_btm '00:aa:bb:cc:dd:ee' + option steer_policy '2' # 0, 1, 2 - see MultiAP spec + option util_threshold '200' # channel-util as in BSS load + option rcpi_threshold '30' # 0 - 220 valid range + option report_scan '0' # 0 or 1 for independent sc include_sta_metric '0' # sta metric in AP metric resp + option pvid '100' # primary vlan id + option pcp_default '5' # default vlan pcp + option disallow_bsta_p1 '0' # 0 or 1 profile20 valid range + option report_scan '0' # 0 or 1 for independent scans + option report_sta_assocfails '1' # 0 or 1 - stas assoc failure + option report_metric_periodic '0' # 0, or 1 - 255 in secs + option report_rcpi_threshold '30' # 0 - 220 valid range + option report_scan '0' # 0 or 1 for independent scans + option report_sta_assocfails '1' # 0 or 1 - stas assoc failure + option report_metric_periodic '0' # 0, or 1 - 255 in secs + option report_rcpi_threshold '0' # 0, or 1 - 220 + option report_util_threshold '0' # 0, or channel-util value + option include_sta_stats '0' # sta stats in AP metric resp + option include_sta_metric '0' # sta metric in AP metric resp + option pvid '100' # primary vlan id + option pcp_default '5' # default vlan pcp + option disallow_bsta_p1 '0' # 0 or 1 profile-1 bSTA + option disallow_bsta_p2 '0' # 0 or 1 profile-2 bSTA + +config agent-policy + option agent_id '00:00:00:00:00:00' + list steer_exclude '00:11:22:33:44:55' + list steer_exclude_btm '00:aa:bb:cc:dd:ee' + option steer_policy '2' # 0, 1, 2 - see MultiAP spec + option util_threshold '200' # channel-util as in BSS load + option rcpi_threshold '30' # 0 - 220 valid range + option report_scan '0' # 0 or 1 for independent sc include_sta_metric '0' # sta metric in AP metric resp + option pvid '100' # primary vlan id + option pcp_default '5' # default vlan pcp + option disallow_bsta_p1 '0' # 0 or 1 profile20 valid range + option report_scan '0' # 0 or 1 for independent scans + option report_sta_assocfails '1' # 0 or 1 - stas assoc failure + option report_metric_periodic '0' # 0, or 1 - 255 in secs + option report_rcpi_threshold '30' # 0 - 220 valid range + option report_scan '0' # 0 or 1 for independent scans + option report_sta_assocfails '1' # 0 or 1 - stas assoc failure + option report_metric_periodic '0' # 0, or 1 - 255 in secs + option report_rcpi_threshold '0' # 0, or 1 - 220 + option report_util_threshold '0' # 0, or channel-util value + option include_sta_stats '0' # sta stats in AP metric resp + option include_sta_metric '0' # sta metric in AP metric resp + option pvid '100' # primary vlan id + option pcp_default '5' # default vlan pcp + option disallow_bsta_p1 '0' # 0 or 1 profile-1 bSTA + option disallow_bsta_p2 '0' # 0 or 1 profile-2 bSTA + +config agent-policy + option agent_id '00:22:07:6A:1C:3A' # 1905al macaddress of agent + list steer_exclude '00:11:22:33:44:55' + list steer_exclude_btm '00:aa:bb:cc:dd:ee' + option steer_policy '2' # 0, 1, 2 - see MultiAP spec + option util_threshold '200' # channel-util as in BSS load + option report_metric_periodic '0' # 0, or 1 - 255 in secs + option report_rcpi_threshold '0' # 0, or 1 - 220 + option report_util_threshold '0' # 0, or channel-util value + option include_sta_stats '0' # sta stats in 3:4d:35:d2' + option bss '00:22:07:11:22:33' + +config rule-custom + option action restrict + option sta 'd8:32:e3:4d:35:d2' + option bss '00:22:07:11:22:33' " > /etc/config/controller diff --git a/src/Makefile b/src/Makefile index 8f6ca42b2390fea7542ed9d9834bf228ef663774..9daac83e83af9a1b91c817a547b32eeebbd4bfb5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,6 +20,7 @@ CNTLR_OBJS = \ core/cntlr_ubus.o \ core/cntlr.o \ core/cntlr_map.o \ + core/cntlr_tlv_generator.o \ core/cntlr_map_debug.o \ core/config.o \ core/main.o @@ -27,6 +28,7 @@ CNTLR_OBJS = \ LIBS = -lubus -lubox -ljson-c -lblobmsg_json -luci -pthread LIBS += -rdynamic -ldl LIBS += -lmaputils +LIBS += -lwsc plugin_subdirs ?= $(wildcard plugins/*) plugin_sofile = $(wildcard $(d)/*.so) diff --git a/src/controller.conf b/src/controller.conf index 452caf3e5219f738916659df50215f0b6a0bffc7..1cb46cfb8c0af03c1d6c4ab8e82b9d0277652059 100644 --- a/src/controller.conf +++ b/src/controller.conf @@ -22,12 +22,22 @@ config bk-credentials option encryption 'psk2' option key '5555555555' option ssid 'map-bkhaul-5' + option multi_ap '2' +# option multi_ap_backhaul_sta '1' # possible future TODO +# option multi_ap_backhaul_key 'multiap_key123' # possible future TODO +# option multi_ap_backhaul_ssid 'MultiAP-0022077E9CD6' # possible future TODO + option disallow_bsta '1' # bitmap, 1 for disallow p1, 2 to disallow p2, 3 to disallow both (probably never applicable) config bk-credentials option band '2' option encryption 'psk2' option key '2222222222' option ssid 'map-bkhaul-2' + option multi_ap '2' +# option multi_ap_backhaul_sta '1' # possible future TODO +# option multi_ap_backhaul_key 'multiap_key123' # possible future TODO +# option multi_ap_backhaul_ssid 'MultiAP-0022077E9CD6' # possible future TODO + option disallow_bsta '0' # 0 or 1 profile-1 bSTA config agent-policy option agent_id '02:20:40:55:66:77' # 1905al macaddress of agent @@ -48,7 +58,6 @@ config agent-policy option disallow_bsta_p1 '0' # 0 or 1 profile-1 bSTA option disallow_bsta_p2 '0' # 0 or 1 profile-2 bSTA - config agent-policy option agent_id '02:20:40:aa:bb:cc' # 1905al macaddress of agent list steer_exclude '00:11:22:33:44:55' @@ -68,7 +77,6 @@ config agent-policy option disallow_bsta_p1 '0' # 0 or 1 profile-1 bSTA option disallow_bsta_p2 '0' # 0 or 1 profile-2 bSTA - ### do not parse following now ### config steer-param 'rssi' option rssi_threshold '-68' diff --git a/src/core/cntlr.c b/src/core/cntlr.c index 73a32fa39db245834591dfa57daed78fb5d8261b..890c547b1e42c2fca97d858da945f4882b98b6e2 100644 --- a/src/core/cntlr.c +++ b/src/core/cntlr.c @@ -29,6 +29,9 @@ #include <easy/easy.h> #include <wifi.h> // FIXME: should not be included +#include <map1905/map2.h> +#include <map1905/maputils.h> + #include "debug.h" #include "utils.h" #include "config.h" @@ -44,6 +47,36 @@ static int update_fronthaul_bsslist(struct node *n, struct netif_fhbss *fh); static void node_getbssinfo(void *cntlr, void *resp, int len, void *cookie); static int enumerate_topology_indirect(struct controller *c); +void stop_cntlr(struct controller *c) +{ + + if (!c) { + warn("%s: (cntlr = NULL)\n", __func__); + exit(0); + } + + stop_test_logging(); + ubus_unregister_event_handler(c->ubus_ctx, &c->ieee1905_evh); + ubus_unregister_event_handler(c->ubus_ctx, &c->ubusx_ev); + cntlr_remove_object(c); + uloop_done(); + cntlr_config_clean(&c->cfg); + comm_destroy(c->comm); + ubus_free(c->ubus_ctx); + free(c); +} + +static void cntlr_terminate(struct controller *c) +{ + dbg("%s: called.\n", __func__); + stop_cntlr(c); + exit_alloctrace(); + stop_logging(); + //unlink(pidfile); + exit(0); +} + + /* find node by macaddress */ static struct node *find_node_by_mac(struct controller *c, const unsigned char *mac) @@ -1977,6 +2010,7 @@ int start_controller(void) as_init_table(&c->as_table); ubus_add_uloop(ctx); + cntlr_config_defaults(c, &c->cfg); cntlr_config_reload(&c->cfg); c->topology = ubus_get_topology_object(c->ubus_ctx); @@ -2008,13 +2042,11 @@ int start_controller(void) cntlr_register_module(c); uloop_run(); - out_exit: /* ubus_unregister_event_handler(ctx, ev); */ /* cntlr_remove_object(ctx); */ - ubus_free(ctx); uloop_done(); - free(c); + cntlr_terminate(c); return 0; } diff --git a/src/core/cntlr.h b/src/core/cntlr.h index 734b564f0f91f8faed1c46ce26a4ae97d26f4d91..a66bd2f97bf8f7962ab0ee79b1082784f8acbbdb 100644 --- a/src/core/cntlr.h +++ b/src/core/cntlr.h @@ -49,6 +49,14 @@ struct netif_link { struct list_head list; }; +/* TODO - fill this structure */ +struct netif_radio { + char name[16]; + unsigned char hwaddr[6]; + bool isup; + struct list_head list; +}; + enum nodetype { NODE_WIFI_EXTENDER, NODE_WIFI_REPEATER, @@ -121,6 +129,7 @@ struct controller { object_t topology; int num_nodes; struct list_head nodelist; + struct list_head radiolist; /** TODOTODO -- list of radios */ struct list_head watchlist; struct uloop_timeout radar_timer; struct hlist_head *as_table; /** active sta hash table */ diff --git a/src/core/cntlr_map.c b/src/core/cntlr_map.c index 75fa1c7482dd917e532965f03eb8cdf06b7610cd..d753e5cce4ebb053abd9c736574899fb9b80dece 100644 --- a/src/core/cntlr_map.c +++ b/src/core/cntlr_map.c @@ -30,6 +30,10 @@ #include <easy/easy.h> #include <wifi.h> // TODO: remove wifi.h +#include <map1905/map2.h> +#include <map1905/maputils.h> +#include <ieee1905/1905_tlvs.h> + #include "map_module.h" #include "utils.h" #include "debug.h" @@ -39,12 +43,10 @@ #include "msgqueue.h" #include "worker.h" #include "cntlr.h" - -#include <map1905/map2.h> -#include <map1905/maputils.h> +#include "cntlr_ubus.h" #include "cntlr_map_debug.h" - +#include "cntlr_tlv_generator.h" #define for_each_tlv(e, _buf, _len) \ for ((e) = (struct tlv *)(_buf); \ @@ -77,10 +79,58 @@ int handle_topology_response(void *cntlr, struct cmdu_cstruct *cmdu) return 0; } -int handle_ap_autoconfig_search(void *cntlr, struct cmdu_cstruct *cmdu) +/* TODO: error handling */ +int handle_ap_autoconfig_search(void *cntlr, struct cmdu_cstruct *rec_cmdu) { trace("%s: --->\n", __func__); - return 0; + struct controller *c = (struct controller *) cntlr; + uint16_t tlv_index = 0; + struct cmdu_cstruct *cmdu; + struct tlv_map_profile *p; + struct tlv_supp_service *p1; + int ret; + + cmdu = (struct cmdu_cstruct *)calloc(1, + sizeof(struct cmdu_cstruct)); + if (!cmdu) { + fprintf(stderr, "Out of memory!\n"); + return -1; + } + + cmdu->message_type = CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE; + memcpy(cmdu->origin, rec_cmdu->origin, 6); + cmdu->message_id = cmdu->message_id; + strncpy(cmdu->intf_name, rec_cmdu->intf_name, + sizeof(cmdu->intf_name) - 1); + + p = cntlr_gen_map_profile(c, cmdu); + if (!p) + goto fail_cmdu; + cmdu->num_tlvs++; + + p1 = cntlr_gen_supp_service(c, cmdu); + if (!p1) + goto fail_p; + cmdu->num_tlvs++; + + cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs, sizeof(uint8_t *)); + if (!cmdu->tlvs) + goto fail_p1; + + cmdu->tlvs[tlv_index++] = (uint8_t *)p; + cmdu->tlvs[tlv_index++] = (uint8_t *)p1; + + ret = send_cmdu(c, cmdu); + map_free_cmdu(cmdu); + + return ret; +fail_p1: + map_free_tlv_cstruct((uint8_t *) p1); +fail_p: + map_free_tlv_cstruct((uint8_t *) p); +fail_cmdu: + free(cmdu); + return -1; } int handle_ap_autoconfig_response(void *cntlr, struct cmdu_cstruct *cmdu) @@ -89,10 +139,108 @@ int handle_ap_autoconfig_response(void *cntlr, struct cmdu_cstruct *cmdu) return 0; } -int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_cstruct *cmdu) +int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_cstruct *rec_cmdu) { trace("%s: --->\n", __func__); - return 0; + struct controller *c = (struct controller *) cntlr; + struct tlv_default_8021q_settings *p; + struct tlv_traffic_sep_policy *p1; + struct tlv_ap_radio_identifier *p2; + struct tlv_wsc *p3; + struct cmdu_cstruct *cmdu; + int tlv_index = 0, ret, i; + uint8_t **tlvs; + + cmdu = (struct cmdu_cstruct *)calloc(1, sizeof(struct cmdu_cstruct)); + if (!cmdu) { + fprintf(stderr, "failed to malloc cmdu\n"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + memcpy(cmdu->origin, rec_cmdu->origin, 6); + cmdu->message_type = CMDU_TYPE_AP_AUTOCONFIGURATION_WSC; + cmdu->message_id = rec_cmdu->message_id; + strncpy(cmdu->intf_name, rec_cmdu->intf_name, + sizeof(cmdu->intf_name) - 1); + + p = cntlr_gen_8021q_settings(c, cmdu, rec_cmdu); + if (!p) + goto fail_cmdu; + cmdu->num_tlvs++; + + p1 = cntlr_gen_traffic_sep_policy(c, cmdu); + if (!p1) + goto fail_p; + cmdu->num_tlvs++; + + p2 = cntlr_gen_radio_identifier(c, cmdu, rec_cmdu); + if (!p2) + goto fail_p1; + cmdu->num_tlvs++; + + cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs, sizeof(uint8_t *)); + if (!cmdu->tlvs) + goto fail_p2; + + cmdu->tlvs[tlv_index++] = (uint8_t *)p; + cmdu->tlvs[tlv_index++] = (uint8_t *)p1; + cmdu->tlvs[tlv_index++] = (uint8_t *)p2; + + /* Generate all fBSS wsc tlvs for this BSS */ + for (i = 0; i < c->cfg.num_fh; i++) { + /* Will return null if band did not match OR on failure*/ + p3 = cntlr_gen_wsc(c, cmdu, rec_cmdu, &c->cfg.fh[i]); + if (!p3) + continue; + cmdu->num_tlvs++; + + tlvs = (uint8_t **)realloc(cmdu->tlvs, cmdu->num_tlvs * sizeof(uint8_t *)); + if (!tlvs) { + cmdu->num_tlvs--; + map_free_tlv_cstruct((uint8_t *) p3); + continue; + } + + cmdu->tlvs = tlvs; + cmdu->tlvs[tlv_index++] = (uint8_t *)p3; + } + + /* Generate all bBSS wsc tlvs for this BSS */ + for (i = 0; i < c->cfg.num_bk; i++) { + /* Will return null if band did not match OR on failure*/ + p3 = cntlr_gen_wsc(c, cmdu, rec_cmdu, &c->cfg.bk[i]); + if (!p3) + continue; + cmdu->num_tlvs++; + + tlvs = (uint8_t **)realloc(cmdu->tlvs, cmdu->num_tlvs * sizeof(uint8_t *)); + if (!tlvs) { + cmdu->num_tlvs--; + map_free_tlv_cstruct((uint8_t *) p3); + continue; + } + + cmdu->tlvs = tlvs; + cmdu->tlvs[tlv_index++] = (uint8_t *)p3; + } + + if (cmdu->num_tlvs < 4) + goto fail_tlvs; + + ret = send_cmdu(c, cmdu); + map_free_cmdu(cmdu); + return ret; +fail_tlvs: + free(cmdu->tlvs); +fail_p2: + map_free_tlv_cstruct((uint8_t *) p2); +fail_p1: + map_free_tlv_cstruct((uint8_t *) p1); +fail_p: + map_free_tlv_cstruct((uint8_t *) p); +fail_cmdu: + free(cmdu); + return -1; } @@ -347,7 +495,7 @@ bool is_cmdu_for_us(void *module, uint16_t type) } int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid, - char *rxif, uint8_t *src, uint8_t *tlvs, int len) + char *rxif, uint8_t *src, uint8_t *tlvs, int len) { struct controller *c = (struct controller *)module; const struct map_cmdu_calltable_t *f; @@ -379,7 +527,6 @@ int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid, if (verbose >= 4 && f[idx].debug) f[idx].debug(c, cmdu); - map_free_cmdu(cmdu); //TODO: check ret diff --git a/src/core/cntlr_map_debug.c b/src/core/cntlr_map_debug.c index 4d2f580af687539b949072f8ebfc751a0efc0328..919586fe9d1c2d034f7f035cd3e52ba3aed1f074 100644 --- a/src/core/cntlr_map_debug.c +++ b/src/core/cntlr_map_debug.c @@ -356,15 +356,22 @@ int debug_sta_caps_report(void *cntlr, struct cmdu_cstruct *cmdu) char *frame; int offset = 1 + 2 + 1; + trace("\tresult_code: 0x%02x\n", p->result_code); + + /* if tlv is shorter or equal to the offset len, + * then no frame is passed + */ + if (p->tlv_len <= offset) + break; + frame = calloc(1, (2 * (p->tlv_len - offset)) + 1); if (!frame) - continue; + break; btostr(p->frame_body + offset, p->tlv_len - offset, frame); - trace("\tresult_code: 0x%02x\n", p->result_code); trace("\tframe: 0x%s\n", frame); break; } diff --git a/src/core/cntlr_tlv_generator.c b/src/core/cntlr_tlv_generator.c new file mode 100644 index 0000000000000000000000000000000000000000..7d6cfab0e79f0ee835e0a2296c3ef3da6e7ca9d8 --- /dev/null +++ b/src/core/cntlr_tlv_generator.c @@ -0,0 +1,263 @@ +/* + * cntlr_tlv_generator.c - tlv building function + * + * Copyright (C) 2020 IOPSYS Software Solutions AB. All rights reserved. + * + * Author: jakob.olsson@iopsys.eu + * + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include <arpa/inet.h> +#include <sys/ioctl.h> +#include <net/if_arp.h> +#include <pthread.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 <easy/easy.h> +#include <wifi.h> // TODO: remove wifi.h + +#include <map1905/map2.h> +#include <map1905/maputils.h> +#include <wsc.h> + +#include "map_module.h" +#include "utils.h" +#include "debug.h" +#include "config.h" +#include "cntlr.h" +#include "cntlr_ubus.h" + +#include "cntlr_map_debug.h" +#include "cntlr_tlv_generator.h" + +uint8_t *extract_tlv_by_type(struct cmdu_cstruct *cmdu, uint8_t tlv_type) +{ + uint8_t *tlv; + int i; + + for (i = 0; i < cmdu->num_tlvs; i++) { + tlv = cmdu->tlvs[i]; + if (*tlv == tlv_type) + return tlv; + } + + return NULL; + +} + +struct tlv_default_8021q_settings *cntlr_gen_8021q_settings(struct controller *c, + struct cmdu_cstruct *cmdu, struct cmdu_cstruct *rec_cmdu) +{ + struct tlv_default_8021q_settings *p; + struct agent_policy *a, *found = NULL; + + list_for_each_entry(a, &c->cfg.policylist, list) { + if (!memcmp(rec_cmdu->origin, a->agent_id, 6)) { + found = a; + break; + } + } + + if (!found) + return NULL; + + p = (struct tlv_default_8021q_settings *) calloc(1, sizeof(*p)); + if (!p) + return NULL; + + p->tlv_type = MAP_TLV_DEFAULT_8021Q_SETTINGS; + p->primary_vid = a->pvid; + p->pcp = a->pcp_default; + + return p; +} + +struct tlv_traffic_sep_policy *cntlr_gen_traffic_sep_policy(struct controller *c, + struct cmdu_cstruct *cmdu) +{ + struct tlv_traffic_sep_policy *p; + int i; + + p = (struct tlv_traffic_sep_policy *) calloc(1, sizeof(*p)); + if (!p) + return NULL; + + p->tlv_type = MAP_TLV_TRAFFIC_SEPARATION_POLICY; + p->nbr_ssid = c->cfg.num_fh; + p->data = calloc(p->nbr_ssid, sizeof(*(p->data))); + if (!p->data) { + map_free_tlv_cstruct((uint8_t *) p); + return NULL; + } + + for (i = 0; i < p->nbr_ssid; i++) { + int len; + + len = strlen((char *)c->cfg.fh[i].ssid); + + p->data[i].ssid_len = len; + p->data[i].vid = c->cfg.fh[i].vlanid; + p->data[i].ssid = calloc(1, len + 1); + if (!p->data[i].ssid) + continue; + + strncpy(p->data[i].ssid, (char *)c->cfg.fh[i].ssid, len); + } + + return p; +} + +struct tlv_wsc *cntlr_gen_wsc(struct controller *c, + struct cmdu_cstruct *cmdu, struct cmdu_cstruct *rec_cmdu, + struct iface_credential *creds) +{ + struct tlv_ap_radio_basic_cap *ap_caps = NULL; + struct tlv_wsc *m2, *m1; + enum wifi_band band = BAND_UNKNOWN; + struct mdata cfg = {0}; + int i, rv; + + ap_caps = (struct tlv_ap_radio_basic_cap *) extract_tlv_by_type(rec_cmdu, + MAP_TLV_AP_RADIO_BASIC_CAPABILITIES); + if (!ap_caps) + return NULL; + + m1 = (struct tlv_wsc *) extract_tlv_by_type(rec_cmdu, + TLV_TYPE_WSC); + if (!m1) + return NULL; + + /* determine radio frequency */ + for (i = 0; i < ap_caps->operating_classes_nr; i++) { + if (ap_caps->operating_class[i].op_class >= 81 && + ap_caps->operating_class[i].op_class <= 84) + band = BAND_2; + else if (ap_caps->operating_class[i].op_class >= 112 && + ap_caps->operating_class[i].op_class <= 130) + band = BAND_5; + + } + + if (creds->band != band) + return NULL; + + m2 = (struct tlv_wsc *) calloc(1, sizeof(struct tlv_wsc)); + if (!m2) + return NULL; + + m2->tlv_type = TLV_TYPE_WSC; + + if (creds->sec == WIFI_SECURITY_WPA3PSK) + cfg.input.auth_types = 0x0040; + else if (creds->sec == WIFI_SECURITY_WPA2PSK) + cfg.input.auth_types = 0x0020; + else if (creds->sec == WIFI_SECURITY_WPAPSK) + cfg.input.auth_types = 0x0002; + else /* default to WPA */ + cfg.input.auth_types = 0x0008; + + /* backhaul STA */ + cfg.input.mapie |= (creds->mode == WIFI_MODE_STA ? 1 << 7 : 0); + /* backhaul BSS */ + cfg.input.mapie |= (creds->multi_ap & 0x01) << 6; + /* fronthaul BSS */ + cfg.input.mapie |= (creds->multi_ap & 0x02) << 4; + /* backhaul STA */ + cfg.input.mapie |= (creds->disallow_bsta << 2); + /* teardown bit */ + //cfg.input.mapie |= 1 << 3; + + memcpy(cfg.input.ssid, creds->ssid, 32); + memcpy(cfg.input.network_key, creds->key, 64); + cfg.input.encryption_types = 0; // Will not match any + + rv = wscBuildM2(m1->wsc_frame, m1->wsc_frame_size, &m2->wsc_frame, + &m2->wsc_frame_size, band, NULL, &cfg); + if (!rv) + err("Failed to build m2!\n"); + + return m2; +} + +struct tlv_ap_radio_identifier *cntlr_gen_radio_identifier(struct controller *c, + struct cmdu_cstruct *cmdu, struct cmdu_cstruct *rec_cmdu) +{ + struct tlv_ap_radio_identifier *p; + uint8_t *tlv; + int i; + + p = (struct tlv_ap_radio_identifier *) calloc(1, + sizeof(struct tlv_ap_radio_identifier)); + if (!p) + return NULL; + + for (i = 0; i < rec_cmdu->num_tlvs; i++) { + tlv = (uint8_t *) rec_cmdu->tlvs[i]; + switch (*tlv) { + case MAP_TLV_AP_RADIO_BASIC_CAPABILITIES: { + struct tlv_ap_radio_basic_cap *rec_p = (struct tlv_ap_radio_basic_cap *)tlv; + + p->tlv_type = MAP_TLV_AP_RADIO_IDENTIFIER; + memcpy(p->radio_id, rec_p->radio_id, 6); + break; + } + default: + break; + } + } + + return p; +} + +struct tlv_supp_service *cntlr_gen_supp_service(struct controller *c, + struct cmdu_cstruct *cmdu) +{ + struct tlv_supp_service *p; + int i; + + p = (struct tlv_supp_service *)calloc(1, sizeof(*p)); + if (!p) + return NULL; + + p->tlv_type = MAP_TLV_SUPPORTED_SERVICE; + p->supported_services_list = 1; + p->supported_services = calloc(p->supported_services_list, + sizeof(*p->supported_services)); + if (!p->supported_services) { + map_free_tlv_cstruct((uint8_t *) p); + return NULL; + } + + for (i = 0; i < p->supported_services_list; i++) + p->supported_services[i].service = SUPPORTED_SERVICE_MULTIAP_CONTROLLER; + + return p; +} + +struct tlv_map_profile *cntlr_gen_map_profile(struct controller *c, + struct cmdu_cstruct *cmdu) +{ + struct tlv_map_profile *p; + + p = calloc(1, sizeof(struct tlv_map_profile)); + if (!p) + return NULL; + + p->tlv_type = MAP_TLV_MULTIAP_PROFILE; + p->profile = 0x02; + + return p; +} diff --git a/src/core/cntlr_tlv_generator.h b/src/core/cntlr_tlv_generator.h new file mode 100644 index 0000000000000000000000000000000000000000..399f92bc4334cccb72068480aae0efb98e48970b --- /dev/null +++ b/src/core/cntlr_tlv_generator.h @@ -0,0 +1,26 @@ +/* + * cntlr_tlv_generator.h - tlv building function declarations + * + * Copyright (C) 2020 IOPSYS Software Solutions AB. All rights reserved. + * + * Author: jakob.olsson@iopsys.eu + * + */ + +#ifndef CNTLR_TLV_GEN_H +#define CNTLR_TLV_GEN_H + +struct tlv_default_8021q_settings *cntlr_gen_8021q_settings(struct controller *c, + struct cmdu_cstruct *cmdu, struct cmdu_cstruct *rec_cmdu); +struct tlv_traffic_sep_policy *cntlr_gen_traffic_sep_policy(struct controller *c, + struct cmdu_cstruct *cmdu); +struct tlv_wsc *cntlr_gen_wsc(struct controller *c, + struct cmdu_cstruct *cmdu, struct cmdu_cstruct *rec_cmdu, + struct iface_credential *fh); +struct tlv_ap_radio_identifier *cntlr_gen_radio_identifier(struct controller *c, + struct cmdu_cstruct *cmdu, struct cmdu_cstruct *rec_cmdu); +struct tlv_supp_service *cntlr_gen_supp_service(struct controller *c, + struct cmdu_cstruct *cmdu); +struct tlv_map_profile *cntlr_gen_map_profile(struct controller *c, + struct cmdu_cstruct *cmdu); +#endif diff --git a/src/core/cntlr_ubus.c b/src/core/cntlr_ubus.c index 5659a95cd7bf36a0c6f631ce4fd2625720ab8837..1bcffc90823922a3cd49ba8dd1e3707bc8c5dc85 100644 --- a/src/core/cntlr_ubus.c +++ b/src/core/cntlr_ubus.c @@ -21,6 +21,8 @@ #include <easy/easy.h> #include <wifi.h> // TODO: remove wifi.h +#include <map1905/map2.h> +#include <map1905/maputils.h> #include "utils.h" #include "debug.h" @@ -32,9 +34,6 @@ #include "map_module.h" -#include <map1905/map2.h> -#include <map1905/maputils.h> - enum { AP_POLICY_AGENT, /* TODO: filter on cntlr side based on bssid */ @@ -71,7 +70,30 @@ static const struct blobmsg_policy channel_pref_policy_params[__CHANNEL_PREF_POL [CHANNEL_PREF_POLICY_AGENT] = { .name = "agent", .type = BLOBMSG_TYPE_STRING } }; -static void send_cmdu_cb(struct ubus_request *req, +enum { + CFG_POLICY_AGENT, + CFG_POLICY_RADIO, + CFG_POLICY_BSSID, + __CFG_POLICY_MAX, +}; + +static const struct blobmsg_policy config_policy_params[__CFG_POLICY_MAX] = { + [CFG_POLICY_AGENT] = { .name = "agent", .type = BLOBMSG_TYPE_STRING }, + [CFG_POLICY_RADIO] = { .name = "radio", .type = BLOBMSG_TYPE_STRING }, + [CFG_POLICY_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING }, +}; + +enum { + RECFG_POLICY_AGENT, + __RECFG_POLICY_MAX, +}; + +static const struct blobmsg_policy reconfig_policy_params[__RECFG_POLICY_MAX] = { + [RECFG_POLICY_AGENT] = { .name = "agent", .type = BLOBMSG_TYPE_STRING }, +}; + + +void send_cmdu_cb(struct ubus_request *req, int type, struct blob_attr *msg) { struct json_object *jobj = NULL; @@ -103,7 +125,7 @@ static void send_cmdu_cb(struct ubus_request *req, json_object_put(jobj); } -static int send_cmdu(struct controller *c, +int send_cmdu(struct controller *c, struct cmdu_cstruct *cmdu_data) { char *tlv_data = NULL; @@ -112,7 +134,7 @@ static int send_cmdu(struct controller *c, int copy_index; struct blob_buf b = { 0 }; char dst_addr[18] = { 0 }; - char tlv_str[512] = { 0 }; + char *tlv_str = NULL; uint8_t *ss = NULL; uint16_t msgid = 0; uint16_t len; @@ -127,7 +149,6 @@ static int send_cmdu(struct controller *c, blobmsg_add_u32(&b, "type", cmdu_data->message_type); blobmsg_add_string(&b, "egress", cmdu_data->intf_name); - blobmsg_add_u32(&b, "mid", cmdu_data->message_id); hwaddr_ntoa(cmdu_data->origin, dst_addr); @@ -139,9 +160,16 @@ static int send_cmdu(struct controller *c, if (cmdu_data->num_tlvs > 0) { for (i = 0; i < cmdu_data->num_tlvs; i++) { + trace("CMDU type: %s\n", map_stringify_tlv_type(*cmdu_data->tlvs[i])); + len = 0; ss = map_put_tlv_cstruct(cmdu_data->tlvs[i], &len); if (ss) { + tlv_str = (char *)calloc((2 * len) + 1, sizeof(char)); + if (!tlv_str) { + free(ss); + goto out; + } btostr(ss, len, tlv_str); tlv_str_len = 2 * len; tlv_data_len += tlv_str_len; @@ -155,17 +183,16 @@ static int send_cmdu(struct controller *c, copy_index = tlv_data_len - tlv_str_len - 1; memcpy(tlv_data + copy_index, tlv_str, tlv_str_len); - memset(tlv_str, 0, sizeof(tlv_str)); free(ss); + free(tlv_str); } } - tlv_data[tlv_data_len - 1] = '\0'; blobmsg_add_string(&b, "data", tlv_data); if (tlv_data) free(tlv_data); - } + } if (ubus_lookup_id(c->ubus_ctx, "map.1905", &id)) { fprintf(stderr, "[%s:%d] not present", __func__, __LINE__); @@ -181,10 +208,10 @@ static int send_cmdu(struct controller *c, __func__, __LINE__); goto out; } + test_cmdu(cmdu_data); out: blob_buf_free(&b); - return ret; } @@ -274,7 +301,7 @@ static int cntlr_status(struct ubus_context *ctx, struct ubus_object *obj, return UBUS_STATUS_OK; } -static int cntlr_ap_caps(struct ubus_context *ctx, struct ubus_object *obj, +int cntlr_ap_caps(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { @@ -310,6 +337,8 @@ static int cntlr_ap_caps(struct ubus_context *ctx, struct ubus_object *obj, send_cmdu(c, cmdu_data); + map_free_cmdu(cmdu_data); + return 0; } @@ -426,9 +455,219 @@ static int cntlr_sta_caps(struct ubus_context *ctx, struct ubus_object *obj, send_cmdu(c, cmdu_data); + map_free_cmdu(cmdu_data); + return 0; } +static int cntlr_teardown_ap(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + return 0; +} + +static int cntlr_reconfig_ap(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + return 0; +} + + +/* + * - One AP Radio Identifier TLV (see section 17.2.3). + * - One or more WSC TLV (containing M2). + * - Zero or one Default 802.1Q Settings TLV (see section 17.2.49). [Profile-2] + * - Zero or one Traffic Separation Policy TLV (see section 17.2.50). [Profile-2] +*/ + +struct tlv_ap_radio_identifier *cntlr_gen_config_ap_tlv(struct controller *c, + struct cmdu_cstruct *cmdu, uint8_t *hwaddr) +{ + struct tlv_ap_radio_identifier *p; + + p = (struct tlv_ap_radio_identifier *)calloc(1, + sizeof(struct tlv_ap_radio_identifier)); + if (!p) { + fprintf(stderr, "failed to malloc tlv\n"); + return NULL; + } + + p->tlv_type = MAP_TLV_AP_RADIO_IDENTIFIER; + memcpy(p->radio_id, hwaddr, 6); + + return p; +} + +static struct netif_radio *cntlr_radio_to_bssid(struct controller *c, const char *radio) +{ + struct netif_radio *r; + + list_for_each_entry(r, &c->radiolist, list) { + if (!strncmp(r->name, radio, 16)) + return r; + } + + return NULL; +} + +static int cntlr_config_ap(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct controller *c = container_of(obj, struct controller, obj); + struct blob_attr *tb[__CFG_POLICY_MAX]; + char agent[18] = {0}; + uint8_t hwaddr[6] = {0}; + struct cmdu_cstruct *cmdu; + struct agent_policy *a, *found = NULL; + struct tlv_ap_radio_identifier *p = NULL; + struct tlv_default_8021q_settings *p1; + struct tlv_traffic_sep_policy *p2; + int i, tlv_index = 0; + + blobmsg_parse(config_policy_params, __CFG_POLICY_MAX, tb, + blob_data(msg), blob_len(msg)); + + if (!tb[CFG_POLICY_AGENT] || + (!tb[CFG_POLICY_RADIO] && !tb[CFG_POLICY_BSSID])) { + fprintf(stderr, "STA Capability Query: provide BSSID " \ + "address in format 11:22:33...\n"); + return UBUS_STATUS_INVALID_ARGUMENT; + } + + strncpy(agent, blobmsg_data(tb[CFG_POLICY_AGENT]), sizeof(agent) - 1); + if (!hwaddr_aton(agent, hwaddr)) + return UBUS_STATUS_UNKNOWN_ERROR; + + list_for_each_entry(a, &c->cfg.policylist, list) { + if (!memcmp(hwaddr, a->agent_id, sizeof(hwaddr))) { + found = a; + break; + } + } + + if (!found) + return UBUS_STATUS_UNKNOWN_ERROR; + + cmdu = (struct cmdu_cstruct *)calloc(1, sizeof(struct cmdu_cstruct)); + if (!cmdu) { + fprintf(stderr, "failed to malloc cmdu\n"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + memcpy(cmdu->origin, hwaddr, sizeof(hwaddr)); + cmdu->message_type = CMDU_TYPE_AP_AUTOCONFIGURATION_WSC; + cmdu->message_id = 1; + + if (tb[CFG_POLICY_BSSID]) { + char bssid[18] = {0}; + uint8_t hwaddr[6] = {0}; + + strncpy(bssid, blobmsg_data(tb[CFG_POLICY_BSSID]), + sizeof(bssid) - 1); + if (!hwaddr_aton(bssid, hwaddr)) { + free(cmdu); + return UBUS_STATUS_UNKNOWN_ERROR; + } + p = cntlr_gen_config_ap_tlv(c, cmdu, hwaddr); + } else if (tb[CFG_POLICY_RADIO]) { + char radio[18] = {0}; + struct netif_radio *r; + + strncpy(radio, blobmsg_data(tb[CFG_POLICY_RADIO]), + sizeof(radio) - 1); + r = cntlr_radio_to_bssid(c, radio); + if (!r) { + free(cmdu); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + p = cntlr_gen_config_ap_tlv(c, cmdu, r->hwaddr); + } + /* + else { // TODO: all radios + struct netif_radio *r; + + list_for_each_entry(r, &c->radiolist, list) { + int i; + + cntlr_gen_config_ap_tlv(c, cmdu, r->hwaddr); + send_cmdu(c, cmdu); + + for (i = 0; i < cmdu->num_tlvs; i++) + free(cmdu->tlvs[i]); + free(cmdu->tlvs); + cmdu->num_tlvs = 0; + } + } + */ + if (!p) + goto fail_cmdu; + + cmdu->num_tlvs++; + + p1 = (struct tlv_default_8021q_settings *) calloc(1, sizeof(*p1)); + if (!p1) + goto fail_p; + + cmdu->num_tlvs++; + p1->tlv_type = MAP_TLV_DEFAULT_8021Q_SETTINGS; + p1->primary_vid = a->pvid; + p1->pcp = a->pcp_default; + + p2 = (struct tlv_traffic_sep_policy *) calloc(1, sizeof(*p2)); + if (!p2) + goto fail_p1; + + cmdu->num_tlvs++; + p2->tlv_type = MAP_TLV_TRAFFIC_SEPARATION_POLICY; + p2->nbr_ssid = c->cfg.num_fh; + p2->data = calloc(p2->nbr_ssid, sizeof(*(p2->data))); + if (!p2->data) + goto fail_p2; + + for (i = 0; i < p2->nbr_ssid; i++) { + int len; + + len = strlen((char *)c->cfg.fh[i].ssid); + + p2->data[i].ssid_len = len; + p2->data[i].vid = c->cfg.fh[i].vlanid; + p2->data[i].ssid = calloc(1, len + 1); + if (!p2->data[i].ssid) + continue; + + strncpy(p2->data[i].ssid, (char *)c->cfg.fh[i].ssid, len); + } + + cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs, sizeof(uint8_t *)); + if (!cmdu->tlvs) + goto fail_p2_data; + cmdu->tlvs[tlv_index++] = (uint8_t *)p; + cmdu->tlvs[tlv_index++] = (uint8_t *)p1; + cmdu->tlvs[tlv_index++] = (uint8_t *)p2; + + // TODO: ff:ff:ff:ff:ff:ff = send to all agents + + send_cmdu(c, cmdu); + map_free_cmdu(cmdu); + return 0; + +fail_p2_data: + free(p2->data); +fail_p2: + free(p2); +fail_p1: + free(p1); +fail_p: + free(p); +fail_cmdu: + free(cmdu); + return UBUS_STATUS_UNKNOWN_ERROR; +} + int cntlr_publish_object(struct controller *c, const char *objname) { struct ubus_object *obj; @@ -439,6 +678,14 @@ int cntlr_publish_object(struct controller *c, const char *objname) UBUS_METHOD("ap_caps", cntlr_ap_caps, ap_caps_policy_params), UBUS_METHOD("sta_caps", cntlr_sta_caps, sta_caps_policy_params), UBUS_METHOD("channels", cntlr_channel_pref, channel_pref_policy_params) + /* + UBUS_METHOD("teardown_ap", cntlr_teardown_ap, + config_policy_params), + UBUS_METHOD("reconfig_ap", cntlr_reconfig_ap, + reconfig_policy_params), + UBUS_METHOD("config_ap", cntlr_config_ap, config_policy_params), + */ + }; int num_methods = ARRAY_SIZE(m); int ret; @@ -482,8 +729,11 @@ int cntlr_publish_object(struct controller *c, const char *objname) void cntlr_remove_object(struct controller *c) { - if (c->ubus_ctx && c->obj.id != OBJECT_INVALID) + if (c->ubus_ctx && c->obj.id != OBJECT_INVALID) { ubus_remove_object(c->ubus_ctx, &c->obj); + free(c->obj.type); + free((void *)c->obj.methods); + } } int cntlr_register_module(struct controller *c) diff --git a/src/core/cntlr_ubus.h b/src/core/cntlr_ubus.h index 42b326a4d0466e1a0a54b20aa9f1699fed9a8628..9df1484004fe37d131dc9826f395e8b862003cfe 100644 --- a/src/core/cntlr_ubus.h +++ b/src/core/cntlr_ubus.h @@ -12,9 +12,8 @@ extern int cntlr_publish_object(struct controller *c, const char *objname); extern void cntlr_remove_object(struct controller *c); - - extern int cntlr_register_module(struct controller *c); - +void send_cmdu_cb(struct ubus_request *req, int type, struct blob_attr *msg); +int send_cmdu(struct controller *c, struct cmdu_cstruct *cmdu_data); #endif /* CNTLR_UBUS_H */ diff --git a/src/core/config.c b/src/core/config.c index c996dfa82705d36ca5f43c3d38a792c2a47da137..bb72a65b3b619cd8b878fea94c0827cc0eb7bf2d 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -69,7 +69,7 @@ void cntlr_config_dump(struct controller_config *c) } dbg("Agents policy: Default\n"); - dbg(" Id : " MACFMT "\n", MAC2STR(c->apolicy.id)); + dbg(" Id : " MACFMT "\n", MAC2STR(c->apolicy.agent_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); @@ -149,6 +149,8 @@ static int cntlr_config_get_credentials(struct controller_config *c, CRED_SEC, CRED_KEY, CRED_VLAN, + CRED_MAP, + CRED_D_BSTA, NUM_CREDS, }; const struct uci_parse_option opts[] = { @@ -157,21 +159,24 @@ static int cntlr_config_get_credentials(struct controller_config *c, [CRED_SEC] = { .name = "encryption", .type = UCI_TYPE_STRING }, [CRED_KEY] = { .name = "key", .type = UCI_TYPE_STRING }, [CRED_VLAN] = { .name = "vlan", .type = UCI_TYPE_STRING }, + [CRED_MAP] = { .name = "multi_ap", .type = UCI_TYPE_STRING }, + [CRED_D_BSTA] = { .name = "disallow_bsta", .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++]; + cred->mode = WIFI_MODE_AP; } else { if (c->num_bk >= 2) return -1; cred = &c->bk[c->num_bk++]; + cred->mode = WIFI_MODE_STA; } uci_parse_section(s, opts, NUM_CREDS, tb); @@ -184,7 +189,7 @@ static int cntlr_config_get_credentials(struct controller_config *c, } if (tb[CRED_SSID]) - memcpy(cred->ssid, tb[CRED_SSID]->v.string, 32); + strncpy((char *) cred->ssid, tb[CRED_SSID]->v.string, 32); if (tb[CRED_SEC]) { const char *sec = tb[CRED_SEC]->v.string; @@ -200,11 +205,17 @@ static int cntlr_config_get_credentials(struct controller_config *c, } if (tb[CRED_KEY]) - memcpy(cred->key, tb[CRED_KEY]->v.string, 63); + strncpy((char *) cred->key, tb[CRED_KEY]->v.string, 63); if (tb[CRED_VLAN]) cred->vlanid = atoi(tb[CRED_VLAN]->v.string); + if (tb[CRED_MAP]) + cred->multi_ap = atoi(tb[CRED_MAP]->v.string); + + if (tb[CRED_D_BSTA]) + cred->disallow_bsta = atoi(tb[CRED_D_BSTA]->v.string); + return 0; } @@ -212,7 +223,7 @@ static int cntlr_config_get_agent_policy(struct controller_config *c, struct uci_section *s) { enum { - POL_ID, + POL_AGENT_ID, POL_STEER, POL_UTIL_TH, POL_RCPI_TH, @@ -230,7 +241,7 @@ static int cntlr_config_get_agent_policy(struct controller_config *c, NUM_POLICIES, }; const struct uci_parse_option opts[] = { - { .name = "id", .type = UCI_TYPE_STRING }, + { .name = "agent_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 }, @@ -247,82 +258,87 @@ static int cntlr_config_get_agent_policy(struct controller_config *c, { .name = "disallow_bsta_p2", .type = UCI_TYPE_STRING }, }; struct uci_option *tb[NUM_POLICIES]; + struct agent_policy *a; + + a = calloc(1, sizeof(*a)); + if (!a) + return -1; uci_parse_section(s, opts, NUM_POLICIES, tb); - if (tb[POL_ID]) { - const char *val = tb[POL_ID]->v.string; + if (tb[POL_AGENT_ID]) { + const char *val = tb[POL_AGENT_ID]->v.string; - hwaddr_aton(val, c->apolicy.id); + hwaddr_aton(val, a->agent_id); } if (tb[POL_STEER]) - c->apolicy.policy = atoi(tb[POL_STEER]->v.string); + a->policy = atoi(tb[POL_STEER]->v.string); if (tb[POL_UTIL_TH]) - c->apolicy.util_threshold = atoi(tb[POL_UTIL_TH]->v.string); + a->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); + a->rcpi_threshold = atoi(tb[POL_RCPI_TH]->v.string); if (tb[POL_RPT_SCAN]) { - c->apolicy.report_scan = + a->report_scan = atoi(tb[POL_RPT_SCAN]->v.string) == 1 ? true : false; } if (tb[POL_RPT_ASSOC_FAILS]) { - c->apolicy.report_sta_assocfails = + a->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 = + a->report_metric_periodic = atoi(tb[POL_RPT_METRIC_PERIODIC]->v.string); } if (tb[POL_RPT_RCPI_TH]) { - c->apolicy.report_rcpi_threshold = + a->report_rcpi_threshold = atoi(tb[POL_RPT_RCPI_TH]->v.string); } if (tb[POL_RPT_UTIL_TH]) { - c->apolicy.report_util_threshold = + a->report_util_threshold = atoi(tb[POL_RPT_UTIL_TH]->v.string); } if (tb[POL_INC_STA_STATS]) { - c->apolicy.include_sta_stats = + a->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 = + a->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); + a->pvid = atoi(tb[POL_PVID]->v.string); if (tb[POL_PCP_DEFAULT]) - c->apolicy.pcp_default = atoi(tb[POL_PCP_DEFAULT]->v.string); + a->pcp_default = atoi(tb[POL_PCP_DEFAULT]->v.string); if (tb[POL_DISALLOW_BSTA_P1]) { - c->apolicy.disallow_bsta_p1 = + a->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 = + a->disallow_bsta_p2 = atoi(tb[POL_DISALLOW_BSTA_P2]->v.string) == 1 ? true : false; } - + list_add(&a->list, &c->policylist); return 0; } @@ -357,3 +373,22 @@ int cntlr_config_reload(struct controller_config *cfg) uci_free_context(ctx); return 0; } + +int clean_agent_policies(struct controller_config *cfg) +{ + struct agent_policy *p, *tmp; + + list_for_each_entry_safe(p, tmp, &cfg->policylist, list) { + list_del(&p->list); + free(p); + } + + return 0; +} + +int cntlr_config_clean(struct controller_config *cfg) +{ + clean_agent_policies(cfg); + + return 0; +} diff --git a/src/core/config.h b/src/core/config.h index c1b752c7ad80ba7a83b3c3921b0461a19a6217a9..792e25bd2732711cbe089a2893755c3c05b743f5 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -44,6 +44,10 @@ struct iface_credential { uint8_t bssid[6]; uint8_t ssid[33]; uint16_t vlanid; + uint8_t multi_ap; + struct list_head *list; + enum wifi_mode mode; + uint8_t disallow_bsta; }; enum agent_steer_policy { @@ -53,7 +57,7 @@ enum agent_steer_policy { }; struct agent_policy { - uint8_t id[6]; /* ieee1905 AL macaddress */ + uint8_t agent_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 */ @@ -95,5 +99,5 @@ struct controller; 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 cntlr_config_clean(struct controller_config *cfg); #endif diff --git a/src/utils/debug.c b/src/utils/debug.c index 0c3e26db97a4ee6ace9fd3c99d2879f70433e4dd..b10ecb1dd45eeeea093b38e6fda3f58edff0032a 100644 --- a/src/utils/debug.c +++ b/src/utils/debug.c @@ -220,5 +220,6 @@ void log_cmdu(int level, void *var) continue; log_test(level, btlv, len); + free(btlv); } }