From e9e8ea7572e6f64aa19041685f4d0e642bf14e44 Mon Sep 17 00:00:00 2001 From: Jakob Olsson <jakob.olsson@iopsys.eu> Date: Tue, 23 Feb 2021 12:41:25 +0100 Subject: [PATCH] map-agent: add ethport event handler --- src/core/agent.c | 83 ++++++++++++++++++++++++++++++++++++++++------- src/core/agent.h | 1 + src/core/config.c | 38 ++++++++++++++++++++++ src/core/config.h | 9 +++++ 4 files changed, 120 insertions(+), 11 deletions(-) diff --git a/src/core/agent.c b/src/core/agent.c index 5df9bc35f..fc6797b53 100644 --- a/src/core/agent.c +++ b/src/core/agent.c @@ -1989,6 +1989,72 @@ static void agent_add_to_bridge(struct agent *a, char *ifname) } } +static void agent_disable_local_cntlr(struct agent *a) +{ + char pid[8] = {0}; + + /** 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); + } +} + +static void ethport_event_handler(void *agent, struct blob_attr *msg) +{ + char ifname[16] = {0}, link[8] = {0}; + struct agent *a = (struct agent *) agent; + struct blob_attr *tb[4]; + static const struct blobmsg_policy ev_attr[4] = { + [0] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, + [1] = { .name = "link", .type = BLOBMSG_TYPE_STRING }, + [2] = { .name = "speed", .type = BLOBMSG_TYPE_TABLE }, + [3] = { .name = "duplex", .type = BLOBMSG_TYPE_TABLE }, + }; + bool up, down; + + blobmsg_parse(ev_attr, 4, tb, blob_data(msg), blob_len(msg)); + + if (!tb[0] || !tb[1]) /* only need ifname and link status */ + return; + + strncpy(ifname, blobmsg_data(tb[0]), sizeof(ifname) - 1); + strncpy(link, blobmsg_data(tb[1]), sizeof(link) - 1); + + up = !strcmp(link, "up"); + down = !strcmp(link, "down"); + + if (up) { + int i; + + /* if is wan port getting a link up, active acs and do cntlr discovery*/ + if (!strncmp(a->ethwan, ifname, IFNAMSIZ)) { + if (a->cfg.discovery_proto == DISCOVERY_AUTOMATIC) + agent_disable_local_cntlr(a); + + dbg("|%s:%d| link up event received\n", __func__, + __LINE__); + + /** upon connecting to new network - allow radios to be + * reconfigured + */ + for (i = 0; i < a->num_radios; i++) { + dbg("|%s:%d| setting radio %s into active state\n", + __func__, __LINE__, a->radios[i].name); + a->radios[i].state = ACS_ACTIVE; + } + + uloop_timeout_set(&a->autocfg_dispatcher, 5 * 1000); + } + } else if (down) { + // TODO + } +} + static void wifi_bsta_event_handler(void *agent, struct blob_attr *msg) { char ifname[16] = {0}, event[16] = {0}, bssid_str[18] = {0}; @@ -2038,20 +2104,13 @@ static void wifi_bsta_event_handler(void *agent, struct blob_attr *msg) if (add) { int i; time_t now; - char pid[8] = {0}; time(&now); bk->connected = true; - /** 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); - } + if (a->cfg.discovery_proto == DISCOVERY_AUTOMATIC) + agent_disable_local_cntlr(a); dbg("|%s:%d| connect event received\n", __func__, __LINE__); @@ -2191,7 +2250,8 @@ static void ubus_wifi_event_handler(struct ubus_context *ctx, { "wifi.radio", wifi_radio_event_handler }, { "wifi.iface", wifi_iface_event_handler }, { "wps_credentials", wifi_wps_creds_event_handler }, - { "wifi.bsta", wifi_bsta_event_handler } + { "wifi.bsta", wifi_bsta_event_handler }, + { "ethport", ethport_event_handler } }; str = blobmsg_format_json(msg, true); @@ -3787,7 +3847,7 @@ int start_agent(void) ubus_add_uloop(ctx); agent_config_init(&w->cfg); - + agent_config_get_ethwan(w->ethwan); memcpy(w->cntlr_almac, w->cfg.cntlr_almac, 6); if (w->cfg.brcm_setup) { int ret; @@ -3825,6 +3885,7 @@ int start_agent(void) agent_init_interfaces(w); + ubus_register_event_handler(ctx, &w->wifi_evh, "ethport"); ubus_register_event_handler(ctx, &w->wifi_evh, "wifi.*"); ubus_register_event_handler(ctx, &w->wifi_evh, "wps_credentials"); ubus_register_event_handler(ctx, &w->ieee1905_evh, "ieee1905.*"); diff --git a/src/core/agent.h b/src/core/agent.h index 85f281ec8..f3bceea81 100644 --- a/src/core/agent.h +++ b/src/core/agent.h @@ -414,6 +414,7 @@ struct agent { int debug; uint8_t almac[6]; uint8_t cntlr_almac[6]; + char ethwan[16]; struct uloop_timeout heartbeat; struct uloop_timeout autocfg_dispatcher; struct list_head fhlist; diff --git a/src/core/config.c b/src/core/config.c index 05af1f4cc..34be6920c 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -281,6 +281,33 @@ out: return rv; } +char *agent_config_get_ethwan(char *ifname) +{ + struct uci_context *ctx; + struct uci_ptr ptr = {0}; + + ctx = uci_alloc_context(); + if (!ctx) + return NULL; + + //ptr.value = value; + ptr.package = "ports"; + ptr.section = "WAN"; + ptr.option = "ifname"; + ptr.target = UCI_TYPE_OPTION; + + if (uci_lookup_ptr(ctx, &ptr, NULL, false)) { + uci_free_context(ctx); + return NULL; + } + + strncpy(ifname, ptr.o->v.string, 15); + + uci_free_context(ctx); + return ifname; +} + + struct uci_section *config_add_section(struct uci_context *ctx, struct uci_package *pkg, const char *config, const char *type, const char *key, const char *value) @@ -1248,6 +1275,7 @@ static int agent_config_get_wifi_agent(struct agent_config *a, A_EXCLUDE_BTM, A_AL_BRIDGE, A_NETDEV, + A_DISCOVERY_PROTO, NUM_POLICIES }; const struct uci_parse_option opts[] = { @@ -1261,6 +1289,7 @@ static int agent_config_get_wifi_agent(struct agent_config *a, { .name = "exclude_btm", .type = UCI_TYPE_LIST }, { .name = "al_bridge", .type = UCI_TYPE_STRING }, { .name = "netdev", .type = UCI_TYPE_STRING }, + { .name = "discovery_proto", .type = UCI_TYPE_STRING } }; struct uci_option *tb[NUM_POLICIES]; @@ -1325,6 +1354,15 @@ static int agent_config_get_wifi_agent(struct agent_config *a, strncpy(a->netdev, (a->brcm_setup)?"wl":"wlan", sizeof(a->netdev) - 1); } + if (tb[A_DISCOVERY_PROTO]) { + const char *proto = tb[A_DISCOVERY_PROTO]->v.string; + + if (!strncmp(proto, "static", 6)) + a->discovery_proto = DISCOVERY_STATIC; + if (!strncmp(proto, "auto", 4)) /* defaults to auto */ + a->discovery_proto = DISCOVERY_AUTOMATIC; + } + return 0; } diff --git a/src/core/config.h b/src/core/config.h index 5594f026e..075058d43 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -143,6 +143,11 @@ struct agent_config_radio { struct list_head list; }; +enum discovery_protocol { + DISCOVERY_AUTOMATIC, /* controller will disable itself upon various network events */ + DISCOVERY_STATIC, /* controller shall not have any dynamic handling */ +}; + struct agent_config { bool enabled; int debug_level; @@ -168,6 +173,9 @@ struct agent_config { /** STAs excluded from BTM req steering; list of stax structs */ struct list_head steer_btm_excludelist; + + enum discovery_protocol discovery_proto; + }; #if 0 @@ -199,6 +207,7 @@ int wifi_set_iface_bssid(const char *ifname, uint8_t *bssid); char *uci_get_bridge(char *ifname, char *bridge); /* END TODO */ +char *agent_config_get_ethwan(char *ifname); int agent_config_init(struct agent_config *cfg); int agent_config_reload(struct agent_config *cfg); -- GitLab