On 2018/12/28 19:05, Peter Hessler wrote: > I gave this a spin, and seems to work in my testing. > > I did a few suspend/resumes, manual if down/up, forced a chan NN, and > walked around to do some roaming between 8 bssids. Recovery took a > short period of time, but was as expected. > > OK
I'm OK with committing and tweaking later, but ... > :++ for (offset = 0; offset < n;) { > :++ rtm = (struct rt_msghdr *)(rtmmsg + offset); > :++ > :++ if ((size_t)(n - offset) < sizeof(rtm->rtm_msglen) || > :++ (n - offset) < rtm->rtm_msglen || > :++ rtm->rtm_version != RTM_VERSION) > :++ goto done; > :++ offset += rtm->rtm_msglen; ... I'm pretty sure "rtm->rtm_version != RTM_VERSION" should "continue" as well. > :++ > :++ if (rtm->rtm_index != drv->ifindex) > :++ continue; > :++ > :++ switch (rtm->rtm_type) { > :++ case RTM_80211INFO: > :++ ifie = &((struct if_ieee80211_msghdr *)rtm)->ifim_ifie; > :++ wpa_driver_openbsd_rtmsg_80211(ifie, drv); > :++ break; > :++ case RTM_IFINFO: > :++ wpa_driver_openbsd_rtmsg_ifinfo(rtm, drv); > :++ break; > :++ default: > :++ wpa_printf(MSG_ERROR, "Unexpected route message of type" > :++ " %d received", rtm->rtm_type); > :++ break; > :++ } > :++ } > :++ > :++done: > :++ os_free(rtmmsg); > :++} > :++ > :++static void * > :++wpa_driver_openbsd_init(void *ctx, const char *ifname) { > :+ struct openbsd_driver_data *drv; > :++ unsigned int rtfilter = ROUTE_FILTER(RTM_80211INFO) | \ > :++ ROUTE_FILTER(RTM_IFINFO); > :+ > :+ drv = os_zalloc(sizeof(*drv)); > :+ if (drv == NULL) > :+@@ -103,9 +207,26 @@ wpa_driver_openbsd_init(void *ctx, const char *ifname) > :+ if (drv->sock < 0) > :+ goto fail; > :+ > :++ > :++ drv->rtsock = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC); > :++ if (drv->rtsock < 0) > :++ goto fail; > :++ if (setsockopt(drv->rtsock, PF_ROUTE, ROUTE_MSGFILTER, > :++ &rtfilter, sizeof(rtfilter)) == -1) > :++ goto fail; > :++ > :+ drv->ctx = ctx; > :+ os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); > :+ > :++ drv->ifindex = if_nametoindex(drv->ifname); > :++ if (drv->ifindex == 0) /* No interface with that name */ > :++ goto fail; > :++ > :++ drv->nwid_len = wpa_driver_openbsd_get_ssid(drv, drv->nwid); > :++ wpa_driver_openbsd_get_bssid(drv, drv->addr); > :++ > :++ eloop_register_read_sock(drv->rtsock, wpa_driver_openbsd_event_receive, > :++ NULL, drv); > :+ return drv; > :+ > :+ fail: > :+@@ -119,7 +240,11 @@ wpa_driver_openbsd_deinit(void *priv) > :+ { > :+ struct openbsd_driver_data *drv = priv; > :+ > :++ eloop_unregister_read_sock(drv->rtsock); > :++ > :+ close(drv->sock); > :++ close(drv->rtsock); > :++ > :+ os_free(drv); > :+ } > :+ > : > > -- > The camel has a single hump; > The dromedary two; > Or else the other way around. > I'm never sure. Are you? > -- Ogden Nash