2010-06-14 06:15:58

by Teemu Paasikivi

[permalink] [raw]
Subject: [PATCH 0/3] mac80211: Add support for configuring ibss basic rates

This patch set implements support for configuring basic rates for ibss network when joining/creating one. First two patches are basically patch proposed by Johannes Berg on linux-wireless posting list split in two. These implement interface to nl80211 to do actual configuration from user space. Last patch impelents removal of the BSS information from the cfg80211 when leaving the IBSS and there is no other active STA's.

Teemu Paasikivi (3):
mac80211: Set basic rates while joining ibss network
mac80211: Set changed basic rates flag
mac80211: remove BSS from cfg80211 list when leaving IBSS

include/net/cfg80211.h | 2 +
net/mac80211/ibss.c | 38 +++++++++++++++++++++++++++++++++-
net/mac80211/ieee80211_i.h | 2 +
net/wireless/nl80211.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 90 insertions(+), 1 deletions(-)



2010-06-14 06:30:12

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/3] mac80211: Set basic rates while joining ibss network

On Mon, 2010-06-14 at 09:15 +0300, Teemu Paasikivi wrote:
> This patch adds support to nl80211 and mac80211 to set basic rates when
> joining/creating ibss network.
>
> Original patch was posted by Johannes Berg on the linux-wireless posting list.

Did you actually change it at all? (Ok I see you did make a bugfix, good
catch)

I personally don't care at all, but I guess generally you should
attribute it to the person who actually did (most of) the work.

In any case, John will need this:

Signed-off-by: Johannes Berg <[email protected]>


> Signed-off-by: Teemu Paasikivi <[email protected]>
> ---
> include/net/cfg80211.h | 2 +
> net/mac80211/ibss.c | 4 ++-
> net/mac80211/ieee80211_i.h | 2 +
> net/wireless/nl80211.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 56 insertions(+), 1 deletions(-)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 22ab9d8..64374f4 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -810,6 +810,7 @@ struct cfg80211_disassoc_request {
> * @beacon_interval: beacon interval to use
> * @privacy: this is a protected network, keys will be configured
> * after joining
> + * @basic_rates: bitmap of basic rates to use when creating the IBSS
> */
> struct cfg80211_ibss_params {
> u8 *ssid;
> @@ -818,6 +819,7 @@ struct cfg80211_ibss_params {
> u8 *ie;
> u8 ssid_len, ie_len;
> u16 beacon_interval;
> + u32 basic_rates;
> bool channel_fixed;
> bool privacy;
> };
> diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
> index d7a96ce..8be5a96 100644
> --- a/net/mac80211/ibss.c
> +++ b/net/mac80211/ibss.c
> @@ -172,6 +172,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
> rcu_assign_pointer(ifibss->presp, skb);
>
> sdata->vif.bss_conf.beacon_int = beacon_int;
> + sdata->vif.bss_conf.basic_rates = basic_rates;
> bss_change = BSS_CHANGED_BEACON_INT;
> bss_change |= ieee80211_reset_erp_info(sdata);
> bss_change |= BSS_CHANGED_BSSID;
> @@ -529,7 +530,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
> sdata->drop_unencrypted = 0;
>
> __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
> - ifibss->channel, 3, /* first two are basic */
> + ifibss->channel, ifibss->basic_rates,
> capability, 0);
> }
>
> @@ -910,6 +911,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
> sdata->u.ibss.fixed_bssid = false;
>
> sdata->u.ibss.privacy = params->privacy;
> + sdata->u.ibss.basic_rates = params->basic_rates;
>
> sdata->vif.bss_conf.beacon_int = params->beacon_interval;
>
> diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
> index 4d3883e..fde058b 100644
> --- a/net/mac80211/ieee80211_i.h
> +++ b/net/mac80211/ieee80211_i.h
> @@ -393,6 +393,8 @@ struct ieee80211_if_ibss {
> unsigned long request;
> unsigned long last_scan_completed;
>
> + u32 basic_rates;
> +
> bool timer_running;
>
> bool fixed_bssid;
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 90ab3c8..324b4a5 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -3955,6 +3955,55 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
> }
> }
>
> + if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
> + u8 *rates =
> + nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
> + int n_rates =
> + nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
> + struct ieee80211_supported_band *sband =
> + wiphy->bands[ibss.channel->band];
> + int i, j;
> +
> + if (n_rates == 0) {
> + err = -EINVAL;
> + goto out;
> + }
> +
> + for (i = 0; i < n_rates; i++) {
> + int rate = (rates[i] & 0x7f) * 5;
> + bool found = false;
> +
> + for (j = 0; j < sband->n_bitrates; j++) {
> + if (sband->bitrates[j].bitrate == rate) {
> + found = true;
> + ibss.basic_rates |= BIT(j);
> + break;
> + }
> + }
> + if (!found) {
> + err = -EINVAL;
> + goto out;
> + }
> + }
> + } else {
> + /*
> + * If no rates were explicitly configured,
> + * use the mandatory rate set for 11b or
> + * 11a for maximum compatibility.
> + */
> + struct ieee80211_supported_band *sband =
> + wiphy->bands[ibss.channel->band];
> + int j;
> + u32 flag = ibss.channel->band == IEEE80211_BAND_5GHZ ?
> + IEEE80211_RATE_MANDATORY_A :
> + IEEE80211_RATE_MANDATORY_B;
> +
> + for (j = 0; j < sband->n_bitrates; j++) {
> + if (sband->bitrates[j].flags & flag)
> + ibss.basic_rates |= BIT(j);
> + }
> + }
> +
> err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
>
> out:
> --
> 1.5.6.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>



