diff options
-rw-r--r-- | include/net/ieee80211.h | 3 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_module.c | 2 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_rx.c | 5 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_wx.c | 13 |
4 files changed, 18 insertions, 5 deletions
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index 931737eec6c6..ef85a96fce49 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h | |||
@@ -851,6 +851,9 @@ struct ieee80211_device { | |||
851 | int host_encrypt; | 851 | int host_encrypt; |
852 | int host_encrypt_msdu; | 852 | int host_encrypt_msdu; |
853 | int host_decrypt; | 853 | int host_decrypt; |
854 | /* host performs multicast decryption */ | ||
855 | int host_mc_decrypt; | ||
856 | |||
854 | int host_open_frag; | 857 | int host_open_frag; |
855 | int ieee802_1x; /* is IEEE 802.1X used */ | 858 | int ieee802_1x; /* is IEEE 802.1X used */ |
856 | 859 | ||
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c index dddc61647390..941f1a13fafa 100644 --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c | |||
@@ -133,6 +133,8 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
133 | /* Default to enabling full open WEP with host based encrypt/decrypt */ | 133 | /* Default to enabling full open WEP with host based encrypt/decrypt */ |
134 | ieee->host_encrypt = 1; | 134 | ieee->host_encrypt = 1; |
135 | ieee->host_decrypt = 1; | 135 | ieee->host_decrypt = 1; |
136 | ieee->host_mc_decrypt = 1; | ||
137 | |||
136 | /* Host fragementation in Open mode. Default is enabled. | 138 | /* Host fragementation in Open mode. Default is enabled. |
137 | * Note: host fragmentation is always enabled if host encryption | 139 | * Note: host fragmentation is always enabled if host encryption |
138 | * is enabled. For cards can do hardware encryption, they must do | 140 | * is enabled. For cards can do hardware encryption, they must do |
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 8bcdbabae3a1..65315bcd6e0a 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c | |||
@@ -409,7 +409,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
409 | return 1; | 409 | return 1; |
410 | } | 410 | } |
411 | 411 | ||
412 | if (ieee->host_decrypt) { | 412 | if (is_multicast_ether_addr(hdr->addr1) ? ieee->host_mc_decrypt : |
413 | ieee->host_decrypt) { | ||
413 | int idx = 0; | 414 | int idx = 0; |
414 | if (skb->len >= hdrlen + 3) | 415 | if (skb->len >= hdrlen + 3) |
415 | idx = skb->data[hdrlen + 3] >> 6; | 416 | idx = skb->data[hdrlen + 3] >> 6; |
@@ -1066,7 +1067,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i | |||
1066 | network->flags = 0; | 1067 | network->flags = 0; |
1067 | network->atim_window = 0; | 1068 | network->atim_window = 0; |
1068 | network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ? | 1069 | network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ? |
1069 | 0x3 : 0x0; | 1070 | 0x3 : 0x0; |
1070 | 1071 | ||
1071 | if (stats->freq == IEEE80211_52GHZ_BAND) { | 1072 | if (stats->freq == IEEE80211_52GHZ_BAND) { |
1072 | /* for A band (No DS info) */ | 1073 | /* for A band (No DS info) */ |
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c index db66217699d5..d710f47c4bd5 100644 --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c | |||
@@ -493,6 +493,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee, | |||
493 | struct iw_point *encoding = &wrqu->encoding; | 493 | struct iw_point *encoding = &wrqu->encoding; |
494 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | 494 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; |
495 | int i, idx, ret = 0; | 495 | int i, idx, ret = 0; |
496 | int group_key = 0; | ||
496 | const char *alg, *module; | 497 | const char *alg, *module; |
497 | struct ieee80211_crypto_ops *ops; | 498 | struct ieee80211_crypto_ops *ops; |
498 | struct ieee80211_crypt_data **crypt; | 499 | struct ieee80211_crypt_data **crypt; |
@@ -509,9 +510,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee, | |||
509 | } else | 510 | } else |
510 | idx = ieee->tx_keyidx; | 511 | idx = ieee->tx_keyidx; |
511 | 512 | ||
512 | if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) | 513 | if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { |
513 | crypt = &ieee->crypt[idx]; | 514 | crypt = &ieee->crypt[idx]; |
514 | else { | 515 | group_key = 1; |
516 | } else { | ||
515 | if (idx != 0) | 517 | if (idx != 0) |
516 | return -EINVAL; | 518 | return -EINVAL; |
517 | if (ieee->iw_mode == IW_MODE_INFRA) | 519 | if (ieee->iw_mode == IW_MODE_INFRA) |
@@ -542,7 +544,9 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee, | |||
542 | sec.enabled = 1; | 544 | sec.enabled = 1; |
543 | sec.encrypt = 1; | 545 | sec.encrypt = 1; |
544 | 546 | ||
545 | if (!(ieee->host_encrypt || ieee->host_decrypt)) | 547 | if (group_key ? !ieee->host_mc_decrypt : |
548 | !(ieee->host_encrypt || ieee->host_decrypt || | ||
549 | ieee->host_encrypt_msdu)) | ||
546 | goto skip_host_crypt; | 550 | goto skip_host_crypt; |
547 | 551 | ||
548 | switch (ext->alg) { | 552 | switch (ext->alg) { |
@@ -632,6 +636,9 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee, | |||
632 | sec.flags |= SEC_LEVEL; | 636 | sec.flags |= SEC_LEVEL; |
633 | sec.level = SEC_LEVEL_3; | 637 | sec.level = SEC_LEVEL_3; |
634 | } | 638 | } |
639 | /* Don't set sec level for group keys. */ | ||
640 | if (group_key) | ||
641 | sec.flags &= ~SEC_LEVEL; | ||
635 | } | 642 | } |
636 | done: | 643 | done: |
637 | if (ieee->set_security) | 644 | if (ieee->set_security) |