Allow SSID to be set independently for each interface. Signed-off-by: Jiri Benc <[EMAIL PROTECTED]>
--- include/net/d80211.h | 9 ++++++-- net/d80211/ieee80211.c | 6 ++++- net/d80211/ieee80211_i.h | 3 +++ net/d80211/ieee80211_ioctl.c | 47 +++++++++++++++++++++++++----------------- 4 files changed, 43 insertions(+), 22 deletions(-) 41fbbdfe8770f3492f888fcd459b2f9d2d615b0b diff --git a/include/net/d80211.h b/include/net/d80211.h index 3943e30..065b34c 100644 --- a/include/net/d80211.h +++ b/include/net/d80211.h @@ -251,8 +251,6 @@ struct ieee80211_conf { /* these fields are used by low level drivers for hardware * that generate beacons independently */ - u8 *ssid; - size_t ssid_len; u8 *generic_elem; size_t generic_elem_len; @@ -344,6 +342,11 @@ struct ieee80211_if_init_conf { * during the live of the interface; this field is present only for * convenience. * @bssid: BSSID of the network we are associated to/creating. + * @ssid: used (together with @ssid_len) by drivers for hardware that + * generate beacons independently. The pointer is valid only during + * config_interface() callback (so copy the value somewhere if you need + * it). + * @ssid_len: length of the @ssid field. * * This structure is passed to config_interface() callback of * &struct ieee80211_hw. @@ -351,6 +354,8 @@ struct ieee80211_if_init_conf { struct ieee80211_if_conf { int type; u8 *bssid; + u8 *ssid; + size_t ssid_len; }; typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL } diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c index 425bd51..984c2b0 100644 --- a/net/d80211/ieee80211.c +++ b/net/d80211/ieee80211.c @@ -1762,6 +1762,11 @@ int ieee80211_if_config(struct net_devic if (sdata->type == IEEE80211_IF_TYPE_STA || sdata->type == IEEE80211_IF_TYPE_IBSS) { conf.bssid = sdata->u.sta.bssid; + conf.ssid = sdata->u.sta.ssid; + conf.ssid_len = sdata->u.sta.ssid_len; + } else if (sdata->type == IEEE80211_IF_TYPE_AP) { + conf.ssid = sdata->u.ap.ssid; + conf.ssid_len = sdata->u.ap.ssid_len; } return local->hw->config_interface(local->mdev, dev->ifindex, &conf); } @@ -4337,7 +4342,6 @@ void ieee80211_unregister_hw(struct net_ kfree(local->basic_rates[i]); } - kfree(local->conf.ssid); kfree(local->conf.generic_elem); ieee80211_proc_deinit_interface(local); diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h index b29a5e8..e78beb2 100644 --- a/net/d80211/ieee80211_i.h +++ b/net/d80211/ieee80211_i.h @@ -192,6 +192,9 @@ struct ieee80211_if_ap { u8 *beacon_head, *beacon_tail; int beacon_head_len, beacon_tail_len; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + size_t ssid_len; + /* TODO: sta_aid could be replaced by 2008-bit large bitfield of * that could be used in TIM element generation. This would also * make TIM element generation a bit faster. */ diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c index 792fcf4..6b73e27 100644 --- a/net/d80211/ieee80211_ioctl.c +++ b/net/d80211/ieee80211_ioctl.c @@ -1746,7 +1746,6 @@ static int ieee80211_ioctl_siwessid(stru struct iw_request_info *info, struct iw_point *data, char *ssid) { - struct ieee80211_local *local = dev->priv; struct ieee80211_sub_if_data *sdata; size_t len = data->length; @@ -1759,14 +1758,14 @@ static int ieee80211_ioctl_siwessid(stru sdata->type == IEEE80211_IF_TYPE_IBSS) return ieee80211_sta_set_ssid(dev, ssid, len); - kfree(local->conf.ssid); - local->conf.ssid = kmalloc(len + 1, GFP_KERNEL); - if (local->conf.ssid == NULL) - return -ENOMEM; - memcpy(local->conf.ssid, ssid, len); - local->conf.ssid[len] = '\0'; - local->conf.ssid_len = len; - return ieee80211_hw_config(dev); + if (sdata->type == IEEE80211_IF_TYPE_AP) { + memcpy(sdata->u.ap.ssid, ssid, len); + memset(sdata->u.ap.ssid + len, 0, + IEEE80211_MAX_SSID_LEN - len); + sdata->u.ap.ssid_len = len; + return ieee80211_if_config(dev); + } + return -EOPNOTSUPP; } @@ -1774,7 +1773,6 @@ static int ieee80211_ioctl_giwessid(stru struct iw_request_info *info, struct iw_point *data, char *ssid) { - struct ieee80211_local *local = dev->priv; size_t len; struct ieee80211_sub_if_data *sdata; @@ -1790,13 +1788,16 @@ static int ieee80211_ioctl_giwessid(stru return res; } - len = local->conf.ssid_len; - if (len > IW_ESSID_MAX_SIZE) - len = IW_ESSID_MAX_SIZE; - memcpy(ssid, local->conf.ssid, len); - data->length = len; - data->flags = 1; - return 0; + if (sdata->type == IEEE80211_IF_TYPE_AP) { + len = sdata->u.ap.ssid_len; + if (len > IW_ESSID_MAX_SIZE) + len = IW_ESSID_MAX_SIZE; + memcpy(ssid, sdata->u.ap.ssid, len); + data->length = len; + data->flags = 1; + return 0; + } + return -EOPNOTSUPP; } @@ -1848,12 +1849,20 @@ static int ieee80211_ioctl_siwscan(struc struct iw_point *data, char *extra) { struct ieee80211_local *local = dev->priv; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); u8 *ssid = NULL; size_t ssid_len = 0; if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { - ssid = local->conf.ssid; - ssid_len = local->conf.ssid_len; + if (sdata->type == IEEE80211_IF_TYPE_STA || + sdata->type == IEEE80211_IF_TYPE_IBSS) { + ssid = sdata->u.sta.ssid; + ssid_len = sdata->u.sta.ssid_len; + } else if (sdata == IEEE80211_IF_TYPE_AP) { + ssid = sdata->u.ap.ssid; + ssid_len = sdata->u.ap.ssid_len; + } else + return -EINVAL; } return ieee80211_sta_req_scan(dev, ssid, ssid_len); } -- 1.3.0 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html