aboutsummaryrefslogtreecommitdiffstats
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 c2e46e88f3c9..a1bf46c64b93 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -20,6 +20,7 @@
20#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
21#include <linux/bitmap.h> 21#include <linux/bitmap.h>
22#include <linux/pm_qos_params.h> 22#include <linux/pm_qos_params.h>
23#include <linux/inetdevice.h>
23#include <net/net_namespace.h> 24#include <net/net_namespace.h>
24#include <net/cfg80211.h> 25#include <net/cfg80211.h>
25 26
@@ -317,23 +318,6 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
317} 318}
318 319
319#ifdef CONFIG_INET 320#ifdef CONFIG_INET
320int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata)
321{
322 struct in_device *idev;
323 int ret = 0;
324
325 BUG_ON(!sdata);
326 ASSERT_RTNL();
327
328 idev = sdata->dev->ip_ptr;
329 if (!idev)
330 return 0;
331
332 ret = drv_configure_arp_filter(sdata->local, &sdata->vif,
333 idev->ifa_list);
334 return ret;
335}
336
337static int ieee80211_ifa_changed(struct notifier_block *nb, 321static int ieee80211_ifa_changed(struct notifier_block *nb,
338 unsigned long data, void *arg) 322 unsigned long data, void *arg)
339{ 323{
@@ -343,8 +327,11 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
343 ifa_notifier); 327 ifa_notifier);
344 struct net_device *ndev = ifa->ifa_dev->dev; 328 struct net_device *ndev = ifa->ifa_dev->dev;
345 struct wireless_dev *wdev = ndev->ieee80211_ptr; 329 struct wireless_dev *wdev = ndev->ieee80211_ptr;
330 struct in_device *idev;
346 struct ieee80211_sub_if_data *sdata; 331 struct ieee80211_sub_if_data *sdata;
332 struct ieee80211_bss_conf *bss_conf;
347 struct ieee80211_if_managed *ifmgd; 333 struct ieee80211_if_managed *ifmgd;
334 int c = 0;
348 335
349 if (!netif_running(ndev)) 336 if (!netif_running(ndev))
350 return NOTIFY_DONE; 337 return NOTIFY_DONE;
@@ -356,17 +343,44 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
356 if (wdev->wiphy != local->hw.wiphy) 343 if (wdev->wiphy != local->hw.wiphy)
357 return NOTIFY_DONE; 344 return NOTIFY_DONE;
358 345
359 /* We are concerned about IP addresses only when associated */
360 sdata = IEEE80211_DEV_TO_SUB_IF(ndev); 346 sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
347 bss_conf = &sdata->vif.bss_conf;
361 348
362 /* ARP filtering is only supported in managed mode */ 349 /* ARP filtering is only supported in managed mode */
363 if (sdata->vif.type != NL80211_IFTYPE_STATION) 350 if (sdata->vif.type != NL80211_IFTYPE_STATION)
364 return NOTIFY_DONE; 351 return NOTIFY_DONE;
365 352
353 idev = sdata->dev->ip_ptr;
354 if (!idev)
355 return NOTIFY_DONE;
356
366 ifmgd = &sdata->u.mgd; 357 ifmgd = &sdata->u.mgd;
367 mutex_lock(&ifmgd->mtx); 358 mutex_lock(&ifmgd->mtx);
368 if (ifmgd->associated) 359
369 ieee80211_set_arp_filter(sdata); 360 /* Copy the addresses to the bss_conf list */
361 ifa = idev->ifa_list;
362 while (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN && ifa) {
363 bss_conf->arp_addr_list[c] = ifa->ifa_address;
364 ifa = ifa->ifa_next;
365 c++;
366 }
367
368 /* If not all addresses fit the list, disable filtering */
369 if (ifa) {
370 sdata->arp_filter_state = false;
371 c = 0;
372 } else {
373 sdata->arp_filter_state = true;
374 }
375 bss_conf->arp_addr_cnt = c;
376
377 /* Configure driver only if associated */
378 if (ifmgd->associated) {
379 bss_conf->arp_filter_enabled = sdata->arp_filter_state;
380 ieee80211_bss_info_change_notify(sdata,
381 BSS_CHANGED_ARP_FILTER);
382 }
383
370 mutex_unlock(&ifmgd->mtx); 384 mutex_unlock(&ifmgd->mtx);
371 385
372 return NOTIFY_DONE; 386 return NOTIFY_DONE;