2012-12-10 19:02:38

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH v2 1/2] mac80211: flush AP_VLAN stations when tearing down the BSS AP

Signed-off-by: Felix Fietkau <[email protected]>
---
net/mac80211/cfg.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 5c61677..a5d4361 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -998,8 +998,10 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp);

/* turn off carrier for this interface and dependent VLANs */
- list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
+ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
+ sta_info_flush(local, vlan);
netif_carrier_off(vlan->dev);
+ }
netif_carrier_off(dev);

/* remove beacon and probe response */
--
1.7.12.2



2012-12-11 19:24:32

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] mac80211: flush AP_VLAN stations when tearing down the BSS AP

On Tue, 2012-12-11 at 20:20 +0100, Johannes Berg wrote:
> Applied.

Ok looking at the code I changed my mind ... I don't love the double
iteration but I think it's better than getting the ordering wrong so I
changed the patch a bit.

johannes


2012-12-10 19:02:37

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH v2 2/2] mac80211: fix AP_VLAN channel context handling

When .start_ap is called, copy the channel context to all active AP VLANs.
Also copy the channel context when bringing up/down an AP VLAN if the AP
has been started already.

Signed-off-by: Felix Fietkau <[email protected]>
---
net/mac80211/cfg.c | 5 +++++
net/mac80211/iface.c | 13 ++++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a5d4361..b0a20ac 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -915,6 +915,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
if (err)
return err;

+ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
+ rcu_assign_pointer(vlan->vif.chanctx_conf,
+ rcu_access_pointer(sdata->vif.chanctx_conf));
+
/*
* Apply control port protocol, this allows us to
* not encrypt dynamic WEP control frames.
@@ -1001,6 +1005,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
sta_info_flush(local, vlan);
netif_carrier_off(vlan->dev);
+ rcu_assign_pointer(sdata->vif.chanctx_conf, NULL);
}
netif_carrier_off(dev);

diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 40c36d5..c2deb2a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -508,6 +508,7 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+ struct ieee80211_sub_if_data *ap;
struct net_device *dev = wdev->netdev;
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
@@ -587,10 +588,15 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP_VLAN:
/* no need to tell driver, but set carrier */
- if (rtnl_dereference(sdata->bss->beacon))
- netif_carrier_on(dev);
- else
+ if (!rtnl_dereference(sdata->bss->beacon)) {
netif_carrier_off(dev);
+ break;
+ }
+
+ ap = get_bss_sdata(sdata);
+ rcu_assign_pointer(sdata->vif.chanctx_conf,
+ rcu_access_pointer(ap->vif.chanctx_conf));
+ netif_carrier_on(dev);
break;
case NL80211_IFTYPE_MONITOR:
if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
@@ -839,6 +845,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP_VLAN:
list_del(&sdata->u.vlan.list);
+ rcu_assign_pointer(sdata->vif.chanctx_conf, NULL);
/* no need to tell driver */
break;
case NL80211_IFTYPE_MONITOR:
--
1.7.12.2