From nobody Mon Aug 15 16:36:20 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4M60KK1bkkz4ZQxB; Mon, 15 Aug 2022 16:36:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4M60KK0RRSz3tks; Mon, 15 Aug 2022 16:36:21 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1660581381; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=UuEbp3wq4u82Y9VQcIvEABMmWYkgD9/Rv3qdGUTJcI8=; b=BL5FX9L7zBDn2OTaoDIzdqrSXKH8YWqUKJslcLUTbWNlsSmPeI3Q3sUYJsY4+zyWcuLnLW uYEi9XFqMd8F1y7fzEx6BsGMs8kbZwk+/vzoBmTpANqLbkw0xs8KFikzd+o6oyHJcdtqT7 om5ZMVfyVR1Y7mUyc0pOphwRxwWRPeOfKSPEM14Fx0NDH3diQqHx68N69C1WpVVMPSNy0c RrxxeddQcood0u4qkwlM5aEa6shvzHWs2zxq9YYwVTv4/GC7fWVaGDg09n0VGyPKeodaby oF80GuJLGUHMjYK68uLKf9+Qp7wJBwm9LM5IyHhmJipYmgrkJ46j8tvYo0c2rg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4M60KJ6LXJzcC6; Mon, 15 Aug 2022 16:36:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 27FGaKP2043515; Mon, 15 Aug 2022 16:36:20 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 27FGaKVK043514; Mon, 15 Aug 2022 16:36:20 GMT (envelope-from git) Date: Mon, 15 Aug 2022 16:36:20 GMT Message-Id: <202208151636.27FGaKVK043514@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Bjoern A. Zeeb" Subject: git: c0b65123d09c - main - wtap: Implement IBSS mode on wtap(4) List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bz X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c0b65123d09c735930c2915890de3b39055f4cc8 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1660581381; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=UuEbp3wq4u82Y9VQcIvEABMmWYkgD9/Rv3qdGUTJcI8=; b=DDQNlrQZjG6K+8QgK9j1/EZ/JVDvSQb8our+CdYSO4yVXWmYrkWUgHZ4p5lYltON1sCyes 9P+IDBTOG+MgBwv/AcEtKdLGeVUXB4BKgC+vy89tibFy9BwoDzOnBBoQwMado5FXNudEon 46uInjLxY0ElQlb1KN7V7VlmgD095NNDoBb4n6F2uyvIpXu4EE/wCit2r1s3y1TcHcLWlI X3wrjfT8BZ/NjmyET0kuQN0IcsEd1Cpc7xC6ymc5sK9eouFaJtecD5mwq9L4dgojUy9xQr pSzC+O6EYxVhTYiCccrZN6t0M36t2pifFiBdjzAeaawaj8B3A6u3Ueabt8L4pg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1660581381; a=rsa-sha256; cv=none; b=oLb2D+bw1sRqGGd8VJbTu9ouprcDvCl6ds/SSvLrQC2BQnEjj18rvKp0pXEuhU8ZN23q2V z0UwRqy40nh9nqrCsHi4EA1EpU0FRJerITEeMSiXax9Br0jGmCp//5xSLIl6saTG9ep64G Pp0UvFbqWqA0iluWsTWegWj9hjeZ6kOhiZ06Ia8KELF9hDk0HMrEUiMYMtkxcn54+BP4hi rAzy82ZSzPv14YNgTyCfuLzIOPgMFRpgFc1HWoIX3l+SM0OCU3Uh8B4pxEArbBBNpRFhQ8 Axw0mpePa6XfziXPL4G4s4zepqjoW5KTY0LDEc8uBCmrRdd6qE1oI73+4ZXv0A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=c0b65123d09c735930c2915890de3b39055f4cc8 commit c0b65123d09c735930c2915890de3b39055f4cc8 Author: En-Wei Wu AuthorDate: 2022-08-15 16:21:15 +0000 Commit: Bjoern A. Zeeb CommitDate: 2022-08-15 16:35:36 +0000 wtap: Implement IBSS mode on wtap(4) For TSF and beacon generation, each STA has to start its local TSF timer and sends beacon frames when it reaches the state IEEE80211_S_RUN. The TSF timer will be used for IBSS merge and beacon frame transmission. The TSF timer is kept in the HAL of wtap(4). It is working by continuously updating its value on timer interrupt simulated by callout_reset(). When receiving beacons, the STA will be merged into the IBSS if - the STA has the same SSID as the beacon sender - the STA's TSF timer is smaller than the beacon sender's TSF timer. After the merging process, the younger STA will be in the IBSS created by the older STA and the younger STA stops sending beacon frames. So beacon frames will always be sent by the oldest STA in IBSS. Sponsored by: Google, Inc. (GSoC 2022) Reviewed By: lwhsu, adrian Differential Revision: https://reviews.freebsd.org/D35841 --- sys/dev/wtap/if_wtap.c | 78 ++++++++++++++++++++++++++++++++++++++++++--- sys/dev/wtap/if_wtapvar.h | 1 + sys/dev/wtap/wtap_hal/hal.c | 34 ++++++++++++++++++++ sys/dev/wtap/wtap_hal/hal.h | 11 +++++++ 4 files changed, 120 insertions(+), 4 deletions(-) diff --git a/sys/dev/wtap/if_wtap.c b/sys/dev/wtap/if_wtap.c index 214f9f739407..4e05c70b53fa 100644 --- a/sys/dev/wtap/if_wtap.c +++ b/sys/dev/wtap/if_wtap.c @@ -41,6 +41,7 @@ #include #include "if_medium.h" +#include "wtap_hal/hal.h" /* * This _requires_ vimage to be useful. @@ -149,10 +150,39 @@ wtap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, const struct ieee80211_rx_stats *stats, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; + struct wtap_softc *sc = vap->iv_ic->ic_softc; #if 0 DWTAP_PRINTF("[%d] %s\n", myath_id(ni), __func__); #endif + /* + * Call up first so subsequent work can use information + * potentially stored in the node (e.g. for ibss merge). + */ WTAP_VAP(vap)->av_recv_mgmt(ni, m, subtype, stats, rssi, nf); + + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_BEACON: + case IEEE80211_FC0_SUBTYPE_PROBE_RESP: + if (vap->iv_opmode == IEEE80211_M_IBSS && + vap->iv_state == IEEE80211_S_RUN && + ieee80211_ibss_merge_check(ni)) { + uint64_t tsf = wtap_hal_get_tsf(sc->hal); + + /* + * Handle ibss merge as needed; check the tsf on the + * frame before attempting the merge. The 802.11 spec + * says the station should change it's bssid to match + * the oldest station with the same ssid, where oldest + * is determined by the tsf. Note that hardware + * reconfiguration happens through callback to + * ath_newstate as the state machine will go from + * RUN -> RUN when this happens. + */ + if (le64toh(ni->ni_tstamp.tsf) >= tsf) + (void) ieee80211_ibss_merge(ni); + } + break; + } } static int @@ -193,7 +223,6 @@ wtap_beacon_alloc(struct wtap_softc *sc, struct ieee80211_node *ni) printf("%s: cannot get mbuf\n", __func__); return ENOMEM; } - callout_init(&avp->av_swba, 0); avp->bf_node = ieee80211_ref_node(ni); return 0; @@ -202,7 +231,6 @@ wtap_beacon_alloc(struct wtap_softc *sc, struct ieee80211_node *ni) static void wtap_beacon_config(struct wtap_softc *sc, struct ieee80211vap *vap) { - DWTAP_PRINTF("%s\n", __func__); } @@ -211,7 +239,10 @@ wtap_beacon_intrp(void *arg) { struct wtap_vap *avp = arg; struct ieee80211vap *vap = arg; + struct wtap_softc *sc = vap->iv_ic->ic_softc; + struct ieee80211_frame *wh; struct mbuf *m; + uint64_t tsf; if (vap->iv_state < IEEE80211_S_RUN) { DWTAP_PRINTF("Skip beacon, not running, state %d", vap->iv_state); @@ -230,6 +261,11 @@ wtap_beacon_intrp(void *arg) " changed size.\n",__func__); } + /* Get TSF from HAL, and insert it into beacon frame */ + tsf = wtap_hal_get_tsf(sc->hal); + wh = mtod(m, struct ieee80211_frame *); + memcpy(&wh[1], &tsf, sizeof(tsf)); + if (ieee80211_radiotap_active_vap(vap)) ieee80211_radiotap_tx(vap, m); @@ -264,11 +300,37 @@ wtap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) ieee80211_free_node(ni); ni = ieee80211_ref_node(vap->iv_bss); switch (vap->iv_opmode) { + case IEEE80211_M_IBSS: case IEEE80211_M_MBSS: + /* + * Stop any previous beacon callout. This may be + * necessary, for example, when an ibss merge + * causes reconfiguration; there will be a state + * transition from RUN->RUN that means we may + * be called with beacon transmission active. + */ + callout_stop(&avp->av_swba); + error = wtap_beacon_alloc(sc, ni); if (error != 0) goto bad; + + /* + * If joining an adhoc network defer beacon timer + * configuration to the next beacon frame so we + * have a current TSF to use. Otherwise we're + * starting an ibss/bss so there's no need to delay; + * if this is the first vap moving to RUN state, then + * beacon state needs to be [re]configured. + */ + if (vap->iv_opmode == IEEE80211_M_IBSS && + ni->ni_tstamp.tsf != 0) + break; + wtap_beacon_config(sc, vap); + + /* Start TSF timer from now, and start s/w beacon alert */ + wtap_hal_reset_tsf(sc->hal); callout_reset(&avp->av_swba, avp->av_bcinterval, wtap_beacon_intrp, vap); break; @@ -314,7 +376,7 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], avp->av_md = sc->sc_md; avp->av_bcinterval = msecs_to_ticks(BEACON_INTRERVAL + 100*sc->id); vap = (struct ieee80211vap *) avp; - error = ieee80211_vap_setup(ic, vap, name, unit, IEEE80211_M_MBSS, + error = ieee80211_vap_setup(ic, vap, name, unit, opmode, flags | IEEE80211_CLONE_NOBEACONS, bssid); if (error) { free(avp, M_80211_VAP); @@ -337,6 +399,7 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], avp->av_dev = make_dev(&wtap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "%s", (const char *)vap->iv_ifp->if_xname); avp->av_dev->si_drv1 = sc; + callout_init(&avp->av_swba, 0); /* TODO this is a hack to force it to choose the rate we want */ ni = ieee80211_ref_node(vap->iv_bss); @@ -460,6 +523,13 @@ wtap_rx_proc(void *arg, int npending) free(bf, M_WTAP_RXBUF); return; } + + /* + * It's weird to do this, but sometimes wtap will + * receive AMPDU packets (like ping(8)) even when + * the ic does not supports 11n HT. + */ + m->m_flags &= ~M_AMPDU; #if 0 ieee80211_dump_pkt(ic, mtod(m, caddr_t), 0,0,0); #endif @@ -585,7 +655,7 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr) ic->ic_name = sc->name; ic->ic_phytype = IEEE80211_T_DS; ic->ic_opmode = IEEE80211_M_MBSS; - ic->ic_caps = IEEE80211_C_MBSS; + ic->ic_caps = IEEE80211_C_MBSS | IEEE80211_C_IBSS; ic->ic_max_keyix = 128; /* A value read from Atheros ATH_KEYMAX */ diff --git a/sys/dev/wtap/if_wtapvar.h b/sys/dev/wtap/if_wtapvar.h index 966704cc481e..1a0983521f4e 100644 --- a/sys/dev/wtap/if_wtapvar.h +++ b/sys/dev/wtap/if_wtapvar.h @@ -134,6 +134,7 @@ struct wtap_softc { int32_t id; int32_t up; struct wtap_medium *sc_md; /* interface medium */ + struct wtap_hal *hal; struct ieee80211_node* (* sc_node_alloc) (struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN]); void (*sc_node_free)(struct ieee80211_node *); diff --git a/sys/dev/wtap/wtap_hal/hal.c b/sys/dev/wtap/wtap_hal/hal.c index 5bdcc40c9ccb..31f705d98e61 100644 --- a/sys/dev/wtap/wtap_hal/hal.c +++ b/sys/dev/wtap/wtap_hal/hal.c @@ -73,6 +73,9 @@ init_hal(struct wtap_hal *hal) init_medium(hal->hal_md); /* register event handler for packets */ TASK_INIT(&hal->hal_md->tx_handler->proc, 0, hal_tx_proc, hal); + + callout_init_mtx(&hal->hw.timer_intr, &hal->hal_mtx, 0); + hal->hw.timer_intr_intval = msecs_to_ticks(HAL_TIMER_INTVAL); } void @@ -182,6 +185,7 @@ new_wtap(struct wtap_hal *hal, int32_t id) sizeof(struct wtap_softc), M_WTAP, M_NOWAIT | M_ZERO); hal->hal_devs[id]->sc_md = hal->hal_md; hal->hal_devs[id]->id = id; + hal->hal_devs[id]->hal = hal; snprintf(hal->hal_devs[id]->name, sizeof(hal->hal_devs[id]->name), "wtap%d", id); mtx_init(&hal->hal_devs[id]->sc_mtx, "wtap_softc mtx", NULL, @@ -212,3 +216,33 @@ free_wtap(struct wtap_hal *hal, int32_t id) hal->hal_devs[id] = NULL; return 0; } + +void +wtap_hal_timer_intr(void *arg) +{ + struct wtap_hal *hal = arg; + uint32_t intval = hal->hw.timer_intr_intval; + + hal->hw.tsf += ticks_to_msecs(intval); + + callout_schedule(&hal->hw.timer_intr, intval); +} + +void +wtap_hal_reset_tsf(struct wtap_hal *hal) +{ + mtx_lock(&hal->hal_mtx); + + callout_stop(&hal->hw.timer_intr); + hal->hw.tsf = 0; + callout_reset(&hal->hw.timer_intr, hal->hw.timer_intr_intval, + wtap_hal_timer_intr, hal); + + mtx_unlock(&hal->hal_mtx); +} + +uint64_t +wtap_hal_get_tsf(struct wtap_hal *hal) +{ + return (hal->hw.tsf); +} diff --git a/sys/dev/wtap/wtap_hal/hal.h b/sys/dev/wtap/wtap_hal/hal.h index 8446bdbcdd1a..9dc05b566b79 100644 --- a/sys/dev/wtap/wtap_hal/hal.h +++ b/sys/dev/wtap/wtap_hal/hal.h @@ -38,11 +38,19 @@ #include "../plugins/wtap_plugin.h" #include "handler.h" +#define HAL_TIMER_INTVAL 50 /* in msecs */ + struct wtap_hal { struct wtap_medium *hal_md; struct mtx hal_mtx; struct wtap_plugin *plugin; struct wtap_softc *hal_devs[MAX_NBR_WTAP]; + /* hardware information */ + struct hw { + struct callout timer_intr; + uint32_t timer_intr_intval; + uint64_t tsf; + } hw; }; void init_hal(struct wtap_hal *); @@ -51,5 +59,8 @@ void register_plugin(struct wtap_hal *, struct wtap_plugin *); void deregister_plugin(struct wtap_hal *); int32_t new_wtap(struct wtap_hal *, int32_t id); int32_t free_wtap(struct wtap_hal *, int32_t id); +void wtap_hal_timer_intr(void *); +void wtap_hal_reset_tsf(struct wtap_hal *); +uint64_t wtap_hal_get_tsf(struct wtap_hal *); #endif