2010-06-14 06:48:40

by Teemu Paasikivi

[permalink] [raw]
Subject: Re: [PATCH 1/3] mac80211: Set basic rates while joining ibss network

Hi,

On Mon, 2010-06-14 at 08:30 +0200, ext Johannes Berg wrote:
> On Mon, 2010-06-14 at 09:15 +0300, Teemu Paasikivi wrote:
> > This patch adds support to nl80211 and mac80211 to set basic rates when
> > joining/creating ibss network.
> >
> > Original patch was posted by Johannes Berg on the linux-wireless posting list.
>
> Did you actually change it at all? (Ok I see you did make a bugfix, good
> catch)
>

You're right, I only made that bugfix.


> I personally don't care at all, but I guess generally you should
> attribute it to the person who actually did (most of) the work.
>
> In any case, John will need this:
>
> Signed-off-by: Johannes Berg <[email protected]>
>

I'm very sorry about forgetting that. I'll send new versions of patches
with appropriate Signed-off-by's.


> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> > the body of a message to [email protected]
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
>
>


Teemu



2010-06-14 06:16:12

by Teemu Paasikivi

[permalink] [raw]
Subject: [PATCH 3/3] mac80211: remove BSS from cfg80211 list when leaving IBSS

Remove BSS from cfg80211 BSS list if we are only member in IBSS when
leaving it.

Signed-off-by: Teemu Paasikivi <[email protected]>
---
net/mac80211/ibss.c | 33 +++++++++++++++++++++++++++++++++
1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index ff91265..6d5489b 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -969,6 +969,39 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
{
struct sk_buff *skb;

+ struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+ struct ieee80211_local *local = sdata->local;
+ struct cfg80211_bss *cbss;
+ struct ieee80211_channel *chan = NULL;
+ const u8 *bssid = NULL;
+ u16 capability;
+ int active_ibss = 0;
+
+
+ active_ibss = ieee80211_sta_active_ibss(sdata);
+
+ if (!active_ibss) {
+ capability = WLAN_CAPABILITY_IBSS;
+ if (ifibss->privacy)
+ capability |= WLAN_CAPABILITY_PRIVACY;
+ if (ifibss->fixed_bssid)
+ bssid = ifibss->bssid;
+ if (ifibss->fixed_channel)
+ chan = ifibss->channel;
+ if (!is_zero_ether_addr(ifibss->bssid))
+ bssid = ifibss->bssid;
+ cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid,
+ ifibss->ssid, ifibss->ssid_len,
+ WLAN_CAPABILITY_IBSS |
+ WLAN_CAPABILITY_PRIVACY,
+ capability);
+
+ if (cbss) {
+ cfg80211_unlink_bss(local->hw.wiphy, cbss);
+ cfg80211_put_bss(cbss);
+ }
+ }
+
del_timer_sync(&sdata->u.ibss.timer);
clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
cancel_work_sync(&sdata->u.ibss.work);
--
1.5.6.3


2010-06-14 06:33:32

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 3/3] mac80211: remove BSS from cfg80211 list when leaving IBSS

