diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/driver-ops.h | 17 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 22 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 54 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 34 |
6 files changed, 58 insertions, 74 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 965d64f68567..c33317320eee 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -89,23 +89,6 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, | |||
89 | trace_drv_return_void(local); | 89 | trace_drv_return_void(local); |
90 | } | 90 | } |
91 | 91 | ||
92 | struct in_ifaddr; | ||
93 | static inline int drv_configure_arp_filter(struct ieee80211_local *local, | ||
94 | struct ieee80211_vif *vif, | ||
95 | struct in_ifaddr *ifa_list) | ||
96 | { | ||
97 | int ret = 0; | ||
98 | |||
99 | might_sleep(); | ||
100 | |||
101 | trace_drv_configure_arp_filter(local, vif_to_sdata(vif)); | ||
102 | if (local->ops->configure_arp_filter) | ||
103 | ret = local->ops->configure_arp_filter(&local->hw, vif, | ||
104 | ifa_list); | ||
105 | trace_drv_return_int(local, ret); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | static inline u64 drv_prepare_multicast(struct ieee80211_local *local, | 92 | static inline u64 drv_prepare_multicast(struct ieee80211_local *local, |
110 | struct netdev_hw_addr_list *mc_list) | 93 | struct netdev_hw_addr_list *mc_list) |
111 | { | 94 | { |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 06444ea67bc4..8da31caff931 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -251,28 +251,6 @@ TRACE_EVENT(drv_bss_info_changed, | |||
251 | ) | 251 | ) |
252 | ); | 252 | ); |
253 | 253 | ||
254 | TRACE_EVENT(drv_configure_arp_filter, | ||
255 | TP_PROTO(struct ieee80211_local *local, | ||
256 | struct ieee80211_sub_if_data *sdata), | ||
257 | |||
258 | TP_ARGS(local, sdata), | ||
259 | |||
260 | TP_STRUCT__entry( | ||
261 | LOCAL_ENTRY | ||
262 | VIF_ENTRY | ||
263 | ), | ||
264 | |||
265 | TP_fast_assign( | ||
266 | LOCAL_ASSIGN; | ||
267 | VIF_ASSIGN; | ||
268 | ), | ||
269 | |||
270 | TP_printk( | ||
271 | VIF_PR_FMT LOCAL_PR_FMT, | ||
272 | VIF_PR_ARG, LOCAL_PR_ARG | ||
273 | ) | ||
274 | ); | ||
275 | |||
276 | TRACE_EVENT(drv_prepare_multicast, | 254 | TRACE_EVENT(drv_prepare_multicast, |
277 | TP_PROTO(struct ieee80211_local *local, int mc_count), | 255 | TP_PROTO(struct ieee80211_local *local, int mc_count), |
278 | 256 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c3c2be3f8a2c..9b3c3f971d28 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -514,6 +514,8 @@ struct ieee80211_sub_if_data { | |||
514 | struct work_struct work; | 514 | struct work_struct work; |
515 | struct sk_buff_head skb_queue; | 515 | struct sk_buff_head skb_queue; |
516 | 516 | ||
517 | bool arp_filter_state; | ||
518 | |||
517 | /* | 519 | /* |
518 | * AP this belongs to: self in AP mode and | 520 | * AP this belongs to: self in AP mode and |
519 | * corresponding AP in VLAN mode, NULL for | 521 | * corresponding AP in VLAN mode, NULL for |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 490be2f3af27..910729fc18cd 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1076,6 +1076,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1076 | sdata->wdev.wiphy = local->hw.wiphy; | 1076 | sdata->wdev.wiphy = local->hw.wiphy; |
1077 | sdata->local = local; | 1077 | sdata->local = local; |
1078 | sdata->dev = ndev; | 1078 | sdata->dev = ndev; |
1079 | #ifdef CONFIG_INET | ||
1080 | sdata->arp_filter_state = true; | ||
1081 | #endif | ||
1079 | 1082 | ||
1080 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) | 1083 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) |
1081 | skb_queue_head_init(&sdata->fragments[i].skb_list); | 1084 | skb_queue_head_init(&sdata->fragments[i].skb_list); |
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; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 583b34686a26..74479c2d12d4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -806,11 +806,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
806 | { | 806 | { |
807 | struct ieee80211_bss *bss = (void *)cbss->priv; | 807 | struct ieee80211_bss *bss = (void *)cbss->priv; |
808 | struct ieee80211_local *local = sdata->local; | 808 | struct ieee80211_local *local = sdata->local; |
809 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | ||
809 | 810 | ||
810 | bss_info_changed |= BSS_CHANGED_ASSOC; | 811 | bss_info_changed |= BSS_CHANGED_ASSOC; |
811 | /* set timing information */ | 812 | /* set timing information */ |
812 | sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; | 813 | bss_conf->beacon_int = cbss->beacon_interval; |
813 | sdata->vif.bss_conf.timestamp = cbss->tsf; | 814 | bss_conf->timestamp = cbss->tsf; |
814 | 815 | ||
815 | bss_info_changed |= BSS_CHANGED_BEACON_INT; | 816 | bss_info_changed |= BSS_CHANGED_BEACON_INT; |
816 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, | 817 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
@@ -835,7 +836,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
835 | 836 | ||
836 | ieee80211_led_assoc(local, 1); | 837 | ieee80211_led_assoc(local, 1); |
837 | 838 | ||
838 | sdata->vif.bss_conf.assoc = 1; | 839 | bss_conf->assoc = 1; |
839 | /* | 840 | /* |
840 | * For now just always ask the driver to update the basic rateset | 841 | * For now just always ask the driver to update the basic rateset |
841 | * when we have associated, we aren't checking whether it actually | 842 | * when we have associated, we aren't checking whether it actually |
@@ -848,9 +849,15 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
848 | 849 | ||
849 | /* Tell the driver to monitor connection quality (if supported) */ | 850 | /* Tell the driver to monitor connection quality (if supported) */ |
850 | if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) && | 851 | if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) && |
851 | sdata->vif.bss_conf.cqm_rssi_thold) | 852 | bss_conf->cqm_rssi_thold) |
852 | bss_info_changed |= BSS_CHANGED_CQM; | 853 | bss_info_changed |= BSS_CHANGED_CQM; |
853 | 854 | ||
855 | /* Enable ARP filtering */ | ||
856 | if (bss_conf->arp_filter_enabled != sdata->arp_filter_state) { | ||
857 | bss_conf->arp_filter_enabled = sdata->arp_filter_state; | ||
858 | bss_info_changed |= BSS_CHANGED_ARP_FILTER; | ||
859 | } | ||
860 | |||
854 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); | 861 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); |
855 | 862 | ||
856 | mutex_lock(&local->iflist_mtx); | 863 | mutex_lock(&local->iflist_mtx); |
@@ -932,6 +939,12 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
932 | 939 | ||
933 | ieee80211_hw_config(local, config_changed); | 940 | ieee80211_hw_config(local, config_changed); |
934 | 941 | ||
942 | /* Disable ARP filtering */ | ||
943 | if (sdata->vif.bss_conf.arp_filter_enabled) { | ||
944 | sdata->vif.bss_conf.arp_filter_enabled = false; | ||
945 | changed |= BSS_CHANGED_ARP_FILTER; | ||
946 | } | ||
947 | |||
935 | /* The BSSID (not really interesting) and HT changed */ | 948 | /* The BSSID (not really interesting) and HT changed */ |
936 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; | 949 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; |
937 | ieee80211_bss_info_change_notify(sdata, changed); | 950 | ieee80211_bss_info_change_notify(sdata, changed); |
@@ -2018,18 +2031,9 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, | |||
2018 | cfg80211_send_assoc_timeout(wk->sdata->dev, | 2031 | cfg80211_send_assoc_timeout(wk->sdata->dev, |
2019 | wk->filter_ta); | 2032 | wk->filter_ta); |
2020 | return WORK_DONE_DESTROY; | 2033 | return WORK_DONE_DESTROY; |
2021 | } else { | ||
2022 | mutex_unlock(&wk->sdata->u.mgd.mtx); | ||
2023 | #ifdef CONFIG_INET | ||
2024 | /* | ||
2025 | * configure ARP filter IP addresses to the driver, | ||
2026 | * intentionally outside the mgd mutex. | ||
2027 | */ | ||
2028 | rtnl_lock(); | ||
2029 | ieee80211_set_arp_filter(wk->sdata); | ||
2030 | rtnl_unlock(); | ||
2031 | #endif | ||
2032 | } | 2034 | } |
2035 | |||
2036 | mutex_unlock(&wk->sdata->u.mgd.mtx); | ||
2033 | } | 2037 | } |
2034 | 2038 | ||
2035 | cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len); | 2039 | cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len); |