diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 54 |
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 |
320 | int 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 | |||
337 | static int ieee80211_ifa_changed(struct notifier_block *nb, | 321 | static 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; |