Commit 65fc73ac authored by Jouni Malinen's avatar Jouni Malinen Committed by John W. Linville

nl80211: Remove NL80211_CMD_SET_MGMT_EXTRA_IE

The functionality that NL80211_CMD_SET_MGMT_EXTRA_IE provided can now
be achieved with cleaner design by adding IE(s) into
NL80211_CMD_TRIGGER_SCAN, NL80211_CMD_AUTHENTICATE,
NL80211_CMD_ASSOCIATE, NL80211_CMD_DEAUTHENTICATE, and
NL80211_CMD_DISASSOCIATE.

Since this is a very recently added command and there are no known (or
known planned) applications using NL80211_CMD_SET_MGMT_EXTRA_IE and
taken into account how much extra complexity it adds to the IE
processing we have now (and need to add in the future to fix IE order
in couple of frames), it looks like the best option is to just remove
the implementation of this command for now. The enum values themselves
are left to avoid changing the nl80211 command or attribute numbers.
Signed-off-by: default avatarJouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent feeb4445
...@@ -142,6 +142,12 @@ ...@@ -142,6 +142,12 @@
* %NL80211_ATTR_IE. If the command succeeds, the requested data will be * %NL80211_ATTR_IE. If the command succeeds, the requested data will be
* added to all specified management frames generated by * added to all specified management frames generated by
* kernel/firmware/driver. * kernel/firmware/driver.
* Note: This command has been removed and it is only reserved at this
* point to avoid re-using existing command number. The functionality this
* command was planned for has been provided with cleaner design with the
* option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN,
* NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE,
* NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE.
* *
* @NL80211_CMD_GET_SCAN: get scan results * @NL80211_CMD_GET_SCAN: get scan results
* @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
...@@ -238,7 +244,7 @@ enum nl80211_commands { ...@@ -238,7 +244,7 @@ enum nl80211_commands {
NL80211_CMD_GET_MESH_PARAMS, NL80211_CMD_GET_MESH_PARAMS,
NL80211_CMD_SET_MESH_PARAMS, NL80211_CMD_SET_MESH_PARAMS,
NL80211_CMD_SET_MGMT_EXTRA_IE, NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
NL80211_CMD_GET_REG, NL80211_CMD_GET_REG,
......
...@@ -471,26 +471,6 @@ struct ieee80211_txq_params { ...@@ -471,26 +471,6 @@ struct ieee80211_txq_params {
u8 aifs; u8 aifs;
}; };
/**
* struct mgmt_extra_ie_params - Extra management frame IE parameters
*
* Used to add extra IE(s) into management frames. If the driver cannot add the
* requested data into all management frames of the specified subtype that are
* generated in kernel or firmware/hardware, it must reject the configuration
* call. The IE data buffer is added to the end of the specified management
* frame body after all other IEs. This addition is not applied to frames that
* are injected through a monitor interface.
*
* @subtype: Management frame subtype
* @ies: IE data buffer or %NULL to remove previous data
* @ies_len: Length of @ies in octets
*/
struct mgmt_extra_ie_params {
u8 subtype;
u8 *ies;
int ies_len;
};
/* from net/wireless.h */ /* from net/wireless.h */
struct wiphy; struct wiphy;
...@@ -743,8 +723,6 @@ struct cfg80211_disassoc_request { ...@@ -743,8 +723,6 @@ struct cfg80211_disassoc_request {
* *
* @set_channel: Set channel * @set_channel: Set channel
* *
* @set_mgmt_extra_ie: Set extra IE data for management frames
*
* @scan: Request to do a scan. If returning zero, the scan request is given * @scan: Request to do a scan. If returning zero, the scan request is given
* the driver, and will be valid until passed to cfg80211_scan_done(). * the driver, and will be valid until passed to cfg80211_scan_done().
* For scan results, call cfg80211_inform_bss(); you can call this outside * For scan results, call cfg80211_inform_bss(); you can call this outside
...@@ -828,10 +806,6 @@ struct cfg80211_ops { ...@@ -828,10 +806,6 @@ struct cfg80211_ops {
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type); enum nl80211_channel_type channel_type);
int (*set_mgmt_extra_ie)(struct wiphy *wiphy,
struct net_device *dev,
struct mgmt_extra_ie_params *params);
int (*scan)(struct wiphy *wiphy, struct net_device *dev, int (*scan)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_scan_request *request); struct cfg80211_scan_request *request);
......
...@@ -1181,91 +1181,6 @@ static int ieee80211_set_channel(struct wiphy *wiphy, ...@@ -1181,91 +1181,6 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
} }
static int set_mgmt_extra_ie_sta(struct ieee80211_sub_if_data *sdata,
u8 subtype, u8 *ies, size_t ies_len)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
switch (subtype) {
case IEEE80211_STYPE_PROBE_REQ >> 4:
if (local->ops->hw_scan)
break;
kfree(ifmgd->ie_probereq);
ifmgd->ie_probereq = ies;
ifmgd->ie_probereq_len = ies_len;
return 0;
case IEEE80211_STYPE_PROBE_RESP >> 4:
kfree(ifmgd->ie_proberesp);
ifmgd->ie_proberesp = ies;
ifmgd->ie_proberesp_len = ies_len;
return 0;
case IEEE80211_STYPE_AUTH >> 4:
kfree(ifmgd->ie_auth);
ifmgd->ie_auth = ies;
ifmgd->ie_auth_len = ies_len;
return 0;
case IEEE80211_STYPE_ASSOC_REQ >> 4:
kfree(ifmgd->ie_assocreq);
ifmgd->ie_assocreq = ies;
ifmgd->ie_assocreq_len = ies_len;
return 0;
case IEEE80211_STYPE_REASSOC_REQ >> 4:
kfree(ifmgd->ie_reassocreq);
ifmgd->ie_reassocreq = ies;
ifmgd->ie_reassocreq_len = ies_len;
return 0;
case IEEE80211_STYPE_DEAUTH >> 4:
kfree(ifmgd->ie_deauth);
ifmgd->ie_deauth = ies;
ifmgd->ie_deauth_len = ies_len;
return 0;
case IEEE80211_STYPE_DISASSOC >> 4:
kfree(ifmgd->ie_disassoc);
ifmgd->ie_disassoc = ies;
ifmgd->ie_disassoc_len = ies_len;
return 0;
}
return -EOPNOTSUPP;
}
static int ieee80211_set_mgmt_extra_ie(struct wiphy *wiphy,
struct net_device *dev,
struct mgmt_extra_ie_params *params)
{
struct ieee80211_sub_if_data *sdata;
u8 *ies;
size_t ies_len;
int ret = -EOPNOTSUPP;
if (params->ies) {
ies = kmemdup(params->ies, params->ies_len, GFP_KERNEL);
if (ies == NULL)
return -ENOMEM;
ies_len = params->ies_len;
} else {
ies = NULL;
ies_len = 0;
}
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
ret = set_mgmt_extra_ie_sta(sdata, params->subtype,
ies, ies_len);
break;
default:
ret = -EOPNOTSUPP;
break;
}
if (ret)
kfree(ies);
return ret;
}
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int ieee80211_suspend(struct wiphy *wiphy) static int ieee80211_suspend(struct wiphy *wiphy)
{ {
...@@ -1465,7 +1380,6 @@ struct cfg80211_ops mac80211_config_ops = { ...@@ -1465,7 +1380,6 @@ struct cfg80211_ops mac80211_config_ops = {
.change_bss = ieee80211_change_bss, .change_bss = ieee80211_change_bss,
.set_txq_params = ieee80211_set_txq_params, .set_txq_params = ieee80211_set_txq_params,
.set_channel = ieee80211_set_channel, .set_channel = ieee80211_set_channel,
.set_mgmt_extra_ie = ieee80211_set_mgmt_extra_ie,
.suspend = ieee80211_suspend, .suspend = ieee80211_suspend,
.resume = ieee80211_resume, .resume = ieee80211_resume,
.scan = ieee80211_scan, .scan = ieee80211_scan,
......
...@@ -323,21 +323,6 @@ struct ieee80211_if_managed { ...@@ -323,21 +323,6 @@ struct ieee80211_if_managed {
int wmm_last_param_set; int wmm_last_param_set;
/* Extra IE data for management frames */ /* Extra IE data for management frames */
u8 *ie_probereq;
size_t ie_probereq_len;
u8 *ie_proberesp;
size_t ie_proberesp_len;
u8 *ie_auth;
size_t ie_auth_len;
u8 *ie_assocreq;
size_t ie_assocreq_len;
u8 *ie_reassocreq;
size_t ie_reassocreq_len;
u8 *ie_deauth;
size_t ie_deauth_len;
u8 *ie_disassoc;
size_t ie_disassoc_len;
u8 *sme_auth_ie; u8 *sme_auth_ie;
size_t sme_auth_ie_len; size_t sme_auth_ie_len;
}; };
......
...@@ -653,13 +653,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev) ...@@ -653,13 +653,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
kfree(sdata->u.mgd.extra_ie); kfree(sdata->u.mgd.extra_ie);
kfree(sdata->u.mgd.assocreq_ies); kfree(sdata->u.mgd.assocreq_ies);
kfree(sdata->u.mgd.assocresp_ies); kfree(sdata->u.mgd.assocresp_ies);
kfree(sdata->u.mgd.ie_probereq);
kfree(sdata->u.mgd.ie_proberesp);
kfree(sdata->u.mgd.ie_auth);
kfree(sdata->u.mgd.ie_assocreq);
kfree(sdata->u.mgd.ie_reassocreq);
kfree(sdata->u.mgd.ie_deauth);
kfree(sdata->u.mgd.ie_disassoc);
kfree(sdata->u.mgd.sme_auth_ie); kfree(sdata->u.mgd.sme_auth_ie);
break; break;
case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_WDS:
......
...@@ -82,38 +82,23 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss, ...@@ -82,38 +82,23 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
/* frame sending functions */ /* frame sending functions */
static void add_extra_ies(struct sk_buff *skb, u8 *ies, size_t ies_len)
{
if (ies)
memcpy(skb_put(skb, ies_len), ies, ies_len);
}
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
{ {
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_mgmt *mgmt; struct ieee80211_mgmt *mgmt;
u8 *pos, *ies, *ht_ie, *e_ies; u8 *pos, *ies, *ht_ie;
int i, len, count, rates_len, supp_rates_len; int i, len, count, rates_len, supp_rates_len;
u16 capab; u16 capab;
struct ieee80211_bss *bss; struct ieee80211_bss *bss;
int wmm = 0; int wmm = 0;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
u32 rates = 0; u32 rates = 0;
size_t e_ies_len;
if (ifmgd->flags & IEEE80211_STA_PREV_BSSID_SET) {
e_ies = sdata->u.mgd.ie_reassocreq;
e_ies_len = sdata->u.mgd.ie_reassocreq_len;
} else {
e_ies = sdata->u.mgd.ie_assocreq;
e_ies_len = sdata->u.mgd.ie_assocreq_len;
}
skb = dev_alloc_skb(local->hw.extra_tx_headroom + skb = dev_alloc_skb(local->hw.extra_tx_headroom +
sizeof(*mgmt) + 200 + ifmgd->extra_ie_len + sizeof(*mgmt) + 200 + ifmgd->extra_ie_len +
ifmgd->ssid_len + e_ies_len); ifmgd->ssid_len);
if (!skb) { if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
"frame\n", sdata->dev->name); "frame\n", sdata->dev->name);
...@@ -304,8 +289,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) ...@@ -304,8 +289,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
} }
add_extra_ies(skb, e_ies, e_ies_len);
kfree(ifmgd->assocreq_ies); kfree(ifmgd->assocreq_ies);
ifmgd->assocreq_ies_len = (skb->data + skb->len) - ies; ifmgd->assocreq_ies_len = (skb->data + skb->len) - ies;
ifmgd->assocreq_ies = kmalloc(ifmgd->assocreq_ies_len, GFP_KERNEL); ifmgd->assocreq_ies = kmalloc(ifmgd->assocreq_ies_len, GFP_KERNEL);
...@@ -323,19 +306,8 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, ...@@ -323,19 +306,8 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_mgmt *mgmt; struct ieee80211_mgmt *mgmt;
u8 *ies;
size_t ies_len;
if (stype == IEEE80211_STYPE_DEAUTH) { skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
ies = sdata->u.mgd.ie_deauth;
ies_len = sdata->u.mgd.ie_deauth_len;
} else {
ies = sdata->u.mgd.ie_disassoc;
ies_len = sdata->u.mgd.ie_disassoc_len;
}
skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) +
ies_len);
if (!skb) { if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer for " printk(KERN_DEBUG "%s: failed to allocate buffer for "
"deauth/disassoc frame\n", sdata->dev->name); "deauth/disassoc frame\n", sdata->dev->name);
...@@ -353,8 +325,6 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, ...@@ -353,8 +325,6 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
/* u.deauth.reason_code == u.disassoc.reason_code */ /* u.deauth.reason_code == u.disassoc.reason_code */
mgmt->u.deauth.reason_code = cpu_to_le16(reason); mgmt->u.deauth.reason_code = cpu_to_le16(reason);
add_extra_ies(skb, ies, ies_len);
ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
} }
......
...@@ -846,16 +846,9 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, ...@@ -846,16 +846,9 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_mgmt *mgmt; struct ieee80211_mgmt *mgmt;
const u8 *ie_auth = NULL;
int ie_auth_len = 0;
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
ie_auth_len = sdata->u.mgd.ie_auth_len;
ie_auth = sdata->u.mgd.ie_auth;
}
skb = dev_alloc_skb(local->hw.extra_tx_headroom + skb = dev_alloc_skb(local->hw.extra_tx_headroom +
sizeof(*mgmt) + 6 + extra_len + ie_auth_len); sizeof(*mgmt) + 6 + extra_len);
if (!skb) { if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer for auth " printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
"frame\n", sdata->dev->name); "frame\n", sdata->dev->name);
...@@ -877,8 +870,6 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, ...@@ -877,8 +870,6 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
mgmt->u.auth.status_code = cpu_to_le16(0); mgmt->u.auth.status_code = cpu_to_le16(0);
if (extra) if (extra)
memcpy(skb_put(skb, extra_len), extra, extra_len); memcpy(skb_put(skb, extra_len), extra, extra_len);
if (ie_auth)
memcpy(skb_put(skb, ie_auth_len), ie_auth, ie_auth_len);
ieee80211_tx_skb(sdata, skb, encrypt); ieee80211_tx_skb(sdata, skb, encrypt);
} }
...@@ -891,20 +882,11 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, ...@@ -891,20 +882,11 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_mgmt *mgmt; struct ieee80211_mgmt *mgmt;
u8 *pos, *supp_rates, *esupp_rates = NULL, *extra_preq_ie = NULL; u8 *pos, *supp_rates, *esupp_rates = NULL;
int i, extra_preq_ie_len = 0; int i;
switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
extra_preq_ie_len = sdata->u.mgd.ie_probereq_len;
extra_preq_ie = sdata->u.mgd.ie_probereq;
break;
default:
break;
}
skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
ie_len + extra_preq_ie_len); ie_len);
if (!skb) { if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer for probe " printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
"request\n", sdata->dev->name); "request\n", sdata->dev->name);
...@@ -953,9 +935,6 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, ...@@ -953,9 +935,6 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
if (ie) if (ie)
memcpy(skb_put(skb, ie_len), ie, ie_len); memcpy(skb_put(skb, ie_len), ie, ie_len);
if (extra_preq_ie)
memcpy(skb_put(skb, extra_preq_ie_len), extra_preq_ie,
extra_preq_ie_len);
ieee80211_tx_skb(sdata, skb, 0); ieee80211_tx_skb(sdata, skb, 0);
} }
......
...@@ -269,7 +269,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, ...@@ -269,7 +269,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
CMD(add_mpath, NEW_MPATH); CMD(add_mpath, NEW_MPATH);
CMD(set_mesh_params, SET_MESH_PARAMS); CMD(set_mesh_params, SET_MESH_PARAMS);
CMD(change_bss, SET_BSS); CMD(change_bss, SET_BSS);
CMD(set_mgmt_extra_ie, SET_MGMT_EXTRA_IE);
CMD(auth, AUTHENTICATE); CMD(auth, AUTHENTICATE);
CMD(assoc, ASSOCIATE); CMD(assoc, ASSOCIATE);
CMD(deauth, DEAUTHENTICATE); CMD(deauth, DEAUTHENTICATE);
...@@ -2355,46 +2354,6 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) ...@@ -2355,46 +2354,6 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
return -EINVAL; return -EINVAL;
} }
static int nl80211_set_mgmt_extra_ie(struct sk_buff *skb,
struct genl_info *info)
{
struct cfg80211_registered_device *drv;
int err;
struct net_device *dev;
struct mgmt_extra_ie_params params;
memset(&params, 0, sizeof(params));
if (!info->attrs[NL80211_ATTR_MGMT_SUBTYPE])
return -EINVAL;
params.subtype = nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
if (params.subtype > 15)
return -EINVAL; /* FC Subtype field is 4 bits (0..15) */
if (info->attrs[NL80211_ATTR_IE]) {
params.ies = nla_data(info->attrs[NL80211_ATTR_IE]);
params.ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
rtnl_lock();
err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
if (err)
goto out_rtnl;
if (drv->ops->set_mgmt_extra_ie)
err = drv->ops->set_mgmt_extra_ie(&drv->wiphy, dev, &params);
else
err = -EOPNOTSUPP;
cfg80211_put_dev(drv);
dev_put(dev);
out_rtnl:
rtnl_unlock();
return err;
}
static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
{ {
struct cfg80211_registered_device *drv; struct cfg80211_registered_device *drv;
...@@ -3043,12 +3002,6 @@ static struct genl_ops nl80211_ops[] = { ...@@ -3043,12 +3002,6 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy, .policy = nl80211_policy,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
}, },
{
.cmd = NL80211_CMD_SET_MGMT_EXTRA_IE,
.doit = nl80211_set_mgmt_extra_ie,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
},
{ {
.cmd = NL80211_CMD_TRIGGER_SCAN, .cmd = NL80211_CMD_TRIGGER_SCAN,
.doit = nl80211_trigger_scan, .doit = nl80211_trigger_scan,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment