PERFORCE change 146210 for review
Sam Leffler
sam at FreeBSD.org
Tue Jul 29 16:19:35 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=146210
Change 146210 by sam at 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 *);
More information about the p4-projects
mailing list