Date: Tue, 29 Jul 2008 16:19:34 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 146210 for review Message-ID: <200807291619.m6TGJYed041739@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=146210 Change 146210 by sam@sam_ebb on 2008/07/29 16:19:17 Change callback api to allocate driver resources for a crypto key: o de-const the key parameter so drivers can muck with the flags o on callback failure don't automatically try to setup s/w crypto; instead the driver must now mark the key entry for s/w crypto and the caller will re-attach the cipher module o update drivers to match new api This change is experimental. It permits drivers more control over fallback to s/w crypto (e.g. based on a limited number of h/w key slots). Affected files ... .. //depot/projects/vap/sys/dev/ath/if_ath.c#88 edit .. //depot/projects/vap/sys/dev/mwl/if_mwl.c#12 edit .. //depot/projects/vap/sys/net80211/ieee80211_crypto.c#19 edit .. //depot/projects/vap/sys/net80211/ieee80211_var.h#48 edit Differences ... ==== //depot/projects/vap/sys/dev/ath/if_ath.c#88 (text+ko) ==== @@ -135,7 +135,7 @@ static int ath_keyset(struct ath_softc *, const struct ieee80211_key *, struct ieee80211_node *); static int ath_key_alloc(struct ieee80211vap *, - const struct ieee80211_key *, + struct ieee80211_key *, ieee80211_keyix *, ieee80211_keyix *); static int ath_key_delete(struct ieee80211vap *, const struct ieee80211_key *); @@ -2397,7 +2397,7 @@ * 64 entries. */ static int -ath_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *k, +ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; ==== //depot/projects/vap/sys/dev/mwl/if_mwl.c#12 (text+ko) ==== @@ -117,7 +117,7 @@ static void mwl_chanswitch_proc(void *, int); static void mwl_bawatchdog_proc(void *, int); static int mwl_key_alloc(struct ieee80211vap *, - const struct ieee80211_key *, + struct ieee80211_key *, ieee80211_keyix *, ieee80211_keyix *); static int mwl_key_delete(struct ieee80211vap *, const struct ieee80211_key *); @@ -1884,11 +1884,11 @@ /* * Allocate a key cache slot for a unicast key. The - * firmware handles key allocation so we just return - * whatever is needed to keep the net80211 layer happy. + * firmware handles key allocation and every station is + * guaranteed key space so we are always successful. */ static int -mwl_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *k, +mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; @@ -1905,8 +1905,7 @@ *keyix = *rxkeyix = k - vap->iv_nw_keys; } else { /* - * Firmware handles key allocation; just set this to - * something so the upper layers are happy. + * Firmware handles key allocation. */ *keyix = *rxkeyix = 0; } ==== //depot/projects/vap/sys/net80211/ieee80211_crypto.c#19 (text+ko) ==== @@ -59,7 +59,7 @@ * Default "null" key management routines. */ static int -null_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *k, +null_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { if (!(&vap->iv_nw_keys[0] <= k && @@ -116,7 +116,7 @@ */ static __inline int dev_key_alloc(struct ieee80211vap *vap, - const struct ieee80211_key *key, + struct ieee80211_key *key, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { return vap->iv_key_alloc(vap, key, keyix, rxkeyix); @@ -335,15 +335,11 @@ * whether or not it needs to do the cipher work. */ if (key->wk_cipher != cip || key->wk_flags != flags) { -again: /* * Fillin the flags so cipher modules can see s/w * crypto requirements and potentially allocate * different state and/or attach different method * pointers. - * - * XXX this is not right when s/w crypto fallback - * fails and we try to restore previous state. */ key->wk_flags = flags; keyctx = cip->ic_attach(vap, key); @@ -375,31 +371,39 @@ if ((key->wk_flags & IEEE80211_KEY_DEVKEY) == 0) { if (!dev_key_alloc(vap, key, &keyix, &rxkeyix)) { /* - * Driver has no room; fallback to doing crypto - * in the host. We change the flags and start the - * procedure over. If we get back here then there's - * no hope and we bail. Note that this can leave - * the key in a inconsistent state if the caller - * continues to use it. + * Unable to setup driver state. */ - if ((key->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { - vap->iv_stats.is_crypto_swfallback++; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: no h/w resources for cipher %s, " - "falling back to s/w\n", __func__, - cip->ic_name); - oflags = key->wk_flags; - flags |= IEEE80211_KEY_SWCRYPT; - if (cipher == IEEE80211_CIPHER_TKIP) - flags |= IEEE80211_KEY_SWMIC; - goto again; - } vap->iv_stats.is_crypto_keyfail++; IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: unable to setup cipher %s\n", __func__, cip->ic_name); return 0; } + if (key->wk_flags != flags) { + /* + * Driver overrode flags we setup; typically because + * resources were unavailable to handle _this_ key. + * Re-attach the cipher context to allow cipher + * modules to handle differing requirements. + */ + IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, + "%s: driver override for cipher %s, flags " + "0x%x -> 0x%x\n", __func__, cip->ic_name, + oflags, key->wk_flags); + keyctx = cip->ic_attach(vap, key); + if (keyctx == NULL) { + IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, + "%s: unable to attach cipher %s with " + "flags 0x%x\n", __func__, cip->ic_name, + key->wk_flags); + key->wk_flags = oflags; /* restore old flags */ + vap->iv_stats.is_crypto_attachfail++; + return 0; + } + cipher_detach(key); + key->wk_cipher = cip; /* XXX refcnt? */ + key->wk_private = keyctx; + } key->wk_keyix = keyix; key->wk_rxkeyix = rxkeyix; key->wk_flags |= IEEE80211_KEY_DEVKEY; ==== //depot/projects/vap/sys/net80211/ieee80211_var.h#48 (text+ko) ==== @@ -370,7 +370,7 @@ ieee80211_keyix iv_def_txkey; /* default/group tx key index */ struct ieee80211_key iv_nw_keys[IEEE80211_WEP_NKID]; int (*iv_key_alloc)(struct ieee80211vap *, - const struct ieee80211_key *, + struct ieee80211_key *, ieee80211_keyix *, ieee80211_keyix *); int (*iv_key_delete)(struct ieee80211vap *, const struct ieee80211_key *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807291619.m6TGJYed041739>