Fix monitor mode vaps to work as intended:
o track # bpf taps on monitor mode vaps instead of # monitor mode vaps o spam monitor mode taps on tx/rx o fix ieee80211_radiotap_rx_all to dispatch frames only if the vap is up o while here print radiotap (and superg) state in show com
This commit is contained in:
parent
97e535876e
commit
35d42ca22f
@ -513,8 +513,6 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
|
||||
|
||||
IEEE80211_LOCK(ic);
|
||||
TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
|
||||
if (vap->iv_opmode == IEEE80211_M_MONITOR)
|
||||
ic->ic_monvaps++;
|
||||
ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
|
||||
#ifdef IEEE80211_SUPPORT_SUPERG
|
||||
ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
|
||||
@ -575,8 +573,6 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
|
||||
IEEE80211_LOCK(ic);
|
||||
KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running"));
|
||||
TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
|
||||
if (vap->iv_opmode == IEEE80211_M_MONITOR)
|
||||
ic->ic_monvaps--;
|
||||
ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
|
||||
#ifdef IEEE80211_SUPPORT_SUPERG
|
||||
ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
|
||||
|
@ -584,6 +584,11 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showp
|
||||
db_printf(" lastnonht %d", ic->ic_lastnonht);
|
||||
db_printf("\n");
|
||||
|
||||
db_printf("\tsuperg %p\n", ic->ic_superg);
|
||||
|
||||
db_printf("\tmontaps %d th %p txchan %p rh %p rxchan %p\n",
|
||||
ic->ic_montaps, ic->ic_th, ic->ic_txchan, ic->ic_rh, ic->ic_rxchan);
|
||||
|
||||
if (showprocs) {
|
||||
DB_PRINTSYM("\t", "ic_vap_create", ic->ic_vap_create);
|
||||
DB_PRINTSYM("\t", "ic_vap_delete", ic->ic_vap_delete);
|
||||
|
@ -706,11 +706,16 @@ bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
|
||||
* vap. This flag is used by drivers to prepare radiotap
|
||||
* state only when needed.
|
||||
*/
|
||||
if (attach)
|
||||
if (attach) {
|
||||
ieee80211_syncflag_ext(vap, IEEE80211_FEXT_BPF);
|
||||
if (vap->iv_opmode == IEEE80211_M_MONITOR)
|
||||
atomic_add_int(&vap->iv_ic->ic_montaps, 1);
|
||||
/* NB: if_softc is NULL on vap detach */
|
||||
else if (vap != NULL && !bpf_peers_present(vap->iv_rawbpf))
|
||||
} else if (vap != NULL && !bpf_peers_present(vap->iv_rawbpf)) {
|
||||
ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_BPF);
|
||||
if (vap->iv_opmode == IEEE80211_M_MONITOR)
|
||||
atomic_subtract_int(&vap->iv_ic->ic_montaps, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,6 +302,9 @@ hostap_deliver_data(struct ieee80211vap *vap,
|
||||
struct ether_header *eh = mtod(m, struct ether_header *);
|
||||
struct ifnet *ifp = vap->iv_ifp;
|
||||
|
||||
/* clear driver/net80211 flags before passing up */
|
||||
m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST);
|
||||
|
||||
KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP,
|
||||
("gack, opmode %d", vap->iv_opmode));
|
||||
/*
|
||||
@ -316,9 +319,6 @@ hostap_deliver_data(struct ieee80211vap *vap,
|
||||
} else
|
||||
IEEE80211_NODE_STAT(ni, rx_ucast);
|
||||
|
||||
/* clear driver/net80211 flags before passing up */
|
||||
m->m_flags &= ~M_80211_RX;
|
||||
|
||||
/* perform as a bridge within the AP */
|
||||
if ((vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0) {
|
||||
struct mbuf *mcopy = NULL;
|
||||
|
@ -60,6 +60,8 @@ ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf)
|
||||
struct ieee80211vap *vap;
|
||||
int type = -1;
|
||||
|
||||
m->m_flags |= M_BCAST; /* NB: mark for bpf tap'ing */
|
||||
|
||||
/* XXX locking */
|
||||
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||
struct ieee80211_node *ni;
|
||||
@ -199,6 +201,9 @@ ieee80211_deliver_data(struct ieee80211vap *vap,
|
||||
struct ether_header *eh = mtod(m, struct ether_header *);
|
||||
struct ifnet *ifp = vap->iv_ifp;
|
||||
|
||||
/* clear driver/net80211 flags before passing up */
|
||||
m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST);
|
||||
|
||||
/* NB: see hostap_deliver_data, this path doesn't handle hostap */
|
||||
KASSERT(vap->iv_opmode != IEEE80211_M_HOSTAP, ("gack, hostap"));
|
||||
/*
|
||||
@ -214,9 +219,6 @@ ieee80211_deliver_data(struct ieee80211vap *vap,
|
||||
IEEE80211_NODE_STAT(ni, rx_ucast);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
|
||||
/* clear driver/net80211 flags before passing up */
|
||||
m->m_flags &= ~M_80211_RX;
|
||||
|
||||
if (ni->ni_vlan != 0) {
|
||||
/* attach vlan tag */
|
||||
m->m_pkthdr.ether_vtag = ni->ni_vlan;
|
||||
|
@ -168,6 +168,7 @@ ieee80211_radiotap_chan_change(struct ieee80211com *ic)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m,
|
||||
struct ieee80211_radiotap_header *rh)
|
||||
@ -175,17 +176,46 @@ dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m,
|
||||
struct ieee80211com *ic = vap0->iv_ic;
|
||||
int len = le16toh(rh->it_len);
|
||||
|
||||
if (ieee80211_radiotap_active_vap(vap0))
|
||||
if (vap0->iv_flags_ext & IEEE80211_FEXT_BPF)
|
||||
bpf_mtap2(vap0->iv_rawbpf, rh, len, m);
|
||||
if (ic->ic_monvaps) {
|
||||
/*
|
||||
* Spam monitor mode vaps with unicast frames. Multicast
|
||||
* frames are handled by passing through ieee80211_input_all
|
||||
* which distributes copies to the monitor mode vaps to be
|
||||
* processed above.
|
||||
*/
|
||||
if (ic->ic_montaps != 0 && (m->m_flags & M_BCAST) == 0) {
|
||||
struct ieee80211vap *vap;
|
||||
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||
if (vap->iv_opmode == IEEE80211_M_MONITOR &&
|
||||
vap != vap0 && ieee80211_radiotap_active_vap(vap))
|
||||
if (vap != vap0 &&
|
||||
vap->iv_opmode == IEEE80211_M_MONITOR &&
|
||||
(vap->iv_flags_ext & IEEE80211_FEXT_BPF) &&
|
||||
vap->iv_state != IEEE80211_S_INIT)
|
||||
bpf_mtap2(vap->iv_rawbpf, rh, len, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Distribute radiotap data (+packet) to all monitor mode
|
||||
* vaps with an active tap other than vap0.
|
||||
*/
|
||||
static void
|
||||
spam_vaps(struct ieee80211vap *vap0, struct mbuf *m,
|
||||
struct ieee80211_radiotap_header *rh, int len)
|
||||
{
|
||||
struct ieee80211com *ic = vap0->iv_ic;
|
||||
struct ieee80211vap *vap;
|
||||
|
||||
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||
if (vap != vap0 &&
|
||||
vap->iv_opmode == IEEE80211_M_MONITOR &&
|
||||
(vap->iv_flags_ext & IEEE80211_FEXT_BPF) &&
|
||||
vap->iv_state != IEEE80211_S_INIT)
|
||||
bpf_mtap2(vap->iv_rawbpf, rh, len, m);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dispatch radiotap data for transmitted packet.
|
||||
@ -193,8 +223,20 @@ dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m,
|
||||
void
|
||||
ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m)
|
||||
{
|
||||
KASSERT(vap0->iv_ic->ic_th != NULL, ("no tx radiotap header"));
|
||||
dispatch_radiotap(vap0, m, vap0->iv_ic->ic_th);
|
||||
struct ieee80211com *ic = vap0->iv_ic;
|
||||
struct ieee80211_radiotap_header *th = ic->ic_th;
|
||||
int len;
|
||||
|
||||
KASSERT(th != NULL, ("no tx radiotap header"));
|
||||
len = le16toh(th->it_len);
|
||||
|
||||
if (vap0->iv_flags_ext & IEEE80211_FEXT_BPF)
|
||||
bpf_mtap2(vap0->iv_rawbpf, th, len, m);
|
||||
/*
|
||||
* Spam monitor mode vaps.
|
||||
*/
|
||||
if (ic->ic_montaps != 0)
|
||||
spam_vaps(vap0, m, th, len);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -203,8 +245,22 @@ ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m)
|
||||
void
|
||||
ieee80211_radiotap_rx(struct ieee80211vap *vap0, struct mbuf *m)
|
||||
{
|
||||
KASSERT(vap0->iv_ic->ic_rh != NULL, ("no rx radiotap header"));
|
||||
dispatch_radiotap(vap0, m, vap0->iv_ic->ic_rh);
|
||||
struct ieee80211com *ic = vap0->iv_ic;
|
||||
struct ieee80211_radiotap_header *rh = ic->ic_rh;
|
||||
int len;
|
||||
|
||||
KASSERT(rh != NULL, ("no rx radiotap header"));
|
||||
len = le16toh(rh->it_len);
|
||||
|
||||
if (vap0->iv_flags_ext & IEEE80211_FEXT_BPF)
|
||||
bpf_mtap2(vap0->iv_rawbpf, rh, len, m);
|
||||
/*
|
||||
* Spam monitor mode vaps with unicast frames. Multicast
|
||||
* frames are handled by passing through ieee80211_input_all
|
||||
* which distributes copies to the monitor mode vaps.
|
||||
*/
|
||||
if (ic->ic_montaps != 0 && (m->m_flags & M_BCAST) == 0)
|
||||
spam_vaps(vap0, m, rh, len);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -221,7 +277,8 @@ ieee80211_radiotap_rx_all(struct ieee80211com *ic, struct mbuf *m)
|
||||
|
||||
/* XXX locking? */
|
||||
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||
if (ieee80211_radiotap_active_vap(vap))
|
||||
if (ieee80211_radiotap_active_vap(vap) &&
|
||||
vap->iv_state != IEEE80211_S_INIT)
|
||||
bpf_mtap2(vap->iv_rawbpf, rh, len, m);
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ struct ieee80211com {
|
||||
void *ic_txchan; /* channel state in ic_th */
|
||||
struct ieee80211_radiotap_header *ic_rh;/* rx radiotap headers */
|
||||
void *ic_rxchan; /* channel state in ic_rh */
|
||||
int ic_monvaps; /* # monitor mode vaps */
|
||||
int ic_montaps; /* active monitor mode taps */
|
||||
|
||||
/* virtual ap create/delete */
|
||||
struct ieee80211vap* (*ic_vap_create)(struct ieee80211com *,
|
||||
@ -669,7 +669,8 @@ ieee80211_radiotap_active(const struct ieee80211com *ic)
|
||||
static __inline int
|
||||
ieee80211_radiotap_active_vap(const struct ieee80211vap *vap)
|
||||
{
|
||||
return (vap->iv_flags_ext & IEEE80211_FEXT_BPF) != 0;
|
||||
return (vap->iv_flags_ext & IEEE80211_FEXT_BPF) ||
|
||||
vap->iv_ic->ic_montaps != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user