On Mon, 2010-06-14 at 09:15 +0300, Teemu Paasikivi wrote:
> Remove BSS from cfg80211 BSS list if we are only member in IBSS when
> leaving it.
>
> Signed-off-by: Teemu Paasikivi <[email protected]>
> ---
> net/mac80211/ibss.c | 33 +++++++++++++++++++++++++++++++++
> 1 files changed, 33 insertions(+), 0 deletions(-)
>
> diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
> index ff91265..6d5489b 100644
> --- a/net/mac80211/ibss.c
> +++ b/net/mac80211/ibss.c
> @@ -969,6 +969,39 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
> {
> struct sk_buff *skb;
>
> + struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;

remove that empty live please

> + struct ieee80211_local *local = sdata->local;
> + struct cfg80211_bss *cbss;
> + struct ieee80211_channel *chan = NULL;
> + const u8 *bssid = NULL;
> + u16 capability;
> + int active_ibss = 0;
> +
> +
> + active_ibss = ieee80211_sta_active_ibss(sdata);
> +
> + if (!active_ibss) {
> + capability = WLAN_CAPABILITY_IBSS;
> + if (ifibss->privacy)
> + capability |= WLAN_CAPABILITY_PRIVACY;
> + if (ifibss->fixed_bssid)
> + bssid = ifibss->bssid;

Don't we update ifibss->bssid even if it's not fixed?

> + if (ifibss->fixed_channel)
> + chan = ifibss->channel;

> + if (!is_zero_ether_addr(ifibss->bssid))
> + bssid = ifibss->bssid;

I guess we do, but can it really ever be zeroed? Or does that happen
when we haven't even joined yet? But in that case you'd pass a NULL
bssid into get_bss() which would return a random one ... shouldn't you
rather not do anything in that case? Like making the first condition

if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {


and then never worry about the bssid again?

johannes


2010-06-14 06:16:13

by Teemu Paasikivi

[permalink] [raw]
Subject: [PATCH 2/3] mac80211: Set changed basic rates flag

Add changed basic rates flag to bss_changed while joinig ibss network.

This patch is split from the patch containing support for setting basic
rates when creating ibss network. Original patch was posted by Johannes
Berg on the linux-wireless posting list.

Signed-off-by: Teemu Paasikivi <[email protected]>
---
net/mac80211/ibss.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 8be5a96..ff91265 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -178,6 +178,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
bss_change |= BSS_CHANGED_BSSID;
bss_change |= BSS_CHANGED_BEACON;
bss_change |= BSS_CHANGED_BEACON_ENABLED;
+ bss_change |= BSS_CHANGED_BASIC_RATES;
bss_change |= BSS_CHANGED_IBSS;
sdata->vif.bss_conf.ibss_joined = true;
ieee80211_bss_info_change_notify(sdata, bss_change);
--
1.5.6.3


2010-06-14 06:30:19

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/3] mac80211: Set changed basic rates flag

On Mon, 2010-06-14 at 09:15 +0300, Teemu Paasikivi wrote:
> Add changed basic rates flag to bss_changed while joinig ibss network.
>
> This patch is split from the patch containing support for setting basic
> rates when creating ibss network. Original patch was posted by Johannes
> Berg on the linux-wireless posting list.
>

Signed-off-by: Johannes Berg <[email protected]>

> Signed-off-by: Teemu Paasikivi <[email protected]>
> ---
> net/mac80211/ibss.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
> index 8be5a96..ff91265 100644
> --- a/net/mac80211/ibss.c
> +++ b/net/mac80211/ibss.c
> @@ -178,6 +178,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
> bss_change |= BSS_CHANGED_BSSID;
> bss_change |= BSS_CHANGED_BEACON;
> bss_change |= BSS_CHANGED_BEACON_ENABLED;
> + bss_change |= BSS_CHANGED_BASIC_RATES;
> bss_change |= BSS_CHANGED_IBSS;
> sdata->vif.bss_conf.ibss_joined = true;
> ieee80211_bss_info_change_notify(sdata, bss_change);



2010-06-14 06:19:07

by Teemu Paasikivi

[permalink] [raw]
Subject: [PATCH 1/3] mac80211: Set basic rates while joining ibss network

This patch adds support to nl80211 and mac80211 to set basic rates when
joining/creating ibss network.

Original patch was posted by Johannes Berg on the linux-wireless posting list.

Signed-off-by: Teemu Paasikivi <[email protected]>
---
include/net/cfg80211.h | 2 +
net/mac80211/ibss.c | 4 ++-
net/mac80211/ieee80211_i.h | 2 +
net/wireless/nl80211.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 56 insertions(+), 1 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 22ab9d8..64374f4 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -810,6 +810,7 @@ struct cfg80211_disassoc_request {
* @beacon_interval: beacon interval to use
* @privacy: this is a protected network, keys will be configured
* after joining
+ * @basic_rates: bitmap of basic rates to use when creating the IBSS
*/
struct cfg80211_ibss_params {
u8 *ssid;
@@ -818,6 +819,7 @@ struct cfg80211_ibss_params {
u8 *ie;
u8 ssid_len, ie_len;
u16 beacon_interval;
+ u32 basic_rates;
bool channel_fixed;
bool privacy;
};
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index d7a96ce..8be5a96 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -172,6 +172,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
rcu_assign_pointer(ifibss->presp, skb);

sdata->vif.bss_conf.beacon_int = beacon_int;
+ sdata->vif.bss_conf.basic_rates = basic_rates;
bss_change = BSS_CHANGED_BEACON_INT;
bss_change |= ieee80211_reset_erp_info(sdata);
bss_change |= BSS_CHANGED_BSSID;
@@ -529,7 +530,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
sdata->drop_unencrypted = 0;

__ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
- ifibss->channel, 3, /* first two are basic */
+ ifibss->channel, ifibss->basic_rates,
capability, 0);
}

@@ -910,6 +911,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.fixed_bssid = false;

sdata->u.ibss.privacy = params->privacy;
+ sdata->u.ibss.basic_rates = params->basic_rates;

sdata->vif.bss_conf.beacon_int = params->beacon_interval;

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4d3883e..fde058b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -393,6 +393,8 @@ struct ieee80211_if_ibss {
unsigned long request;
unsigned long last_scan_completed;

+ u32 basic_rates;
+
bool timer_running;

bool fixed_bssid;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 90ab3c8..324b4a5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3955,6 +3955,55 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
}
}

+ if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
+ u8 *rates =
+ nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
+ int n_rates =
+ nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
+ struct ieee80211_supported_band *sband =
+ wiphy->bands[ibss.channel->band];
+ int i, j;
+
+ if (n_rates == 0) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < n_rates; i++) {
+ int rate = (rates[i] & 0x7f) * 5;
+ bool found = false;
+
+ for (j = 0; j < sband->n_bitrates; j++) {
+ if (sband->bitrates[j].bitrate == rate) {
+ found = true;
+ ibss.basic_rates |= BIT(j);
+ break;
+ }
+ }
+ if (!found) {
+ err = -EINVAL;
+ goto out;
+ }
+ }
+ } else {
+ /*
+ * If no rates were explicitly configured,
+ * use the mandatory rate set for 11b or
+ * 11a for maximum compatibility.
+ */
+ struct ieee80211_supported_band *sband =
+ wiphy->bands[ibss.channel->band];
+ int j;
+ u32 flag = ibss.channel->band == IEEE80211_BAND_5GHZ ?
+ IEEE80211_RATE_MANDATORY_A :
+ IEEE80211_RATE_MANDATORY_B;
+
+ for (j = 0; j < sband->n_bitrates; j++) {
+ if (sband->bitrates[j].flags & flag)
+ ibss.basic_rates |= BIT(j);
+ }
+ }
+
err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);

