diff options
author | thompsa <thompsa@FreeBSD.org> | 2010-01-19 05:00:57 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2010-01-19 05:00:57 +0000 |
commit | e3e987d4d1f2740c3f6820b69ac9170ffb38cfa5 (patch) | |
tree | a63da5ef95f41ec8ff00f25979822611418b23d0 /sys/net80211/ieee80211_freebsd.c | |
parent | d0093d69aa47b2e5b4ca7be5feb402876e1bc9f2 (diff) | |
download | FreeBSD-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.c | 35 |
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; |