summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_freebsd.c
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2010-01-19 05:00:57 +0000
committerthompsa <thompsa@FreeBSD.org>2010-01-19 05:00:57 +0000
commite3e987d4d1f2740c3f6820b69ac9170ffb38cfa5 (patch)
treea63da5ef95f41ec8ff00f25979822611418b23d0 /sys/net80211/ieee80211_freebsd.c
parentd0093d69aa47b2e5b4ca7be5feb402876e1bc9f2 (diff)
downloadFreeBSD-src-e3e987d4d1f2740c3f6820b69ac9170ffb38cfa5.zip
FreeBSD-src-e3e987d4d1f2740c3f6820b69ac9170ffb38cfa5.tar.gz
Use the iflladdr_event event to keep the mac address on the vap in sync with
the parent wirless interface. If the user passed in a mac address or it was autogenerated then flag this to avoid trashing it on update. This will fix wlan+lagg in a post vap world.
Diffstat (limited to 'sys/net80211/ieee80211_freebsd.c')
-rw-r--r--sys/net80211/ieee80211_freebsd.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 22800fb..1de5800 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -730,6 +730,7 @@ ieee80211_load_module(const char *modname)
}
static eventhandler_tag wlan_bpfevent;
+static eventhandler_tag wlan_ifllevent;
static void
bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
@@ -756,6 +757,33 @@ bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
}
}
+static void
+wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
+{
+ struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211vap *vap, *next;
+
+ if (ifp->if_type != IFT_IEEE80211 || ic == NULL)
+ return;
+
+ IEEE80211_LOCK(ic);
+ TAILQ_FOREACH_SAFE(vap, &ic->ic_vaps, iv_next, next) {
+ /*
+ * If the MAC address has changed on the parent and it was
+ * copied to the vap on creation then re-sync.
+ */
+ if (vap->iv_ic == ic &&
+ (vap->iv_flags_ext & IEEE80211_FEXT_UNIQMAC) == 0) {
+ IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
+ IEEE80211_UNLOCK(ic);
+ if_setlladdr(vap->iv_ifp, IF_LLADDR(ifp),
+ IEEE80211_ADDR_LEN);
+ IEEE80211_LOCK(ic);
+ }
+ }
+ IEEE80211_UNLOCK(ic);
+}
+
/*
* Module glue.
*
@@ -772,6 +800,12 @@ wlan_modevent(module_t mod, int type, void *unused)
bpf_track, 0, EVENTHANDLER_PRI_ANY);
if (wlan_bpfevent == NULL)
return ENOMEM;
+ wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
+ wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
+ if (wlan_ifllevent == NULL) {
+ EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
+ return ENOMEM;
+ }
if_clone_attach(&wlan_cloner);
if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free);
return 0;
@@ -779,6 +813,7 @@ wlan_modevent(module_t mod, int type, void *unused)
if_deregister_com_alloc(IFT_IEEE80211);
if_clone_detach(&wlan_cloner);
EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
+ EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
return 0;
}
return EINVAL;
OpenPOWER on IntegriCloud