Date: Mon, 28 Mar 2005 01:47:27 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 73944 for review Message-ID: <200503280147.j2S1lRR2095549@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=73944 Change 73944 by sam@sam_ebb on 2005/03/28 01:46:29 o IFC o resurrect ff support lost in a previous merge o forward merge some stuff from the vap branch to simplify ifconfig sharing Affected files ... .. //depot/projects/wifi/sys/net80211/_ieee80211.h#5 edit .. //depot/projects/wifi/sys/net80211/ieee80211.c#22 edit .. //depot/projects/wifi/sys/net80211/ieee80211_input.c#45 edit .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#23 edit .. //depot/projects/wifi/sys/net80211/ieee80211_output.c#40 edit Differences ... ==== //depot/projects/wifi/sys/net80211/_ieee80211.h#5 (text+ko) ==== @@ -59,7 +59,8 @@ IEEE80211_M_IBSS = 0, /* IBSS (adhoc) station */ IEEE80211_M_AHDEMO = 3, /* Old lucent compatible adhoc demo */ IEEE80211_M_HOSTAP = 6, /* Software Access Point */ - IEEE80211_M_MONITOR = 8 /* Monitor mode */ + IEEE80211_M_MONITOR = 8, /* Monitor mode */ + IEEE80211_M_WDS = 2 /* WDS link */ }; /* ==== //depot/projects/wifi/sys/net80211/ieee80211.c#22 (text+ko) ==== @@ -625,6 +625,7 @@ case IEEE80211_M_HOSTAP: case IEEE80211_M_STA: case IEEE80211_M_MONITOR: + case IEEE80211_M_WDS: ic->ic_flags &= ~IEEE80211_F_IBSSON; break; case IEEE80211_M_IBSS: @@ -696,6 +697,11 @@ case IEEE80211_M_MONITOR: imr->ifm_active |= IFM_IEEE80211_MONITOR; break; + case IEEE80211_M_WDS: +#if 0 + imr->ifm_active |= IFM_IEEE80211_WDS; +#endif + break; } switch (ic->ic_curmode) { case IEEE80211_MODE_11A: ==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#45 (text+ko) ==== @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.33 2005/02/23 04:52:30 sam Exp $"); +__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.35 2005/03/16 20:39:05 sam Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -109,7 +109,11 @@ static struct mbuf *ieee80211_defrag(struct ieee80211com *, struct ieee80211_node *, struct mbuf *); +static void ieee80211_deliver_data(struct ieee80211com *, + struct ieee80211_node *, struct mbuf *); static struct mbuf *ieee80211_decap(struct ieee80211com *, struct mbuf *); +static struct mbuf *ieee80211_decap_fastframe(struct ieee80211com *, + struct ieee80211_node *, struct mbuf *); static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable); static void ieee80211_recv_pspoll(struct ieee80211com *, struct ieee80211_node *, struct mbuf *); @@ -134,7 +138,7 @@ struct ieee80211_frame *wh; struct ieee80211_key *key; struct ether_header *eh; - int len, hdrsize, off; + int hdrsize, off; u_int8_t dir, type, subtype; u_int8_t *bssid; u_int16_t rxseq; @@ -237,8 +241,7 @@ * discovered member of the IBSS. */ ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta, - type == IEEE80211_FC0_TYPE_CTL ? - wh->i_addr1 : wh->i_addr2); + wh->i_addr2); if (ni == NULL) { /* NB: stat kept for alloc failure */ goto err; @@ -289,9 +292,9 @@ hdrsize = roundup(hdrsize, sizeof(u_int32_t)); if (m->m_len < hdrsize && (m = m_pullup(m, hdrsize)) == NULL) { - IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, - wh, "data", "too short: len %u, expecting %u", - m->m_pkthdr.len, hdrsize); + IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, + ni->ni_macaddr, NULL, + "data too short: expecting %u", hdrsize); ic->ic_stats.is_rx_tooshort++; goto out; /* XXX */ } @@ -493,49 +496,32 @@ IEEE80211_NODE_STAT(ni, rx_data); IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len); - /* perform as a bridge within the AP */ - if (ic->ic_opmode == IEEE80211_M_HOSTAP && - (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0) { - struct mbuf *m1 = NULL; +#define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) + if ((ni->ni_flags & IEEE80211_NODE_FF) && + m->m_pkthdr.len >= 3*FF_LLC_SIZE) { + struct llc *llc; - if (ETHER_IS_MULTICAST(eh->ether_dhost)) { - m1 = m_copypacket(m, M_DONTWAIT); - if (m1 == NULL) - ifp->if_oerrors++; - else - m1->m_flags |= M_MCAST; - } else { - /* XXX this dups work done in ieee80211_encap */ - /* check if destination is associated */ - struct ieee80211_node *ni1 = - ieee80211_find_node(&ic->ic_sta, - eh->ether_dhost); - if (ni1 != NULL) { - /* XXX check if authorized */ - if (ni1->ni_associd != 0) { - m1 = m; - m = NULL; - } - /* XXX statistic? */ - ieee80211_free_node(ni1); - } + /* + * Check for fast-frame tunnel encapsulation. + */ + if (m->m_len < FF_LLC_SIZE && + (m = m_pullup(m, FF_LLC_SIZE)) == NULL) { + IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, + ni->ni_macaddr, "fast-frame", + "%s", "m_pullup(llc) failed"); + ic->ic_stats.is_rx_tooshort++; } - if (m1 != NULL) { - len = m1->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m1); - if (m != NULL) - ifp->if_omcasts++; - ifp->if_obytes += len; + llc = (struct llc *)(mtod(m, u_int8_t *) + + sizeof(struct ether_header)); + if (llc->llc_snap.ether_type == htons(ATH_FF_ETH_TYPE)) { + m_adj(m, FF_LLC_SIZE); + m = ieee80211_decap_fastframe(ic, ni, m); + if (m == NULL) + return; } } - if (m != NULL) { - if (ni->ni_vlan != 0) { - /* attach vlan tag */ - /* XXX goto err? */ - VLAN_INPUT_TAG(ifp, m, ni->ni_vlan, goto out); - } - (*ifp->if_input)(ifp, m); - } +#undef FF_LLC_SIZE + ieee80211_deliver_data(ic, ni, m); return; case IEEE80211_FC0_TYPE_MGT: @@ -706,13 +692,72 @@ *(u_int16_t *) lwh->i_seq = *(u_int16_t *) wh->i_seq; } if (more_frag) { /* more to come, save */ - ni->ni_rxfragstamp = ticks; ni->ni_rxfrag[0] = mfrag; mfrag = NULL; } return mfrag; } +static void +ieee80211_deliver_data(struct ieee80211com *ic, + struct ieee80211_node *ni, struct mbuf *m) +{ + struct ether_header *eh = mtod(m, struct ether_header *); + struct ifnet *ifp = ic->ic_ifp; + int len; + + /* perform as a bridge within the AP */ + if (ic->ic_opmode == IEEE80211_M_HOSTAP && + (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0) { + struct mbuf *m1 = NULL; + + if (ETHER_IS_MULTICAST(eh->ether_dhost)) { + m1 = m_copypacket(m, M_DONTWAIT); + if (m1 == NULL) + ifp->if_oerrors++; + else + m1->m_flags |= M_MCAST; + } else { + /* XXX this dups work done in ieee80211_encap */ + /* check if destination is associated */ + struct ieee80211_node *ni1 = + ieee80211_find_node(&ic->ic_sta, + eh->ether_dhost); + if (ni1 != NULL) { + /* XXX check if authorized */ + if (ni1->ni_associd != 0) { + m1 = m; + m = NULL; + } + /* XXX statistic? */ + ieee80211_free_node(ni1); + } + } + if (m1 != NULL) { + len = m1->m_pkthdr.len; + IF_ENQUEUE(&ifp->if_snd, m1); + if (m != NULL) + ifp->if_omcasts++; + ifp->if_obytes += len; + } + } + if (m != NULL) { + if (ni->ni_vlan != 0) { + /* attach vlan tag */ + /* XXX goto err? */ + VLAN_INPUT_TAG(ifp, m, ni->ni_vlan, goto out); + } + (*ifp->if_input)(ifp, m); + } + return; + out: + if (m != NULL) { + if (ic->ic_rawbpf) + bpf_mtap(ic->ic_rawbpf, m); + m_freem(m); + } +} + static struct mbuf * ieee80211_decap(struct ieee80211com *ic, struct mbuf *m) { @@ -815,6 +860,104 @@ } /* + * Decap a frame encapsulated in a fast-frame. + */ +static struct mbuf * +ieee80211_decap1(struct mbuf *m, int *framelen) +{ +#define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) + struct ether_header *eh; + struct llc *llc; + + /* + * The frame has an 802.3 header followed by an 802.2 + * LLC header. The encapsulated frame length is in the + * first header type field; save that and overwrite it + * with the true type field found in the second. Then + * copy the 802.3 header up to where it belongs and + * adjust the mbuf contents to remove the void. + */ + if (m->m_len < FF_LLC_SIZE && (m = m_pullup(m, FF_LLC_SIZE)) == NULL) + return NULL; + eh = mtod(m, struct ether_header *); /* 802.3 header is first */ + llc = (struct llc *)&eh[1]; /* 802.2 header follows */ + *framelen = ntohs(eh->ether_type) /* encap'd frame size */ + + sizeof(struct ether_header) - sizeof(struct llc); + eh->ether_type = llc->llc_un.type_snap.ether_type; + ovbcopy(eh, mtod(m, u_int8_t *) + sizeof(struct llc), + sizeof(struct ether_header)); + m_adj(m, sizeof(struct llc)); + return m; +#undef FF_LLC_SIZE +} + +/* + * Decap the encapsulated frame pair and dispatch the first + * for delivery. The second frame is returned for delivery + * via the normal path. + */ +static struct mbuf * +ieee80211_decap_fastframe(struct ieee80211com *ic, + struct ieee80211_node *ni, struct mbuf *m) +{ +#define MS(x,f) (((x) & f) >> f##_S) + u_int32_t ath; + struct mbuf *n; + int framelen; + + m_copydata(m, 0, sizeof(u_int32_t), (caddr_t) &ath); + if (MS(ath, ATH_FF_PROTO) != ATH_FF_PROTO_L2TUNNEL) { + IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, + ni->ni_macaddr, "fast-frame", + "unsupport tunnel protocol, header 0x%x", ath); + ic->ic_stats.is_ff_badhdr++; + m_freem(m); + return NULL; + } + /* NB: skip header and alignment padding */ + m_adj(m, roundup(sizeof(u_int32_t) - 2, 4) + 2); + + ic->ic_stats.is_ff_decap++; + + /* + * Decap the first frame, bust it apart from the + * second and deliver; then decap the second frame + * and return it to the caller for normal delivery. + */ + m = ieee80211_decap1(m, &framelen); + if (m == NULL) { + IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, + ni->ni_macaddr, "fast-frame", "%s", "first decap failed"); + ic->ic_stats.is_ff_tooshort++; + return NULL; + } + n = m_split(m, framelen, M_NOWAIT); + if (n == NULL) { + IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, + ni->ni_macaddr, "fast-frame", + "%s", "unable to split encapsulated frames"); + ic->ic_stats.is_ff_split++; + m_freem(m); /* NB: must reclaim */ + return NULL; + } + ieee80211_deliver_data(ic, ni, m); /* 1st of pair */ + + /* + * Decap second frame. + */ + m_adj(n, roundup2(framelen, 4) - framelen); /* padding */ + n = ieee80211_decap1(n, &framelen); + if (n == NULL) { + IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, + ni->ni_macaddr, "fast-frame", "%s", "second decap failed"); + ic->ic_stats.is_ff_tooshort++; + } + /* XXX verify framelen against mbuf contents */ + return n; /* 2nd delivered by caller */ +#undef MS +} + +/* * Install received rate set information in the node's state block. */ static int @@ -864,6 +1007,7 @@ break; case IEEE80211_M_AHDEMO: + case IEEE80211_M_WDS: /* should not come here */ break; @@ -1007,6 +1151,7 @@ case IEEE80211_M_MONITOR: case IEEE80211_M_AHDEMO: case IEEE80211_M_IBSS: + case IEEE80211_M_WDS: IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, ni->ni_macaddr, "shared key auth", "bad operating mode %u", ic->ic_opmode); @@ -1613,6 +1758,40 @@ #undef MS } +static int +ieee80211_parse_athparams(struct ieee80211_node *ni, u_int8_t *frm, + const struct ieee80211_frame *wh) +{ + struct ieee80211com *ic = ni->ni_ic; + const struct ieee80211_ath_ie *ath; + u_int len = frm[1]; + int caps; + + if (len < sizeof(struct ieee80211_ath_ie)-2) { + IEEE80211_DISCARD_IE(ic, + IEEE80211_MSG_ELEMID | IEEE80211_MSG_SUPERG, + wh, "Atheros", "too short, len %u", len); + return -1; + } + ath = (const struct ieee80211_ath_ie *)frm; + caps = 0; + if ((ath->ath_capability & ATHEROS_CAP_TURBO_PRIME) && + (ic->ic_flags & IEEE80211_F_TURBOP)) + caps |= IEEE80211_NODE_TURBOP; + if ((ath->ath_capability & ATHEROS_CAP_FAST_FRAME) && + (ic->ic_flags & IEEE80211_F_FF)) + caps |= IEEE80211_NODE_FF; + if ((ni->ni_flags ^ caps) & IEEE80211_NODE_ATH) { + IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG, + "[%s] ath ie: caps 0x%x defkeyix 0x%x, use 0x%x\n", + ether_sprintf(ni->ni_macaddr), + ath->ath_capability, LE_READ_2(ath->ath_defkeyix), caps); + ni->ni_flags = (ni->ni_flags &~ IEEE80211_NODE_ATH) | caps; + return 1; + } else + return 0; /* NB: no change */ +} + static void ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie) { @@ -1671,7 +1850,7 @@ #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP) struct ieee80211_frame *wh; u_int8_t *frm, *efrm; - u_int8_t *ssid, *rates, *xrates, *wpa, *wme; + u_int8_t *ssid, *rates, *xrates, *wpa, *wme, *ath; int reassoc, resp, allocbs; wh = mtod(m0, struct ieee80211_frame *); @@ -1712,12 +1891,13 @@ * [tlv] extended supported rates * [tlv] WME * [tlv] WPA or RSN + * [tlv] Atheros capabilities */ IEEE80211_VERIFY_LENGTH(efrm - frm, 12); tstamp = frm; frm += 8; bintval = le16toh(*(u_int16_t *)frm); frm += 2; capinfo = le16toh(*(u_int16_t *)frm); frm += 2; - ssid = rates = xrates = country = wpa = wme = NULL; + ssid = rates = xrates = country = wpa = wme = ath = NULL; bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); chan = bchan; fhdwell = 0; @@ -1777,7 +1957,8 @@ wpa = frm; else if (iswmeparam(frm) || iswmeinfo(frm)) wme = frm; - /* XXX Atheros OUI support */ + else if (isatherosoui(frm)) + ath = frm; break; default: IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID, @@ -1870,6 +2051,8 @@ if (wme != NULL && ieee80211_parse_wmeparams(ic, wme, wh) > 0) ieee80211_wme_updateparams(ic); + if (ath != NULL) + ieee80211_parse_athparams(ni, ath, wh); /* NB: don't need the rest of this */ if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) return; @@ -1945,6 +2128,10 @@ ieee80211_saveie(&ni->ni_wme_ie, wme); if (wpa != NULL) ieee80211_saveie(&ni->ni_wpa_ie, wpa); + if (ath != NULL) { + ieee80211_saveie(&ni->ni_ath_ie, ath); + (void) ieee80211_parse_athparams(ni, ath, wh); + } /* NB: must be after ni_chan is setup */ ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); break; @@ -1969,8 +2156,9 @@ * [tlv] ssid * [tlv] supported rates * [tlv] extended supported rates + * [tlv] Atheros capabilities */ - ssid = rates = xrates = NULL; + ssid = rates = xrates = ath = NULL; while (frm < efrm) { switch (*frm) { case IEEE80211_ELEMID_SSID: @@ -1982,20 +2170,16 @@ case IEEE80211_ELEMID_XRATES: xrates = frm; break; + case IEEE80211_ELEMID_VENDOR: + if (isatherosoui(frm)) + ath = frm; + break; } frm += frm[1] + 2; } IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); IEEE80211_VERIFY_SSID(ic->ic_bss, ssid); - if ((ic->ic_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) { - IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, - wh, ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], - "%s", "no ssid with ssid suppression enabled"); - ic->ic_stats.is_rx_ssidmismatch++; /*XXX*/ - return; - } if (ni == ic->ic_bss) { if (ic->ic_opmode == IEEE80211_M_IBSS) { @@ -2018,6 +2202,10 @@ "[%s] recv probe req\n", ether_sprintf(wh->i_addr2)); ni->ni_rssi = rssi; ni->ni_rstamp = rstamp; + if (ath != NULL) { + ieee80211_saveie(&ni->ni_ath_ie, ath); + (void) ieee80211_parse_athparams(ni, ath, wh); + } rate = ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); @@ -2124,6 +2312,7 @@ * [tlv] supported rates * [tlv] extended supported rates * [tlv] WPA or RSN + * [tlv] Atheros capabilities */ IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4)); if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) { @@ -2138,7 +2327,7 @@ bintval = le16toh(*(u_int16_t *)frm); frm += 2; if (reassoc) frm += 6; /* ignore current AP info */ - ssid = rates = xrates = wpa = wme = NULL; + ssid = rates = xrates = wpa = wme = ath = NULL; while (frm < efrm) { switch (*frm) { case IEEE80211_ELEMID_SSID: @@ -2160,7 +2349,8 @@ wpa = frm; } else if (iswmeinfo(frm)) wme = frm; - /* XXX Atheros OUI support */ + else if (isatherosoui(frm)) + ath = frm; break; } frm += frm[1] + 2; @@ -2184,6 +2374,20 @@ ic->ic_stats.is_rx_assoc_notauth++; return; } + /* assert right associstion security credentials */ + if (wpa == NULL && (ic->ic_flags & IEEE80211_F_WPA)) { + IEEE80211_DPRINTF(ic, + IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, + "[%s] no WPA/RSN IE in association request\n", + ether_sprintf(wh->i_addr2)); + IEEE80211_SEND_MGMT(ic, ni, + IEEE80211_FC0_SUBTYPE_DEAUTH, + IEEE80211_REASON_RSN_REQUIRED); + ieee80211_node_leave(ic, ni); + /* XXX distinguish WPA/RSN? */ + ic->ic_stats.is_rx_assoc_badwpaie++; + return; + } if (wpa != NULL) { /* * Parse WPA information element. Note that @@ -2287,6 +2491,23 @@ ni->ni_wme_ie = NULL; ni->ni_flags &= ~IEEE80211_NODE_QOS; } + if (ath != NULL) { + /* + * Record ATH parameters for station, mark + * node with appropriate capabilities, and + * record the information element for + * applications that require it. + */ + ieee80211_saveie(&ni->ni_ath_ie, ath); + (void) ieee80211_parse_athparams(ni, ath, wh); + } else if (ni->ni_ath_ie != NULL) { + /* + * Flush any state from a previous association. + */ + FREE(ni->ni_ath_ie, M_DEVBUF); + ni->ni_ath_ie = NULL; + ni->ni_flags &= ~IEEE80211_NODE_ATH; + } ieee80211_node_join(ic, ni, resp); break; } @@ -2330,7 +2551,7 @@ associd = le16toh(*(u_int16_t *)frm); frm += 2; - rates = xrates = wpa = wme = NULL; + rates = xrates = wme = NULL; while (frm < efrm) { switch (*frm) { case IEEE80211_ELEMID_RATES: @@ -2398,13 +2619,15 @@ else ic->ic_flags &= ~IEEE80211_F_USEPROT; IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, - "[%s] %sassoc success: %s preamble, %s slot time%s%s\n", + "[%s] %sassoc success: %s preamble, %s slot time%s%s%s%s\n", ether_sprintf(wh->i_addr2), ISREASSOC(subtype) ? "re" : "", ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long", ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long", ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "", - ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "" + ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "", + ni->ni_flags & IEEE80211_NODE_FF ? ", fast-frames" : "", + ni->ni_flags & IEEE80211_NODE_TURBOP ? ", turbo'" : "" ); ieee80211_new_state(ic, IEEE80211_S_RUN, subtype); break; ==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#23 (text+ko) ==== @@ -360,6 +360,7 @@ }; #define SIOCS80211 _IOW('i', 234, struct ieee80211req) #define SIOCG80211 _IOWR('i', 235, struct ieee80211req) +#define SIOCG80211STATS _IOWR('i', 236, struct ifreq) #define IEEE80211_IOC_SSID 1 #define IEEE80211_IOC_NUMSSIDS 2 @@ -453,7 +454,10 @@ /* variable length SSID followed by IE data */ }; -#define SIOCG80211STATS _IOWR('i', 236, struct ifreq) +struct ieee80211_clone_params { + char icp_parent[IFNAMSIZ]; /* parent device */ + int icp_opmode; /* operating mode */ +}; #endif /* __FreeBSD__ */ #endif /* _NET80211_IEEE80211_IOCTL_H_ */ ==== //depot/projects/wifi/sys/net80211/ieee80211_output.c#40 (text+ko) ==== @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.20 2005/02/10 17:00:48 sam Exp $"); +__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.21 2005/03/16 20:42:00 sam Exp $"); #include "opt_inet.h" @@ -233,7 +233,7 @@ v_wme_ac = 0; if (ni->ni_vlan != 0) { struct m_tag *mtag = VLAN_OUTPUT_TAG(ic->ic_ifp, m); - if (mtag != NULL) { + if (mtag == NULL) { IEEE80211_NODE_STAT(ni, tx_novlantag); return 1; } @@ -593,6 +593,7 @@ IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost); break; case IEEE80211_M_MONITOR: + case IEEE80211_M_WDS: goto bad; } if (addqos) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200503280147.j2S1lRR2095549>