diff --git a/src/core/agent.c b/src/core/agent.c index defc7d25e56c9a0144898a3621017b8bc590fcdd..a6a955addfc61e797002c3c0f4e3ba5e2a431c93 100644 --- a/src/core/agent.c +++ b/src/core/agent.c @@ -1226,7 +1226,7 @@ static int wifi_send_sta_report(struct agent *a, const char *vif, return -1; //TODO use the cntl ifname and origin address - strcpy(ifname, "br-lan"); + strncpy(ifname, a->cfg.al_bridge, sizeof(ifname)); memcpy(origin, a->cntlr_almac, 6); /* Here we get need to send the steering report */ @@ -1890,10 +1890,10 @@ static void agent_add_to_bridge(struct agent *a, char *ifname) } } -static void wifi_bsta_event_handler(void *c, struct blob_attr *msg) +static void wifi_bsta_event_handler(void *agent, struct blob_attr *msg) { char ifname[16] = {0}, event[16] = {0}, bssid_str[18] = {0}; - struct agent *a = (struct agent *) c; + struct agent *a = (struct agent *) agent; struct blob_attr *tb[3]; static const struct blobmsg_policy ev_attr[3] = { [0] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, @@ -1911,7 +1911,6 @@ static void wifi_bsta_event_handler(void *c, struct blob_attr *msg) if (!tb[0] || !tb[1] || !tb[2]) return; - strncpy(ifname, blobmsg_data(tb[0]), sizeof(ifname) - 1); strncpy(event, blobmsg_data(tb[1]), sizeof(event) - 1); @@ -1933,19 +1932,51 @@ static void wifi_bsta_event_handler(void *c, struct blob_attr *msg) strncpy(bssid_str, blobmsg_data(data[0]), sizeof(bssid_str) - 1); + + hwaddr_aton(bssid_str, bssid); } if (add) { + int i; + time_t now; + char pid[8] = {0}; + + time(&now); + bk->connected = true; - if (!a->configured) { - time(&a->autocfg); - uloop_timeout_set(&a->autocfg_dispatcher, 2 * 1000); // 2 seconds - } else { - trace("Autoconfig already completed, will not trigger" \ - " again on bsta connection\n"); - /* if (a->cfg.brcm_setup) */ - agent_add_to_bridge(a, ifname); + + /** TODO: use pidfile */ + chrCmd(pid, sizeof(pid), "pidof mapcontroller"); + if (strlen(pid)) { + set_value_by_string("mapcontroller", "controller", "enabled", "0", + UCI_TYPE_STRING); + trace("found pid %s of mapcontroller, sending SIGHUP\n", pid); + kill(atoi(pid), SIGHUP); + } + + dbg("|%s:%d| connect event received\n", __func__, __LINE__); + + dbg("|%s:%d| new bssid " MACFMT " old bssid " MACFMT ","\ + " difftime %.2f(s)\n", __func__, __LINE__, + MAC2STR(bssid), MAC2STR(bk->wan_bssid), + difftime(now, bk->connect_t)); + + if (memcmp(bssid, bk->wan_bssid, 6) || + difftime(now, bk->connect_t) > 15) { + dbg("|%s:%d| new bssid or difftime exceeded 15s,"\ + "setting radio states to ACTIVE\n", + __func__, __LINE__); + /** upon connecting to new network - allow radios to be + * reconfigured + */ + for (i = 0; i < a->num_radios; i++) + a->radios[i].state = ACS_ACTIVE; } + hwaddr_aton(bssid_str, bk->wan_bssid); + + time(&bk->connect_t); + uloop_timeout_set(&a->autocfg_dispatcher, 5 * 1000); + agent_add_to_bridge(a, ifname); } else if (del) { bk->connected = false; wifi_mod_bridge(a, ifname, "remove"); @@ -1960,8 +1991,6 @@ static void wifi_bsta_event_handler(void *c, struct blob_attr *msg) if (!p) goto fail_cmdu; - hwaddr_aton(bssid_str, bssid); - /** * if event bssid and tlv target bssid differ, that means steering * failed, add an error TLV prior to sending response @@ -2035,7 +2064,7 @@ static void wifi_wps_creds_event_handler(void *c, struct blob_attr *msg) return; } - uci_reload_services(); + uci_reload_services("wireless"); radio = wifi_ifname_to_radio_element(a, ifname); if (!radio) @@ -2641,7 +2670,7 @@ static void parse_radio(struct ubus_request *req, int type, re->rx_streams = blobmsg_get_u8(tb[3]); if (tb[4]) - re->rx_streams = blobmsg_get_u8(tb[4]); + re->tx_streams = blobmsg_get_u8(tb[4]); if (tb[5]) { struct blob_attr *cur, *cur1; @@ -3470,7 +3499,7 @@ static void agent_steering_opp_timeout(struct uloop_timeout *t) char ifname[IFNAMESIZE] = { 0 }; uint8_t origin[6] = { 0 }; - strncpy(ifname, "br-lan", sizeof(ifname)); + strncpy(ifname, a->cfg.al_bridge, sizeof(ifname)); memcpy(origin, a->cntlr_almac, 6); send_sta_steer_complete((void *)a, origin, ifname); } @@ -3480,23 +3509,21 @@ static void agent_dispatch_autoconfig(struct uloop_timeout *t) { struct agent *a = container_of(t, struct agent, autocfg_dispatcher); int diff; - time_t now; struct netif_bk *bk; int i; - time(&now); - - trace("|%s:%d| Attempting to trigger AP-Autoconfig\n", __func__, __LINE__); + trace("|%s:%d| Triggering AP-Autoconfig Search\n", __func__, __LINE__); +#if 0 diff = difftime(now, a->autocfg); dbg("|%s:%d| Time since AP-Auotconfig was triggered %d(s)\n", __func__, __LINE__, diff); /* if more than 2 minutes has passed since triggered, stop */ - if (a->configured && diff > 2 * 60) { + if (diff > 2 * 60) { dbg("|%s:%d| Diff exceeds 2 minutes and agent is configured, "\ "will not retrigger\n", __func__, __LINE__); return; } - +#endif /* Only applicable for bSTA interfaces */ list_for_each_entry(bk, &a->bklist, list) { if (!bk->connected) @@ -3508,14 +3535,14 @@ static void agent_dispatch_autoconfig(struct uloop_timeout *t) for (i = 0; i < a->num_radios; i++) { struct cmdu_cstruct *cmdu; struct wifi_radio_element *radio = &a->radios[i]; - - if (radio->onboarded || radio->configured) { - dbg("radio %s has been onboarded, don't trigger search\n", + int mid; +#if 0 + if (/* radio->onboarded || */radio->configured) { + dbg("radio %s has been configured, don't trigger search\n", radio->name); continue; } - - +#endif cmdu = agent_gen_ap_autoconfig_search(a, radio, NULL, 0x02); if (!cmdu) continue; @@ -3523,7 +3550,9 @@ static void agent_dispatch_autoconfig(struct uloop_timeout *t) trace("|%s:%d| Sending Autoconfig Search for radio %s(%s)\n", __func__, __LINE__, radio->name, (radio->band == BAND_2 ? "2.4GHz" : "5GHz")); - agent_send_cmdu(a, cmdu); + mid = agent_send_cmdu(a, cmdu); + if (mid >= 0) + radio->mid = mid; map_free_cmdu(cmdu); } @@ -3651,7 +3680,7 @@ int start_agent(void) /* TODO: memory management of thread on cleaup */ ret = pthread_create(&(tid[0]), NULL, (void *)&brcm_nl_loop, - NULL); + w->cfg.al_bridge); if (ret) { fprintf(stderr, "Failed to create thread\n"); return -1; @@ -3675,6 +3704,7 @@ int start_agent(void) if (flags & IFF_UP) break; + trace("Interface %s (found in mapagent UCI) is not up, waiting for it to come up\n", f->name); sleep(2); } } @@ -3703,8 +3733,7 @@ int start_agent(void) w->sta_steerlist_count = 0; w->sta_steer_req_timer.cb = agent_steering_opp_timeout; - time(&w->autocfg); - uloop_timeout_set(&w->autocfg_dispatcher, 2 * 1000); // 2 seconds + uloop_timeout_set(&w->autocfg_dispatcher, 0 * 1000); uloop_run(); diff --git a/src/core/agent.h b/src/core/agent.h index f6e5eb6d71727ba63d3b5cb7893f02803d811145..4336fb777b07093b32f1cb4a8bb25a31e25edd41 100644 --- a/src/core/agent.h +++ b/src/core/agent.h @@ -201,8 +201,10 @@ struct netif_bk { char name[16]; int channel; unsigned char bssid[6]; + unsigned char wan_bssid[6]; char ssid[33]; bool connected; + time_t connect_t; struct netif_bkcfg *cfg; /* enum netif_type iftype; */ struct list_head list; @@ -347,12 +349,15 @@ struct wsc_data { struct wsc_key *key; }; +enum acs_state { + ACS_ACTIVE, + ACS_HEARTBEAT +}; + struct wifi_radio_element { char name[16]; uint8_t macaddr[6]; uint8_t country_code[2]; - bool onboarded; - bool configured; enum wifi_band band; bool enabled; int anpi; @@ -368,7 +373,6 @@ struct wifi_radio_element { uint8_t transmit_power_limit; /* set in the channel selection message */ uint8_t max_bss; - uint32_t num_supp_opclass; uint32_t num_curr_opclass; uint32_t num_unassoc_sta; @@ -384,6 +388,11 @@ struct wifi_radio_element { struct wifi_scanres_element *scanlist; struct wifi_unassoc_sta_element *unassoc_stalist; + /** AP-Autoconfig */ + enum acs_state state; + bool onboarded; + bool configured; + uint16_t mid; struct wsc_data autconfig; }; @@ -406,8 +415,6 @@ struct agent { uint8_t almac[6]; uint8_t cntlr_almac[6]; struct uloop_timeout heartbeat; - bool configured; - time_t autocfg; struct uloop_timeout autocfg_dispatcher; struct list_head fhlist; struct list_head bklist; diff --git a/src/core/agent_cmdu_generator.c b/src/core/agent_cmdu_generator.c index 7d5680a532a209b9db29dfca7ff8f77d8c6e1e03..fd442e8d96e343d78d341b315bd7734bf900156c 100644 --- a/src/core/agent_cmdu_generator.c +++ b/src/core/agent_cmdu_generator.c @@ -71,7 +71,7 @@ struct cmdu_cstruct *agent_gen_ap_autoconfig_search(struct agent *a, strncpy(cmdu->intf_name, intf_name, sizeof(cmdu->intf_name) - 1); else - strncpy(cmdu->intf_name, "br-lan", sizeof(cmdu->intf_name) - 1); + strncpy(cmdu->intf_name, a->cfg.al_bridge, sizeof(cmdu->intf_name) - 1); cmdu->message_type = CMDU_TYPE_AP_AUTOCONFIGURATION_SEARCH; @@ -120,7 +120,7 @@ struct cmdu_cstruct *agent_gen_ap_autoconfig_search(struct agent *a, cmdu->num_tlvs++; band = wifi_band_to_ieee1905band(radio->band); - + trace("radio band = %d, band = %d\n", radio->band, band); p4 = agent_gen_autoconf_freq_band(a, band); if (!p4) goto fail_p3; diff --git a/src/core/agent_map.c b/src/core/agent_map.c index eefabba146dc5b6eab2e29b3c2a325aade73081d..41cccfead27866a75da456b424ac1bae1cd6fcb6 100644 --- a/src/core/agent_map.c +++ b/src/core/agent_map.c @@ -135,8 +135,8 @@ int build_ap_autoconfig_wsc(void *agent, struct cmdu_cstruct *rec_cmdu, int tlv_index = 0; /* don't trigger autoconfig for bSTA radios */ - if (radio->onboarded) - return -1; + //if (radio->onboarded) + // return -1; cmdu = (struct cmdu_cstruct *)calloc(1, sizeof(struct cmdu_cstruct)); if (!cmdu) { @@ -150,7 +150,7 @@ int build_ap_autoconfig_wsc(void *agent, struct cmdu_cstruct *rec_cmdu, strncpy(cmdu->intf_name, rec_cmdu->intf_name, sizeof(cmdu->intf_name) - 1); - p = agent_gen_ap_radio_basic_cap(a, cmdu, idx); + p = agent_gen_ap_radio_basic_cap(a, cmdu, radio); if (!p) goto fail_cmdu; cmdu->num_tlvs++; @@ -531,13 +531,28 @@ int handle_ap_autoconfig_response(void *agent, struct cmdu_cstruct *cmdu) { trace("agent: %s: --->\n", __func__); struct agent *a = (struct agent *) agent; - struct wifi_radio_element *radio; + struct wifi_radio_element *radio = NULL; struct tlv_supp_service *supp_serv; struct tlv_supported_freq_band *supp_freq; char mac_str[18] = {0}; bool cntlr = false; + uint8_t band; int i; + trace("%s %d mid = %d\n", __func__, __LINE__, cmdu->message_id); + + /* If MID is not the one we sent, discard response */ + for (i = 0; i < a->num_radios; i++) { + trace("radio %s has mid %d\n", a->radios[i].name, a->radios[i].mid); + if (a->radios[i].mid != cmdu->message_id) + continue; + + radio = &a->radios[i]; + break; + } + if (!radio) + return -1; + supp_serv = (struct tlv_supp_service *) extract_tlv_by_type(cmdu, MAP_TLV_SUPPORTED_SERVICE); if (!supp_serv) @@ -555,27 +570,40 @@ int handle_ap_autoconfig_response(void *agent, struct cmdu_cstruct *cmdu) return -1; } - memcpy(a->cntlr_almac, cmdu->origin, 6); - if (!hwaddr_ntoa(a->cntlr_almac, mac_str)) - return -1; + dbg("cntlr_almac " MACFMT " origin " MACFMT "\n", + MAC2STR(a->cntlr_almac), MAC2STR(cmdu->origin)); - set_value_by_string("mapagent", "agent", "controller_mac", mac_str, - UCI_TYPE_STRING); - uloop_timeout_cancel(&a->autocfg_dispatcher); + /* if it is a new controller, update cntlr_almac and uci */ + if (memcmp(a->cntlr_almac, cmdu->origin, 6)) { + memcpy(a->cntlr_almac, cmdu->origin, 6); + if (!hwaddr_ntoa(a->cntlr_almac, mac_str)) + return -1; - supp_freq = (struct tlv_supported_freq_band *) extract_tlv_by_type(cmdu, - TLV_TYPE_SUPPORTED_FREQ_BAND); - if (!supp_freq) - return -1; + set_value_by_string("mapagent", "agent", "controller_mac", mac_str, + UCI_TYPE_STRING); + dbg("|%s:%d| new controller found! Activate ACS configuration"\ + " for all radios\n", __func__, __LINE__); + for (i = 0; i < a->num_radios; i++) + a->radios[i].state = ACS_ACTIVE; + } - for (i = 0; i < a->num_radios; i++) { - uint8_t band; + /* return if it was just heartbeat and no activity */ + if (radio->state == ACS_HEARTBEAT) { + /** TODO: active own controller if no controller has been + * observed for certain time period + */ + } else if (radio->state == ACS_ACTIVE) { + supp_freq = (struct tlv_supported_freq_band *) extract_tlv_by_type(cmdu, + TLV_TYPE_SUPPORTED_FREQ_BAND); + if (!supp_freq) + return -1; - radio = a->radios + i; band = wifi_band_to_ieee1905band(radio->band); if (band != supp_freq->freq_band) - continue; + return -1; + dbg("|%s:%d| generate wsc for radio %s\n", __func__, __LINE__, + radio->name); build_ap_autoconfig_wsc(a, cmdu, radio, i); } @@ -652,14 +680,6 @@ int wifi_teardown_map_ifaces_by_radio(struct agent *a, char *device) clean_fh(fh); } - list_for_each_entry_safe(bk, bk_tmp, &a->cfg.bklist, list) { - if (strncmp(bk->device, device, sizeof(bk->device) - 1)) - continue; - - wifi_teardown_iface(bk->name); - clean_bk(bk); - } - agent_config_reload(&a->cfg); return 0; } @@ -677,14 +697,6 @@ int wifi_teardown_map_ifaces_by_band(struct agent *a, enum wifi_band band) clean_fh(fh); } - list_for_each_entry_safe(bk, bk_tmp, &a->cfg.bklist, list) { - if (bk->band != band) - continue; - - wifi_teardown_iface(bk->name); - clean_bk(bk); - } - agent_config_reload(&a->cfg); return 0; @@ -808,6 +820,14 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_cstruct *cmdu) dbg("|%s:%d| found radio = %s\n", __func__, __LINE__, radio->name); wifi_teardown_map_ifaces_by_radio(a, radio->name); + + if (radio->onboarded) { + dbg("|%s:%d| radio (%s) was onboarded, do not apply m2, apply heartbeat for this radio\n", + __func__, __LINE__, radio->name); + radio->configured = 1; /* not necessarily true */ + radio->state = ACS_HEARTBEAT; + goto teardown; + } /* iterate every TLV_TYPE_WSC, may be multiple */ for (i = 0; i < cmdu->num_tlvs; i++) { tlv = cmdu->tlvs[i]; @@ -852,17 +872,21 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_cstruct *cmdu) MAC2STR(bssid)); wifi_teardown_map_ifaces_by_radio(a, radio->name); + uci_set_wireless_interface_option("mapagent", + "wifi-radio", "device", + radio->name, "configured", "0"); goto teardown; } - rv = uci_apply_m2(ifname, radio->name, out.output.ssid, - out.output.auth_types, + rv = uci_apply_m2(&a->cfg, ifname, radio->name, + out.output.ssid, out.output.auth_types, out.output.encryption_types, out.output.network_key, out.output.mapie, radio->band, out.output.bridge, out.output.proto, out.output.vid, out.output.br_ip, - out.output.bk_ssid, out.output.bk_key); + out.output.bk_ssid, out.output.bk_key, + radio->onboarded); if (rv) { err("Failure to process M2, tearing down all "\ " MAP interfaces"\ @@ -872,26 +896,30 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_cstruct *cmdu) radio->name); goto teardown; } + break; } default: break; - } } + uci_set_wireless_interface_option("mapagent", "wifi-radio", "device", radio->name, "configured", "1"); + dbg("|%s:%d| radio (%s) was configured! Apply heartbeat for this radio\n", + __func__, __LINE__, radio->name); radio->configured = 1; - //a->configured = true; wifi_reorder_interfaces(&a->cfg); agent_config_reload(&a->cfg); + radio->state = ACS_HEARTBEAT; //uci_apply_wps_credentials(&a->cfg, radio->band); teardown: // TODO: freeing from here risks freeing an updated frame agent_free_wsc_data(&radio->autconfig); radio->autconfig.key = NULL; radio->autconfig.m1_frame = NULL; - uci_reload_services(); + uci_reload_services("wireless"); + //uci_reload_services("dhcp"); return 0; } @@ -1157,7 +1185,7 @@ int handle_ap_caps_query(void *agent, struct cmdu_cstruct *rec_cmdu) for (i = 0; i < a->num_radios; i++) { struct tlv_ap_radio_basic_cap *p; - p = agent_gen_ap_radio_basic_cap(a, cmdu, i); + p = agent_gen_ap_radio_basic_cap(a, cmdu, &a->radios[i]); if (!p) continue; //cmdu->num_tlvs++; @@ -3207,8 +3235,6 @@ int agent_send_cmdu(struct agent *a, struct cmdu_cstruct *cmdu) int ret = 0; size_t i; uint32_t id; - //uint8_t is_store_mid = 1; - //struct ieee1905_cmdu_msg *cmsg = NULL; trace("|%s:%d| Entry\n", __func__, __LINE__); @@ -3280,19 +3306,7 @@ int agent_send_cmdu(struct agent *a, struct cmdu_cstruct *cmdu) goto out; } - //TODO: improve ///////////////////////// - //if (is_store_mid) { - // cmsg = &priv->cmsg; - // for (i = 0; i < MAX_CMDU_MSG; i++) { - // if (cmsg->msg_id[i] == -1) { - // cmsg->msg_id[i] = msgid; - // cmsg->msg_ts[i] = time(NULL); - // break; - // } - // } - //} - ///////////////////////////////////////// - + ret = msgid; out: blob_buf_free(&b); diff --git a/src/core/agent_tlv_generator.c b/src/core/agent_tlv_generator.c index 7ca4c85944b130089316b813fa3dcde3471be03c..946e380020a65034de499c7654a7a15d7e314692 100644 --- a/src/core/agent_tlv_generator.c +++ b/src/core/agent_tlv_generator.c @@ -98,14 +98,11 @@ struct tlv_ap_cap *agent_gen_ap_caps(struct agent *a, } struct tlv_ap_radio_basic_cap *agent_gen_ap_radio_basic_cap(struct agent *a, - struct cmdu_cstruct *cmdu, uint32_t radio_index) + struct cmdu_cstruct *cmdu, struct wifi_radio_element *radio) { uint32_t j; - struct wifi_radio_element *radio; struct tlv_ap_radio_basic_cap *p; - radio = a->radios + radio_index; - p = (struct tlv_ap_radio_basic_cap *)calloc(1, sizeof(struct tlv_ap_radio_basic_cap)); diff --git a/src/core/agent_tlv_generator.h b/src/core/agent_tlv_generator.h index f3ff1d17b3b63bb98ee5359a94281aa80c80ca55..cd2587a25d439c894d9595c633fd47262c5edb36 100644 --- a/src/core/agent_tlv_generator.h +++ b/src/core/agent_tlv_generator.h @@ -20,7 +20,7 @@ struct tlv_ap_ht_cap *agent_gen_ap_ht_caps(struct agent *a, struct tlv_ap_cap *agent_gen_ap_caps(struct agent *a, struct cmdu_cstruct *cmdu); struct tlv_ap_radio_basic_cap *agent_gen_ap_radio_basic_cap(struct agent *a, - struct cmdu_cstruct *cmdu, uint32_t radio_index); + struct cmdu_cstruct *cmdu, struct wifi_radio_element *radio); struct tlv_ap_vht_cap *agent_gen_ap_vht_caps(struct agent *a, struct cmdu_cstruct *cmdu, uint32_t radio_index); struct tlv_profile2_ap_cap *agent_gen_profile2_ap_cap(struct agent *a); diff --git a/src/core/config.c b/src/core/config.c index 46e5c1921a278b313981d7cbfe924910dbdc4ea1..d2e17bde8131671baf2ca9eea39087b60fe0f1ba 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -90,7 +90,7 @@ int set_value_by_string(const char *package, const char *section, uci_commit(ctx, &ptr.p, false); uci_free_context(ctx); - return -1; + return rv; } struct uci_section *config_get_section(struct uci_context *ctx, @@ -200,7 +200,7 @@ int wifi_set_iface_bssid(const char *ifname, uint8_t *bssid) uci_commit(ctx, &pkg, false); - uci_reload_services(); + uci_reload_services("wireless"); out_pkg: uci_unload(ctx, pkg); uci_free_context(ctx); @@ -585,14 +585,14 @@ static int ubus_call(const char *object, const char *method, return UBUS_STATUS_OK; } -bool uci_reload_services(void) +bool uci_reload_services(char *services) { struct blob_buf bb; - int rv; + int rv = 0; memset(&bb, 0, sizeof(struct blob_buf)); blob_buf_init(&bb, 0); - blobmsg_add_string(&bb, "config", "wireless"); + blobmsg_add_string(&bb, "config", services); rv = ubus_call("uci", "commit", &bb, NULL, NULL); @@ -600,6 +600,8 @@ bool uci_reload_services(void) //if (!ubus_call("uci", "reload_config", &bb, NULL, NULL)) // return true; + //ubus_call("uci", "reload_config", &bb, NULL, NULL); + blob_buf_free(&bb); return false; @@ -652,21 +654,24 @@ int uci_apply_wps_credentials(struct agent_config *cfg, enum wifi_band band) /* TODO: batch the changes arther than commit oneby one */ -int uci_apply_m2(char *interface_name, char *device, uint8_t *ssid, - uint16_t auth_type, uint16_t encryption_type, +int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device, + uint8_t *ssid, uint16_t auth_type, uint16_t encryption_type, uint8_t *network_key, uint8_t mapie, uint8_t band, uint8_t *bridge, uint8_t *proto, uint8_t vid, uint32_t br_ip, - uint8_t *bk_ssid, uint8_t *bk_key) + uint8_t *bk_ssid, uint8_t *bk_key, bool onboarded) { bool ret; char auth_type_str[20] = {0}; char multiap_str[2] = {0}; uint8_t multi_ap = 0; - bool bk_mode; char band_str[2] = {0}; char agent_section[16] = {0}; char ipaddr_str[INET_ADDRSTRLEN] = {0}; + /* step past br- prefix if present*/ + if (!strncmp("br-", bridge, 3)) + bridge += 3; + inet_ntop(AF_INET, &br_ip, ipaddr_str, INET_ADDRSTRLEN); dbg("Applying WSC configuration (%s):\n", interface_name); @@ -687,7 +692,6 @@ int uci_apply_m2(char *interface_name, char *device, uint8_t *ssid, multi_ap |= (BIT(5, mapie) << 1); multi_ap |= BIT(6, mapie); - bk_mode = BIT(6, mapie); snprintf(multiap_str, sizeof(multiap_str), "%d", multi_ap); @@ -706,9 +710,7 @@ int uci_apply_m2(char *interface_name, char *device, uint8_t *ssid, return M2_PROCESS_ERROR; } - - strncpy(agent_section, (bk_mode ? UCI_BK_AGENT : UCI_FH_AGENT), - sizeof(agent_section)); + strncpy(agent_section, UCI_FH_AGENT, sizeof(agent_section)); // Set uci in agent ret = uci_check_wifi_iface(UCI_AGENT, interface_name, @@ -727,8 +729,6 @@ int uci_apply_m2(char *interface_name, char *device, uint8_t *ssid, else /* TODO: 60 */ return M2_PROCESS_ERROR; - uci_set_wireless_interface_option(UCI_AGENT, agent_section, "ifname", - interface_name, "band", band_str); uci_set_wireless_interface_option(UCI_AGENT, agent_section, "ifname", interface_name, "band", band_str); uci_set_wireless_interface_option(UCI_AGENT, agent_section, "ifname", @@ -739,13 +739,13 @@ int uci_apply_m2(char *interface_name, char *device, uint8_t *ssid, interface_name, "key", network_key); uci_set_wireless_interface_option(UCI_AGENT, agent_section, "ifname", interface_name, "encryption", auth_type_str); - if (bk_mode) { + if (multi_ap & 0x01) { char disallow_str[2] = {0}; snprintf(disallow_str, sizeof(disallow_str), "%d", ((mapie >> 2) & 0x03)); uci_set_wireless_interface_option(UCI_AGENT, - UCI_BK_AGENT, "ifname", + agent_section, "ifname", interface_name, "disallow_bsta", disallow_str); } @@ -779,7 +779,10 @@ int uci_apply_m2(char *interface_name, char *device, uint8_t *ssid, uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname", interface_name, "multi_ap_backhaul_ssid", bk_ssid); - if (bk_mode) { + if (onboarded) + uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname", + interface_name, "disabled", "1"); + if (multi_ap == 0x01) { uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname", interface_name, "hidden", "1"); } else { @@ -789,6 +792,11 @@ int uci_apply_m2(char *interface_name, char *device, uint8_t *ssid, UCI_WLAN_IFACE, "ifname", interface_name, "wps_pushbutton", "1"); } + + /* TODO: don't support guest network for the moment */ + //uci_add_dhcp(bridge); + //uci_add_fw(cfg, bridge); + return M2_PROCESS_OK; } /* end of functions taken from ieee1905d */ @@ -1233,6 +1241,7 @@ static int agent_config_get_wifi_agent(struct agent_config *a, A_CNTLR_MAC, A_EXCLUDE, A_EXCLUDE_BTM, + A_AL_BRIDGE, NUM_POLICIES }; const struct uci_parse_option opts[] = { @@ -1244,6 +1253,7 @@ static int agent_config_get_wifi_agent(struct agent_config *a, { .name = "controller_macaddr", .type = UCI_TYPE_STRING }, { .name = "exclude", .type = UCI_TYPE_LIST }, { .name = "exclude_btm", .type = UCI_TYPE_LIST }, + { .name = "al_bridge", .type = UCI_TYPE_STRING }, }; struct uci_option *tb[NUM_POLICIES]; @@ -1292,6 +1302,14 @@ static int agent_config_get_wifi_agent(struct agent_config *a, dbg("\n"); } + if (tb[A_AL_BRIDGE]) { + const char *iface; + + iface = tb[A_AL_BRIDGE]->v.string; + strncpy(a->al_bridge, iface, sizeof(a->al_bridge) - 1); + } else /* Default to br-lan if non-specfied */ + strncpy(a->al_bridge, "br-lan", sizeof(a->al_bridge) - 1); + return 0; } @@ -1798,7 +1816,7 @@ int config_generate_radio(struct agent_config *cfg, struct uci_context *ctx, } int config_generate_bsta_agent(struct agent_config *cfg, struct uci_context *ctx, - char *device, char *ifname, + const char *device, const char *ifname, uint8_t band) { struct uci_section *s; @@ -1907,7 +1925,7 @@ bool config_find_bsta_agent(struct agent_config *cfg, struct uci_context *ctx, } struct uci_section *config_find_bsta_wireless(struct agent_config *cfg, - struct uci_context *ctx, struct uci_package *pkg, char *device) + struct uci_context *ctx, struct uci_package *pkg, const char *device) { struct uci_element *e; int rv; @@ -2184,3 +2202,107 @@ int uci_set_bridge(char *config, char *bridge, char *proto, char *ipaddress) uci_free_context(ctx); return false; } + +int uci_add_dhcp(char *iface) +{ + struct uci_context *ctx = NULL; + struct uci_package *pkg; + struct uci_element *e; + struct uci_section *section = NULL; + struct uci_ptr ptr = {0}; + + /** if bridge starts with br prefix, step past */ + if (!strncmp(iface, "br-", 3)) + iface += 3; + + pkg = uci_load_pkg(&ctx, "dhcp"); + if (!pkg) + return -1; + + uci_foreach_element(&pkg->sections, e) { + struct uci_section *s = uci_to_section(e); + + if (strncmp(s->e.name, iface, 16)) + continue; + + trace("Existing section found for ifname %s\n", iface); + goto out; + } + + trace("Adding DHCP section for ifname %s\n", iface); + + ptr.p = pkg; + ptr.section = iface; + ptr.value = "dhcp"; + ptr.option = NULL; + uci_set(ctx, &ptr); + section = ptr.s; + + set_value(ctx, pkg, section, "interface", iface, UCI_TYPE_STRING); + set_value(ctx, pkg, section, "start", "100", UCI_TYPE_STRING); + set_value(ctx, pkg, section, "limit", "150", UCI_TYPE_STRING); + set_value(ctx, pkg, section, "leasetime", "1h", UCI_TYPE_STRING); + set_value(ctx, pkg, section, "dhcpv6", "server", UCI_TYPE_STRING); + set_value(ctx, pkg, section, "ra", "server", UCI_TYPE_STRING); + + uci_commit(ctx, &pkg, false); +out: + uci_unload(ctx, pkg); + uci_free_context(ctx); + return false; +} + +int uci_add_fw(struct agent_config *cfg, char *iface) +{ + struct uci_context *ctx = NULL; + struct uci_package *pkg; + struct uci_element *e; + struct uci_section *section = NULL; + int rv; + + /** if bridge starts with br prefix, step past */ + if (!strncmp(iface, "br-", 3)) + iface += 3; + + pkg = uci_load_pkg(&ctx, "firewall"); + if (!pkg) + return -1; + + section = config_get_section(ctx, pkg, "zone", "name", iface); + if (!section) { + trace("No fw section found for %s\n", iface); + rv = uci_add_section(ctx, pkg, "zone", §ion); + if (rv) + goto out_pkg; + + set_value(ctx, pkg, section, "name", iface, UCI_TYPE_STRING); + set_value(ctx, pkg, section, "network", iface, UCI_TYPE_LIST); + set_value(ctx, pkg, section, "input", "ACCEPT", UCI_TYPE_STRING); + set_value(ctx, pkg, section, "output", "ACCEPT", UCI_TYPE_STRING); + set_value(ctx, pkg, section, "forward", "ACCEPT", UCI_TYPE_STRING); + rv = uci_save(ctx, pkg); + if (rv) + goto out_pkg; + uci_commit(ctx, &pkg, false); + } + + section = config_get_section(ctx, pkg, "forwarding", "src", iface); + if (!section) { + //section = config_add_section(ctx, pkg, "firewall", "forwarding", "src", iface); + //if (!section) + // goto out; + rv = uci_add_section(ctx, pkg, "forwarding", §ion); + if (rv) + goto out_pkg; + + set_value(ctx, pkg, section, "src", iface, UCI_TYPE_STRING); + set_value(ctx, pkg, section, "dest", cfg->al_bridge, UCI_TYPE_STRING); + uci_commit(ctx, &pkg, false); + } + +out_pkg: + uci_unload(ctx, pkg); + uci_free_context(ctx); + return false; +} + diff --git a/src/core/config.h b/src/core/config.h index 1c8d3d64782b236dfa9f83e6368db69451c16e06..60844c767bb82c056c97ed0346032aa65415f3eb 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -157,6 +157,7 @@ struct agent_config { bool brcm_setup; bool configured; uint8_t cntlr_almac[6]; + char al_bridge[16]; struct policy_cfg *pcfg; /* policy section */ struct uloop_timeout metric_report_timer; @@ -166,7 +167,6 @@ struct agent_config { /** STAs excluded from BTM req steering; list of stax structs */ struct list_head steer_btm_excludelist; - }; #if 0 @@ -192,7 +192,7 @@ int set_value_by_string(const char *package, const char *section, const char *key, const char *value, enum uci_option_type type); struct uci_section *config_get_iface_section(struct uci_context *ctx, struct uci_package *pkg, const char *type, const char *ifname); -bool uci_reload_services(void); +bool uci_reload_services(char *services); struct uci_package *uci_load_pkg(struct uci_context **ctx, const char *config); int wifi_set_iface_bssid(const char *ifname, uint8_t *bssid); char *uci_get_bridge(char *ifname, char *bridge); @@ -239,14 +239,16 @@ int clean_all_bk(struct agent_config *cfg); void clean_fh(struct netif_fhcfg *p); int clean_all_fh(struct agent_config *cfg); -int uci_apply_m2(char *interface_name, char *device, uint8_t *ssid, - uint16_t auth_type, uint16_t encryption_type, +int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device, + uint8_t *ssid, uint16_t auth_type, uint16_t encryption_type, uint8_t *network_key, uint8_t mapie, uint8_t band, uint8_t *bridge, uint8_t *proto, uint8_t vid, uint32_t br_ip, - uint8_t *bk_ssid, uint8_t *bk_key); + uint8_t *bk_ssid, uint8_t *bk_key, bool onboaded); int uci_apply_wps_credentials(struct agent_config *cfg, enum wifi_band band); int wifi_reorder_interfaces_by_device(struct agent_config *a, struct uci_context *ctx, struct uci_package *pkg, char *device); int wifi_reorder_interfaces(struct agent_config *a); int uci_set_bridge(char *config, char *bridge, char *proto, char *ipaddress); +int uci_add_dhcp(char *interface); +int uci_add_fw(struct agent_config *cfg, char *interface); #endif diff --git a/src/utils/brcm_nl.c b/src/utils/brcm_nl.c index 80f1aea45697057286c6d4d8ae17109793d7ad44..1fc46cb3a3afbac7bd43e4227618cde845259494 100644 --- a/src/utils/brcm_nl.c +++ b/src/utils/brcm_nl.c @@ -65,12 +65,6 @@ int if_updown(const char *ifname, bool up) return 0; } -static bool get_bridge(char *ifname, char *bridge) -{ - strncpy(bridge, "br-lan", 15); - return true; -} - static int func(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); @@ -81,7 +75,7 @@ static int func(struct nl_msg *msg, void *arg) { struct ifinfomsg *ifi; char ifname[16] = {0}; - char bridge[16] = {0}; + char *bridge = (char *) arg; int ret; ifi = NLMSG_DATA(nlh); @@ -99,8 +93,8 @@ static int func(struct nl_msg *msg, void *arg) if (!strstr(ifname, "wds")) break; - if (!get_bridge(ifname, bridge)) - break; + + printf("Adding interface %s to bridge %s!\n", ifname, bridge); /* add wds iface to bridge */ ret = br_addif(bridge, ifname); @@ -124,7 +118,7 @@ static int func(struct nl_msg *msg, void *arg) return 0; } -int brcm_nl_loop(void) +int brcm_nl_loop(void *arg) { struct nl_sock *sk; @@ -134,7 +128,7 @@ int brcm_nl_loop(void) nl_socket_disable_seq_check(sk); - nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, func, NULL); + nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, func, arg); nl_connect(sk, NETLINK_ROUTE); nl_socket_add_memberships(sk, RTNLGRP_LINK, 0); diff --git a/src/utils/debug.c b/src/utils/debug.c index b2a320b939d78ed358bb617df077fdf0f1dabb86..061df0a5785187ce36f6c08849b1318874349ebc 100644 --- a/src/utils/debug.c +++ b/src/utils/debug.c @@ -196,8 +196,6 @@ void log_test(int level, void *var, int len) btostr(var, len, bstr); - printf("%s %d agent bstr = %s\n", __func__, __LINE__, bstr); - fprintf(testfile, "%s\n", bstr); fflush(testfile); free(bstr);