aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/driver-ops.h12
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/main.c48
-rw-r--r--net/mac80211/trace.h8
4 files changed, 69 insertions, 0 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index e6033b06caba..d51afbd614d3 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1036,4 +1036,16 @@ drv_set_default_unicast_key(struct ieee80211_local *local,
1036 trace_drv_return_void(local); 1036 trace_drv_return_void(local);
1037} 1037}
1038 1038
1039#if IS_ENABLED(CONFIG_IPV6)
1040static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
1041 struct ieee80211_sub_if_data *sdata,
1042 struct inet6_dev *idev)
1043{
1044 trace_drv_ipv6_addr_change(local, sdata);
1045 if (local->ops->ipv6_addr_change)
1046 local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1047 trace_drv_return_void(local);
1048}
1049#endif
1050
1039#endif /* __MAC80211_DRIVER_OPS */ 1051#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b1fed5491ed6..aec1b332aeb7 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1127,6 +1127,7 @@ struct ieee80211_local {
1127 struct timer_list dynamic_ps_timer; 1127 struct timer_list dynamic_ps_timer;
1128 struct notifier_block network_latency_notifier; 1128 struct notifier_block network_latency_notifier;
1129 struct notifier_block ifa_notifier; 1129 struct notifier_block ifa_notifier;
1130 struct notifier_block ifa6_notifier;
1130 1131
1131 /* 1132 /*
1132 * The dynamic ps timeout configured from user space via WEXT - 1133 * The dynamic ps timeout configured from user space via WEXT -
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index baf9720c1876..2bdd454e8bcf 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -23,6 +23,7 @@
23#include <linux/inetdevice.h> 23#include <linux/inetdevice.h>
24#include <net/net_namespace.h> 24#include <net/net_namespace.h>
25#include <net/cfg80211.h> 25#include <net/cfg80211.h>
26#include <net/addrconf.h>
26 27
27#include "ieee80211_i.h" 28#include "ieee80211_i.h"
28#include "driver-ops.h" 29#include "driver-ops.h"
@@ -369,6 +370,37 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
369} 370}
370#endif 371#endif
371 372
373#if IS_ENABLED(CONFIG_IPV6)
374static int ieee80211_ifa6_changed(struct notifier_block *nb,
375 unsigned long data, void *arg)
376{
377 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
378 struct inet6_dev *idev = ifa->idev;
379 struct net_device *ndev = ifa->idev->dev;
380 struct ieee80211_local *local =
381 container_of(nb, struct ieee80211_local, ifa6_notifier);
382 struct wireless_dev *wdev = ndev->ieee80211_ptr;
383 struct ieee80211_sub_if_data *sdata;
384
385 /* Make sure it's our interface that got changed */
386 if (!wdev || wdev->wiphy != local->hw.wiphy)
387 return NOTIFY_DONE;
388
389 sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
390
391 /*
392 * For now only support station mode. This is mostly because
393 * doing AP would have to handle AP_VLAN in some way ...
394 */
395 if (sdata->vif.type != NL80211_IFTYPE_STATION)
396 return NOTIFY_DONE;
397
398 drv_ipv6_addr_change(local, sdata, idev);
399
400 return NOTIFY_DONE;
401}
402#endif
403
372static int ieee80211_napi_poll(struct napi_struct *napi, int budget) 404static int ieee80211_napi_poll(struct napi_struct *napi, int budget)
373{ 405{
374 struct ieee80211_local *local = 406 struct ieee80211_local *local =
@@ -977,12 +1009,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
977 goto fail_ifa; 1009 goto fail_ifa;
978#endif 1010#endif
979 1011
1012#if IS_ENABLED(CONFIG_IPV6)
1013 local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
1014 result = register_inet6addr_notifier(&local->ifa6_notifier);
1015 if (result)
1016 goto fail_ifa6;
1017#endif
1018
980 netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll, 1019 netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll,
981 local->hw.napi_weight); 1020 local->hw.napi_weight);
982 1021
983 return 0; 1022 return 0;
984 1023
1024#if IS_ENABLED(CONFIG_IPV6)
1025 fail_ifa6:
985#ifdef CONFIG_INET 1026#ifdef CONFIG_INET
1027 unregister_inetaddr_notifier(&local->ifa_notifier);
1028#endif
1029#endif
1030#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
986 fail_ifa: 1031 fail_ifa:
987 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, 1032 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
988 &local->network_latency_notifier); 1033 &local->network_latency_notifier);
@@ -1018,6 +1063,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1018#ifdef CONFIG_INET 1063#ifdef CONFIG_INET
1019 unregister_inetaddr_notifier(&local->ifa_notifier); 1064 unregister_inetaddr_notifier(&local->ifa_notifier);
1020#endif 1065#endif
1066#if IS_ENABLED(CONFIG_IPV6)
1067 unregister_inet6addr_notifier(&local->ifa6_notifier);
1068#endif
1021 1069
1022 rtnl_lock(); 1070 rtnl_lock();
1023 1071
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index e9f95913c6f0..2a2c2e20307d 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1437,6 +1437,14 @@ DEFINE_EVENT(local_only_evt, drv_restart_complete,
1437 TP_ARGS(local) 1437 TP_ARGS(local)
1438); 1438);
1439 1439
1440#if IS_ENABLED(CONFIG_IPV6)
1441DEFINE_EVENT(local_sdata_evt, drv_ipv6_addr_change,
1442 TP_PROTO(struct ieee80211_local *local,
1443 struct ieee80211_sub_if_data *sdata),
1444 TP_ARGS(local, sdata)
1445);
1446#endif
1447
1440/* 1448/*
1441 * Tracing for API calls that drivers call. 1449 * Tracing for API calls that drivers call.
1442 */ 1450 */