summaryrefslogtreecommitdiff
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index c2e46e88f3c..a1bf46c64b9 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -20,6 +20,7 @@
#include <linux/rtnetlink.h>
#include <linux/bitmap.h>
#include <linux/pm_qos_params.h>
+#include <linux/inetdevice.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
@@ -317,23 +318,6 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
}
#ifdef CONFIG_INET
-int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata)
-{
- struct in_device *idev;
- int ret = 0;
-
- BUG_ON(!sdata);
- ASSERT_RTNL();
-
- idev = sdata->dev->ip_ptr;
- if (!idev)
- return 0;
-
- ret = drv_configure_arp_filter(sdata->local, &sdata->vif,
- idev->ifa_list);
- return ret;
-}
-
static int ieee80211_ifa_changed(struct notifier_block *nb,
unsigned long data, void *arg)
{
@@ -343,8 +327,11 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
ifa_notifier);
struct net_device *ndev = ifa->ifa_dev->dev;
struct wireless_dev *wdev = ndev->ieee80211_ptr;
+ struct in_device *idev;
struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_bss_conf *bss_conf;
struct ieee80211_if_managed *ifmgd;
+ int c = 0;
if (!netif_running(ndev))
return NOTIFY_DONE;
@@ -356,17 +343,44 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
if (wdev->wiphy != local->hw.wiphy)
return NOTIFY_DONE;
- /* We are concerned about IP addresses only when associated */
sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
+ bss_conf = &sdata->vif.bss_conf;
/* ARP filtering is only supported in managed mode */
if (sdata->vif.type != NL80211_IFTYPE_STATION)
return NOTIFY_DONE;
+ idev = sdata->dev->ip_ptr;
+ if (!idev)
+ return NOTIFY_DONE;
+
ifmgd = &sdata->u.mgd;
mutex_lock(&ifmgd->mtx);
- if (ifmgd->associated)
- ieee80211_set_arp_filter(sdata);
+
+ /* Copy the addresses to the bss_conf list */
+ ifa = idev->ifa_list;
+ while (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN && ifa) {
+ bss_conf->arp_addr_list[c] = ifa->ifa_address;
+ ifa = ifa->ifa_next;
+ c++;
+ }
+
+ /* If not all addresses fit the list, disable filtering */
+ if (ifa) {
+ sdata->arp_filter_state = false;
+ c = 0;
+ } else {
+ sdata->arp_filter_state = true;
+ }
+ bss_conf->arp_addr_cnt = c;
+
+ /* Configure driver only if associated */
+ if (ifmgd->associated) {
+ bss_conf->arp_filter_enabled = sdata->arp_filter_state;
+ ieee80211_bss_info_change_notify(sdata,
+ BSS_CHANGED_ARP_FILTER);
+ }
+
mutex_unlock(&ifmgd->mtx);
return NOTIFY_DONE;