cfg80211: make action channel type optional
authorJohannes Berg <johannes@sipsolutions.net>
Wed, 19 May 2010 10:17:12 +0000 (12:17 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 2 Jun 2010 20:13:27 +0000 (16:13 -0400)
When sending action frames, we want to verify
that we do that on the correct channel. However,
checking the channel type in addition can get in
the way, since the channel type could change on
the fly during an association, and it's not
useful to have the channel type anyway since it
has no effect on the transmission. Therefore,
make it optional to specify so that if wanted,
it can still be checked, but is not required.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/net/cfg80211.h
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/wireless/core.h
net/wireless/mlme.c
net/wireless/nl80211.c

index 049e507d2f8274ace06760b743acfa774567d6f0..0c3c214772e77fa29066c66fbcc8b5eb58c19ab5 100644 (file)
@@ -1168,6 +1168,7 @@ struct cfg80211_ops {
        int     (*action)(struct wiphy *wiphy, struct net_device *dev,
                          struct ieee80211_channel *chan,
                          enum nl80211_channel_type channel_type,
+                         bool channel_type_valid,
                          const u8 *buf, size_t len, u64 *cookie);
 
        int     (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
index c7000a6ca379a2e206be38292dd550a39b396a17..f8c49c5ad8aaf2f4d4440c7761bc0bd5637b90c9 100644 (file)
@@ -1554,10 +1554,12 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
 static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
                            struct ieee80211_channel *chan,
                            enum nl80211_channel_type channel_type,
+                           bool channel_type_valid,
                            const u8 *buf, size_t len, u64 *cookie)
 {
        return ieee80211_mgd_action(IEEE80211_DEV_TO_SUB_IF(dev), chan,
-                                   channel_type, buf, len, cookie);
+                                   channel_type, channel_type_valid,
+                                   buf, len, cookie);
 }
 
 struct cfg80211_ops mac80211_config_ops = {
index 1a9e2da37a93d91320a6f20ec7594423e535da77..d4677efd3a36e02ea0eb5df2cba22e114484c288 100644 (file)
@@ -988,6 +988,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
 int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
                         struct ieee80211_channel *chan,
                         enum nl80211_channel_type channel_type,
+                        bool channel_type_valid,
                         const u8 *buf, size_t len, u64 *cookie);
 ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
                                          struct sk_buff *skb);
index 31e3386b8d43eb2fc18ace9ae3bc434f9c3c0d7a..29c3a75a7ad043cebe1ccce4d53c6edf03c3abd5 100644 (file)
@@ -2308,6 +2308,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
 int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
                         struct ieee80211_channel *chan,
                         enum nl80211_channel_type channel_type,
+                        bool channel_type_valid,
                         const u8 *buf, size_t len, u64 *cookie)
 {
        struct ieee80211_local *local = sdata->local;
@@ -2315,9 +2316,11 @@ int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
        struct sk_buff *skb;
 
        /* Check that we are on the requested channel for transmission */
-       if ((chan != local->tmp_channel ||
-            channel_type != local->tmp_channel_type) &&
-           (chan != local->oper_channel ||
+       if (chan != local->tmp_channel &&
+           chan != local->oper_channel)
+               return -EBUSY;
+       if (channel_type_valid &&
+           (channel_type != local->tmp_channel_type &&
             channel_type != local->_oper_channel_type))
                return -EBUSY;
 
index ae930acf75e9fb45bef945da23a0fdd1690e61f6..63d57ae399c3f9d73da4f2bf963867a6699af4c4 100644 (file)
@@ -339,6 +339,7 @@ int cfg80211_mlme_action(struct cfg80211_registered_device *rdev,
                         struct net_device *dev,
                         struct ieee80211_channel *chan,
                         enum nl80211_channel_type channel_type,
+                        bool channel_type_valid,
                         const u8 *buf, size_t len, u64 *cookie);
 
 /* SME */
index 48ead6f0426dc9763cc49819f7ac6e613aa36a76..f69ae19f497fc4b2ac44a5b0f6f18d1019ee065d 100644 (file)
@@ -827,6 +827,7 @@ int cfg80211_mlme_action(struct cfg80211_registered_device *rdev,
                         struct net_device *dev,
                         struct ieee80211_channel *chan,
                         enum nl80211_channel_type channel_type,
+                        bool channel_type_valid,
                         const u8 *buf, size_t len, u64 *cookie)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -855,7 +856,7 @@ int cfg80211_mlme_action(struct cfg80211_registered_device *rdev,
 
        /* Transmit the Action frame as requested by user space */
        return rdev->ops->action(&rdev->wiphy, dev, chan, channel_type,
-                                buf, len, cookie);
+                                channel_type_valid, buf, len, cookie);
 }
 
 bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf,
index db71150b8040d07d9590a8229b9070b7461d7279..90ab3c8519bec695f471e5d095fb1673e450b385 100644 (file)
@@ -4681,6 +4681,7 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info)
        struct net_device *dev;
        struct ieee80211_channel *chan;
        enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
+       bool channel_type_valid = false;
        u32 freq;
        int err;
        void *hdr;
@@ -4722,6 +4723,7 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info)
                        err = -EINVAL;
                        goto out;
                }
+               channel_type_valid = true;
        }
 
        freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
@@ -4745,6 +4747,7 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info)
                goto free_msg;
        }
        err = cfg80211_mlme_action(rdev, dev, chan, channel_type,
+                                  channel_type_valid,
                                   nla_data(info->attrs[NL80211_ATTR_FRAME]),
                                   nla_len(info->attrs[NL80211_ATTR_FRAME]),
                                   &cookie);