diff options
author | Jouni Malinen <j@w1.fi> | 2009-01-08 06:32:06 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 16:00:05 -0500 |
commit | fea147328908b7e2bfcaf9dc4377909d5507ca35 (patch) | |
tree | 4fa92b2ed01a5b4ec06d41b299606ed4546c09a1 /net | |
parent | fdfacf0ae2e8339098b1164d2317b792d7662c0a (diff) |
mac80211: 802.11w - SA Query processing
Process SA Query Requests for client mode in mac80211. AP side
processing of SA Query Response frames is in user space (hostapd).
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/rx.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index abc3aa583ca6..63db89aef3e4 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1667,6 +1667,57 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
1667 | return RX_CONTINUE; | 1667 | return RX_CONTINUE; |
1668 | } | 1668 | } |
1669 | 1669 | ||
1670 | void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, | ||
1671 | struct ieee80211_mgmt *mgmt, | ||
1672 | size_t len) | ||
1673 | { | ||
1674 | struct ieee80211_local *local = sdata->local; | ||
1675 | struct sk_buff *skb; | ||
1676 | struct ieee80211_mgmt *resp; | ||
1677 | |||
1678 | if (compare_ether_addr(mgmt->da, sdata->dev->dev_addr) != 0) { | ||
1679 | /* Not to own unicast address */ | ||
1680 | return; | ||
1681 | } | ||
1682 | |||
1683 | if (compare_ether_addr(mgmt->sa, sdata->u.sta.bssid) != 0 || | ||
1684 | compare_ether_addr(mgmt->bssid, sdata->u.sta.bssid) != 0) { | ||
1685 | /* Not from the current AP. */ | ||
1686 | return; | ||
1687 | } | ||
1688 | |||
1689 | if (sdata->u.sta.state == IEEE80211_STA_MLME_ASSOCIATE) { | ||
1690 | /* Association in progress; ignore SA Query */ | ||
1691 | return; | ||
1692 | } | ||
1693 | |||
1694 | if (len < 24 + 1 + sizeof(resp->u.action.u.sa_query)) { | ||
1695 | /* Too short SA Query request frame */ | ||
1696 | return; | ||
1697 | } | ||
1698 | |||
1699 | skb = dev_alloc_skb(sizeof(*resp) + local->hw.extra_tx_headroom); | ||
1700 | if (skb == NULL) | ||
1701 | return; | ||
1702 | |||
1703 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
1704 | resp = (struct ieee80211_mgmt *) skb_put(skb, 24); | ||
1705 | memset(resp, 0, 24); | ||
1706 | memcpy(resp->da, mgmt->sa, ETH_ALEN); | ||
1707 | memcpy(resp->sa, sdata->dev->dev_addr, ETH_ALEN); | ||
1708 | memcpy(resp->bssid, sdata->u.sta.bssid, ETH_ALEN); | ||
1709 | resp->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
1710 | IEEE80211_STYPE_ACTION); | ||
1711 | skb_put(skb, 1 + sizeof(resp->u.action.u.sa_query)); | ||
1712 | resp->u.action.category = WLAN_CATEGORY_SA_QUERY; | ||
1713 | resp->u.action.u.sa_query.action = WLAN_ACTION_SA_QUERY_RESPONSE; | ||
1714 | memcpy(resp->u.action.u.sa_query.trans_id, | ||
1715 | mgmt->u.action.u.sa_query.trans_id, | ||
1716 | WLAN_SA_QUERY_TR_ID_LEN); | ||
1717 | |||
1718 | ieee80211_tx_skb(sdata, skb, 1); | ||
1719 | } | ||
1720 | |||
1670 | static ieee80211_rx_result debug_noinline | 1721 | static ieee80211_rx_result debug_noinline |
1671 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | 1722 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) |
1672 | { | 1723 | { |
@@ -1743,6 +1794,24 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1743 | break; | 1794 | break; |
1744 | } | 1795 | } |
1745 | break; | 1796 | break; |
1797 | case WLAN_CATEGORY_SA_QUERY: | ||
1798 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
1799 | sizeof(mgmt->u.action.u.sa_query))) | ||
1800 | return RX_DROP_MONITOR; | ||
1801 | switch (mgmt->u.action.u.sa_query.action) { | ||
1802 | case WLAN_ACTION_SA_QUERY_REQUEST: | ||
1803 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | ||
1804 | return RX_DROP_MONITOR; | ||
1805 | ieee80211_process_sa_query_req(sdata, mgmt, len); | ||
1806 | break; | ||
1807 | case WLAN_ACTION_SA_QUERY_RESPONSE: | ||
1808 | /* | ||
1809 | * SA Query response is currently only used in AP mode | ||
1810 | * and it is processed in user space. | ||
1811 | */ | ||
1812 | return RX_CONTINUE; | ||
1813 | } | ||
1814 | break; | ||
1746 | default: | 1815 | default: |
1747 | return RX_CONTINUE; | 1816 | return RX_CONTINUE; |
1748 | } | 1817 | } |