out:
--
1.5.6.3


2010-06-14 07:18:00

by Teemu Paasikivi

[permalink] [raw]
Subject: Re: [PATCH 3/3] mac80211: remove BSS from cfg80211 list when leaving IBSS

On Mon, 2010-06-14 at 08:33 +0200, ext Johannes Berg wrote:
> On Mon, 2010-06-14 at 09:15 +0300, Teemu Paasikivi wrote:
> > Remove BSS from cfg80211 BSS list if we are only member in IBSS when
> > leaving it.
> >
> > Signed-off-by: Teemu Paasikivi <[email protected]>
> > ---
> > net/mac80211/ibss.c | 33 +++++++++++++++++++++++++++++++++
> > 1 files changed, 33 insertions(+), 0 deletions(-)
> >
> > diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
> > index ff91265..6d5489b 100644
> > --- a/net/mac80211/ibss.c
> > +++ b/net/mac80211/ibss.c
> > @@ -969,6 +969,39 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
> > {
> > struct sk_buff *skb;
> >
> > + struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
>
> remove that empty live please
>
> > + struct ieee80211_local *local = sdata->local;
> > + struct cfg80211_bss *cbss;
> > + struct ieee80211_channel *chan = NULL;
> > + const u8 *bssid = NULL;
> > + u16 capability;
> > + int active_ibss = 0;
> > +
> > +
> > + active_ibss = ieee80211_sta_active_ibss(sdata);
> > +
> > + if (!active_ibss) {
> > + capability = WLAN_CAPABILITY_IBSS;
> > + if (ifibss->privacy)
> > + capability |= WLAN_CAPABILITY_PRIVACY;
> > + if (ifibss->fixed_bssid)
> > + bssid = ifibss->bssid;
>
> Don't we update ifibss->bssid even if it's not fixed?
>
> > + if (ifibss->fixed_channel)
> > + chan = ifibss->channel;
>
> > + if (!is_zero_ether_addr(ifibss->bssid))
> > + bssid = ifibss->bssid;
>
> I guess we do, but can it really ever be zeroed? Or does that happen
> when we haven't even joined yet? But in that case you'd pass a NULL
> bssid into get_bss() which would return a random one ... shouldn't you
> rather not do anything in that case? Like making the first condition
>
> if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
>
>
> and then never worry about the bssid again?
>
> johannes
>

Valid points. Back to the drawing board. I'll rework this a little bit.


Teemu