net80211: enable promiscuous mode state change for non-monitor/ahdemo modes

- Allow to enable/disable promiscuous mode when:
  * interface is not a member of bridge, or;
  * request was issued by user (ifconfig wlan0 promisc), or;
  * interface is in MONITOR or AHDEMO mode.
- Drop local workarounds in mwl(4) and malo(4).

Tested with:
- Intel 3945BG, STA mode;
- RTL8188CUS, MONITOR mode;

Reviewed by:	adrian
Differential Revision:	https://reviews.freebsd.org/D5472
This commit is contained in:
Andriy Voskoboinyk 2016-04-21 05:47:47 +00:00
parent c706c470e4
commit 6459bd2843
4 changed files with 22 additions and 30 deletions

View File

@ -1570,14 +1570,7 @@ malo_mode_init(struct malo_softc *sc)
struct ieee80211com *ic = &sc->malo_ic;
struct malo_hal *mh = sc->malo_mh;
/*
* NB: Ignore promisc in hostap mode; it's set by the
* bridge. This is wrong but we have no way to
* identify internal requests (from the bridge)
* versus external requests such as for tcpdump.
*/
malo_hal_setpromisc(mh, ic->ic_promisc > 0 &&
ic->ic_opmode != IEEE80211_M_HOSTAP);
malo_hal_setpromisc(mh, ic->ic_promisc > 0);
malo_setmcastfilter(sc);
return ENXIO;

View File

@ -1753,14 +1753,7 @@ mwl_mode_init(struct mwl_softc *sc)
struct ieee80211com *ic = &sc->sc_ic;
struct mwl_hal *mh = sc->sc_mh;
/*
* NB: Ignore promisc in hostap mode; it's set by the
* bridge. This is wrong but we have no way to
* identify internal requests (from the bridge)
* versus external requests such as for tcpdump.
*/
mwl_hal_setpromisc(mh, ic->ic_promisc > 0 &&
ic->ic_opmode != IEEE80211_M_HOSTAP);
mwl_hal_setpromisc(mh, ic->ic_promisc > 0);
mwl_setmcastfilter(sc);
return 0;

View File

@ -704,16 +704,6 @@ ieee80211_promisc(struct ieee80211vap *vap, bool on)
{
struct ieee80211com *ic = vap->iv_ic;
/*
* XXX the bridge sets PROMISC but we don't want to
* enable it on the device, discard here so all the
* drivers don't need to special-case it
*/
if (!(vap->iv_opmode == IEEE80211_M_MONITOR ||
(vap->iv_opmode == IEEE80211_M_AHDEMO &&
(vap->iv_caps & IEEE80211_C_TDMA) == 0)))
return;
IEEE80211_LOCK_ASSERT(ic);
if (on) {

View File

@ -3306,11 +3306,27 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
switch (cmd) {
case SIOCSIFFLAGS:
IEEE80211_LOCK(ic);
if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_PROMISC)
ieee80211_promisc(vap, ifp->if_flags & IFF_PROMISC);
if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_ALLMULTI)
if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_PROMISC) {
/*
* Enable promiscuous mode when:
* 1. Interface is not a member of bridge, or
* 2. Requested by user, or
* 3. In monitor (or adhoc-demo) mode.
*/
if (ifp->if_bridge == NULL ||
(ifp->if_flags & IFF_PPROMISC) != 0 ||
vap->iv_opmode == IEEE80211_M_MONITOR ||
(vap->iv_opmode == IEEE80211_M_AHDEMO &&
(vap->iv_caps & IEEE80211_C_TDMA) == 0)) {
ieee80211_promisc(vap,
ifp->if_flags & IFF_PROMISC);
vap->iv_ifflags ^= IFF_PROMISC;
}
}
if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_ALLMULTI) {
ieee80211_allmulti(vap, ifp->if_flags & IFF_ALLMULTI);
vap->iv_ifflags = ifp->if_flags;
vap->iv_ifflags ^= IFF_ALLMULTI;
}
if (ifp->if_flags & IFF_UP) {
/*
* Bring ourself up unless we're already operational.