diff options
author | rpaulo <rpaulo@FreeBSD.org> | 2010-02-08 20:23:20 +0000 |
---|---|---|
committer | rpaulo <rpaulo@FreeBSD.org> | 2010-02-08 20:23:20 +0000 |
commit | def28d2809f75a8ab70de810865728bc31f1c6cb (patch) | |
tree | 717679366c279bad9bce1f2d444f23607f8b3ebf | |
parent | 8fa59f844ebe44b567eb67de82c353348ddb4265 (diff) | |
download | FreeBSD-src-def28d2809f75a8ab70de810865728bc31f1c6cb.zip FreeBSD-src-def28d2809f75a8ab70de810865728bc31f1c6cb.tar.gz |
Add multicast key search support. This fixes corrupted mcast packets
when we have more than one hostap vap.
Submitted by: Russell Yount <russell.yount at gmail.com>
MFC after: 2 weeks
-rw-r--r-- | sys/dev/ath/if_ath.c | 35 | ||||
-rw-r--r-- | sys/dev/ath/if_athvar.h | 6 |
2 files changed, 30 insertions, 11 deletions
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index ed69a7d..d00d469 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -620,6 +620,13 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) sc->sc_wmetkipmic = 1; } sc->sc_hasclrkey = ath_hal_ciphersupported(ah, HAL_CIPHER_CLR); + /* + * Check for multicast key sarch support. + */ + if (ath_hal_hasmcastkeysearch(sc->sc_ah) && + !ath_hal_getmcastkeysearch(sc->sc_ah)) { + ath_hal_setmcastkeysearch(sc->sc_ah, 1); + } sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah); /* * Mark key cache slots associated with global keys @@ -2038,7 +2045,7 @@ ath_keyset(struct ath_softc *sc, const struct ieee80211_key *k, if ((k->wk_flags & IEEE80211_KEY_GROUP) && sc->sc_mcastkey) { /* * Group keys on hardware that supports multicast frame - * key search use a mac that is the sender's address with + * key search use a MAC that is the sender's address with * the high bit set instead of the app-specified address. */ IEEE80211_ADDR_COPY(gmac, bss->ni_macaddr); @@ -2218,8 +2225,10 @@ ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, * it permits us to support multiple users for adhoc and/or * multi-station operation. */ - if (k->wk_keyix != IEEE80211_KEYIX_NONE || /* global key */ - ((k->wk_flags & IEEE80211_KEY_GROUP) && !sc->sc_mcastkey)) { + if (k->wk_keyix != IEEE80211_KEYIX_NONE) { + /* + * Only global keys should have key index assigned. + */ if (!(&vap->iv_nw_keys[0] <= k && k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) { /* should not happen */ @@ -2227,12 +2236,22 @@ ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, "%s: bogus group key\n", __func__); return 0; } + */ + if (vap->iv_opmode != IEEE80211_M_HOSTAP || + !(k->wk_flags & IEEE80211_KEY_GROUP) || + !sc->sc_mcastkey) { + /* + * XXX we pre-allocate the global keys so + * have no way to check if they've already + * been allocated. + */ + *keyix = *rxkeyix = k - vap->iv_nw_keys; + return 1; + } /* - * XXX we pre-allocate the global keys so - * have no way to check if they've already been allocated. + * Group key and device supports multicast key search. */ - *keyix = *rxkeyix = k - vap->iv_nw_keys; - return 1; + k->wk_keyix = IEEE80211_KEYIX_NONE; } /* @@ -6944,6 +6963,8 @@ ath_announce(struct ath_softc *sc) if_printf(ifp, "using %u rx buffers\n", ath_rxbuf); if (ath_txbuf != ATH_TXBUF) if_printf(ifp, "using %u tx buffers\n", ath_txbuf); + if (sc->sc_mcastkey && bootverbose) + if_printf(ifp, "using multicast key search\n"); } #ifdef IEEE80211_SUPPORT_TDMA diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 29efc4c..31b1d4c 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -580,14 +580,12 @@ void ath_intr(void *); ath_hal_setcapability(_ah, HAL_CAP_TPC, 1, _v, NULL) #define ath_hal_hasbursting(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_BURST, 0, NULL) == HAL_OK) -#ifdef notyet +#define ath_hal_setmcastkeysearch(_ah, _v) \ + ath_hal_setcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, _v, NULL) #define ath_hal_hasmcastkeysearch(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, NULL) == HAL_OK) #define ath_hal_getmcastkeysearch(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 1, NULL) == HAL_OK) -#else -#define ath_hal_getmcastkeysearch(_ah) 0 -#endif #define ath_hal_hasfastframes(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_FASTFRAME, 0, NULL) == HAL_OK) #define ath_hal_hasbssidmask(_ah) \ |