ieee80211_output.c (190094) | ieee80211_output.c (190391) |
---|---|
1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_output.c 190094 2009-03-19 18:45:37Z rpaulo $"); | 28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_output.c 190391 2009-03-24 20:39:08Z sam $"); |
29 30#include "opt_inet.h" 31#include "opt_wlan.h" 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/mbuf.h> 36#include <sys/kernel.h> --- 5 unchanged lines hidden (view full) --- 42#include <net/ethernet.h> 43#include <net/if.h> 44#include <net/if_llc.h> 45#include <net/if_media.h> 46#include <net/if_vlan_var.h> 47 48#include <net80211/ieee80211_var.h> 49#include <net80211/ieee80211_regdomain.h> | 29 30#include "opt_inet.h" 31#include "opt_wlan.h" 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/mbuf.h> 36#include <sys/kernel.h> --- 5 unchanged lines hidden (view full) --- 42#include <net/ethernet.h> 43#include <net/if.h> 44#include <net/if_llc.h> 45#include <net/if_media.h> 46#include <net/if_vlan_var.h> 47 48#include <net80211/ieee80211_var.h> 49#include <net80211/ieee80211_regdomain.h> |
50#ifdef IEEE80211_SUPPORT_SUPERG 51#include <net80211/ieee80211_superg.h> 52#endif |
|
50#ifdef IEEE80211_SUPPORT_TDMA 51#include <net80211/ieee80211_tdma.h> 52#endif 53#include <net80211/ieee80211_wds.h> 54 55#ifdef INET 56#include <netinet/in.h> 57#include <netinet/if_ether.h> 58#include <netinet/in_systm.h> 59#include <netinet/ip.h> 60#endif 61 62#define ETHER_HEADER_COPY(dst, src) \ 63 memcpy(dst, src, sizeof(struct ether_header)) 64 | 53#ifdef IEEE80211_SUPPORT_TDMA 54#include <net80211/ieee80211_tdma.h> 55#endif 56#include <net80211/ieee80211_wds.h> 57 58#ifdef INET 59#include <netinet/in.h> 60#include <netinet/if_ether.h> 61#include <netinet/in_systm.h> 62#include <netinet/ip.h> 63#endif 64 65#define ETHER_HEADER_COPY(dst, src) \ 66 memcpy(dst, src, sizeof(struct ether_header)) 67 |
65static struct mbuf *ieee80211_encap_fastframe(struct ieee80211vap *, 66 struct mbuf *m1, const struct ether_header *eh1, 67 struct mbuf *m2, const struct ether_header *eh2); | |
68static int ieee80211_fragment(struct ieee80211vap *, struct mbuf *, 69 u_int hdrsize, u_int ciphdrsize, u_int mtu); 70static void ieee80211_tx_mgt_cb(struct ieee80211_node *, void *, int); 71 72#ifdef IEEE80211_DEBUG 73/* 74 * Decide if an outbound management frame should be 75 * printed when debugging is enabled. This filters some --- 650 unchanged lines hidden (view full) --- 726} 727 728/* 729 * Insure there is sufficient contiguous space to encapsulate the 730 * 802.11 data frame. If room isn't already there, arrange for it. 731 * Drivers and cipher modules assume we have done the necessary work 732 * and fail rudely if they don't find the space they need. 733 */ | 68static int ieee80211_fragment(struct ieee80211vap *, struct mbuf *, 69 u_int hdrsize, u_int ciphdrsize, u_int mtu); 70static void ieee80211_tx_mgt_cb(struct ieee80211_node *, void *, int); 71 72#ifdef IEEE80211_DEBUG 73/* 74 * Decide if an outbound management frame should be 75 * printed when debugging is enabled. This filters some --- 650 unchanged lines hidden (view full) --- 726} 727 728/* 729 * Insure there is sufficient contiguous space to encapsulate the 730 * 802.11 data frame. If room isn't already there, arrange for it. 731 * Drivers and cipher modules assume we have done the necessary work 732 * and fail rudely if they don't find the space they need. 733 */ |
734static struct mbuf * | 734struct mbuf * |
735ieee80211_mbuf_adjust(struct ieee80211vap *vap, int hdrsize, 736 struct ieee80211_key *key, struct mbuf *m) 737{ 738#define TO_BE_RECLAIMED (sizeof(struct ether_header) - sizeof(struct llc)) 739 int needed_space = vap->iv_ic->ic_headroom + hdrsize; 740 741 if (key != NULL) { 742 /* XXX belongs in crypto code? */ --- 113 unchanged lines hidden (view full) --- 856{ 857#define WH4(wh) ((struct ieee80211_frame_addr4 *)(wh)) 858 struct ieee80211vap *vap = ni->ni_vap; 859 struct ieee80211com *ic = ni->ni_ic; 860 struct ether_header eh; 861 struct ieee80211_frame *wh; 862 struct ieee80211_key *key; 863 struct llc *llc; | 735ieee80211_mbuf_adjust(struct ieee80211vap *vap, int hdrsize, 736 struct ieee80211_key *key, struct mbuf *m) 737{ 738#define TO_BE_RECLAIMED (sizeof(struct ether_header) - sizeof(struct llc)) 739 int needed_space = vap->iv_ic->ic_headroom + hdrsize; 740 741 if (key != NULL) { 742 /* XXX belongs in crypto code? */ --- 113 unchanged lines hidden (view full) --- 856{ 857#define WH4(wh) ((struct ieee80211_frame_addr4 *)(wh)) 858 struct ieee80211vap *vap = ni->ni_vap; 859 struct ieee80211com *ic = ni->ni_ic; 860 struct ether_header eh; 861 struct ieee80211_frame *wh; 862 struct ieee80211_key *key; 863 struct llc *llc; |
864 int hdrsize, hdrspace, datalen, addqos, txfrag, isff, is4addr; | 864 int hdrsize, hdrspace, datalen, addqos, txfrag, is4addr; |
865 866 /* 867 * Copy existing Ethernet header to a safe place. The 868 * rest of the code assumes it's ok to strip it when 869 * reorganizing state for the final encapsulation. 870 */ 871 KASSERT(m->m_len >= sizeof(eh), ("no ethernet header!")); 872 ETHER_HEADER_COPY(&eh, mtod(m, caddr_t)); --- 57 unchanged lines hidden (view full) --- 930 /* 931 * Honor driver DATAPAD requirement. 932 */ 933 if (ic->ic_flags & IEEE80211_F_DATAPAD) 934 hdrspace = roundup(hdrsize, sizeof(uint32_t)); 935 else 936 hdrspace = hdrsize; 937 | 865 866 /* 867 * Copy existing Ethernet header to a safe place. The 868 * rest of the code assumes it's ok to strip it when 869 * reorganizing state for the final encapsulation. 870 */ 871 KASSERT(m->m_len >= sizeof(eh), ("no ethernet header!")); 872 ETHER_HEADER_COPY(&eh, mtod(m, caddr_t)); --- 57 unchanged lines hidden (view full) --- 930 /* 931 * Honor driver DATAPAD requirement. 932 */ 933 if (ic->ic_flags & IEEE80211_F_DATAPAD) 934 hdrspace = roundup(hdrsize, sizeof(uint32_t)); 935 else 936 hdrspace = hdrsize; 937 |
938 if ((isff = m->m_flags & M_FF) != 0) { 939 struct mbuf *m2; 940 struct ether_header eh2; 941 | 938 if (__predict_true((m->m_flags & M_FF) == 0)) { |
942 /* | 939 /* |
943 * Fast frame encapsulation. There must be two packets 944 * chained with m_nextpkt. We do header adjustment for 945 * each, add the tunnel encapsulation, and then concatenate 946 * the mbuf chains to form a single frame for transmission. 947 */ 948 m2 = m->m_nextpkt; 949 if (m2 == NULL) { 950 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, 951 "%s: only one frame\n", __func__); 952 goto bad; 953 } 954 m->m_nextpkt = NULL; 955 /* 956 * Include fast frame headers in adjusting header 957 * layout; this allocates space according to what 958 * ieee80211_encap_fastframe will do. 959 */ 960 m = ieee80211_mbuf_adjust(vap, 961 hdrspace + sizeof(struct llc) + sizeof(uint32_t) + 2 + 962 sizeof(struct ether_header), 963 key, m); 964 if (m == NULL) { 965 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */ 966 m_freem(m2); 967 goto bad; 968 } 969 /* 970 * Copy second frame's Ethernet header out of line 971 * and adjust for encapsulation headers. Note that 972 * we make room for padding in case there isn't room 973 * at the end of first frame. 974 */ 975 KASSERT(m2->m_len >= sizeof(eh2), ("no ethernet header!")); 976 ETHER_HEADER_COPY(&eh2, mtod(m2, caddr_t)); 977 m2 = ieee80211_mbuf_adjust(vap, 978 ATH_FF_MAX_HDR_PAD + sizeof(struct ether_header), 979 NULL, m2); 980 if (m2 == NULL) { 981 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */ 982 goto bad; 983 } 984 m = ieee80211_encap_fastframe(vap, m, &eh, m2, &eh2); 985 if (m == NULL) 986 goto bad; 987 } else { 988 /* | |
989 * Normal frame. 990 */ 991 m = ieee80211_mbuf_adjust(vap, hdrspace, key, m); 992 if (m == NULL) { 993 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */ 994 goto bad; 995 } 996 /* NB: this could be optimized 'cuz of ieee80211_mbuf_adjust */ 997 m_adj(m, sizeof(struct ether_header) - sizeof(struct llc)); 998 llc = mtod(m, struct llc *); 999 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 1000 llc->llc_control = LLC_UI; 1001 llc->llc_snap.org_code[0] = 0; 1002 llc->llc_snap.org_code[1] = 0; 1003 llc->llc_snap.org_code[2] = 0; 1004 llc->llc_snap.ether_type = eh.ether_type; | 940 * Normal frame. 941 */ 942 m = ieee80211_mbuf_adjust(vap, hdrspace, key, m); 943 if (m == NULL) { 944 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */ 945 goto bad; 946 } 947 /* NB: this could be optimized 'cuz of ieee80211_mbuf_adjust */ 948 m_adj(m, sizeof(struct ether_header) - sizeof(struct llc)); 949 llc = mtod(m, struct llc *); 950 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 951 llc->llc_control = LLC_UI; 952 llc->llc_snap.org_code[0] = 0; 953 llc->llc_snap.org_code[1] = 0; 954 llc->llc_snap.org_code[2] = 0; 955 llc->llc_snap.ether_type = eh.ether_type; |
956 } else { 957#ifdef IEEE80211_SUPPORT_SUPERG 958 m = ieee80211_ff_encap(vap, m, hdrspace, key); 959 if (m == NULL) 960#endif 961 goto bad; |
|
1005 } 1006 datalen = m->m_pkthdr.len; /* NB: w/o 802.11 header */ 1007 1008 M_PREPEND(m, hdrspace, M_DONTWAIT); 1009 if (m == NULL) { 1010 vap->iv_stats.is_tx_nobuf++; 1011 goto bad; 1012 } --- 29 unchanged lines hidden (view full) --- 1042 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost); 1043 IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid); 1044 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost); 1045 break; 1046 case IEEE80211_M_MONITOR: 1047 case IEEE80211_M_WDS: /* NB: is4addr should always be true */ 1048 goto bad; 1049 } | 962 } 963 datalen = m->m_pkthdr.len; /* NB: w/o 802.11 header */ 964 965 M_PREPEND(m, hdrspace, M_DONTWAIT); 966 if (m == NULL) { 967 vap->iv_stats.is_tx_nobuf++; 968 goto bad; 969 } --- 29 unchanged lines hidden (view full) --- 999 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost); 1000 IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid); 1001 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost); 1002 break; 1003 case IEEE80211_M_MONITOR: 1004 case IEEE80211_M_WDS: /* NB: is4addr should always be true */ 1005 goto bad; 1006 } |
1050 if (m->m_flags & M_MORE_DATA) | 1007 if (m->m_flags & M_MORE_DATA) |
1051 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; 1052 if (addqos) { 1053 uint8_t *qos; 1054 int ac, tid; 1055 1056 if (is4addr) { 1057 qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos; 1058 } else --- 64 unchanged lines hidden (view full) --- 1123 *(uint16_t *)wh->i_seq = 1124 htole16(ni->ni_txseqs[IEEE80211_NONQOS_TID] << IEEE80211_SEQ_SEQ_SHIFT); 1125 ni->ni_txseqs[IEEE80211_NONQOS_TID]++; 1126 } 1127 /* check if xmit fragmentation is required */ 1128 txfrag = (m->m_pkthdr.len > vap->iv_fragthreshold && 1129 !IEEE80211_IS_MULTICAST(wh->i_addr1) && 1130 (vap->iv_caps & IEEE80211_C_TXFRAG) && | 1008 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; 1009 if (addqos) { 1010 uint8_t *qos; 1011 int ac, tid; 1012 1013 if (is4addr) { 1014 qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos; 1015 } else --- 64 unchanged lines hidden (view full) --- 1080 *(uint16_t *)wh->i_seq = 1081 htole16(ni->ni_txseqs[IEEE80211_NONQOS_TID] << IEEE80211_SEQ_SEQ_SHIFT); 1082 ni->ni_txseqs[IEEE80211_NONQOS_TID]++; 1083 } 1084 /* check if xmit fragmentation is required */ 1085 txfrag = (m->m_pkthdr.len > vap->iv_fragthreshold && 1086 !IEEE80211_IS_MULTICAST(wh->i_addr1) && 1087 (vap->iv_caps & IEEE80211_C_TXFRAG) && |
1131 !isff); /* NB: don't fragment ff's */ | 1088 (m->m_flags & M_FF) == 0); /* NB: don't fragment ff's */ |
1132 if (key != NULL) { 1133 /* 1134 * IEEE 802.1X: send EAPOL frames always in the clear. 1135 * WPA/WPA2: encrypt EAPOL keys when pairwise keys are set. 1136 */ 1137 if ((m->m_flags & M_EAPOL) == 0 || 1138 ((vap->iv_flags & IEEE80211_F_WPA) && 1139 (vap->iv_opmode == IEEE80211_M_STA ? --- 30 unchanged lines hidden (view full) --- 1170bad: 1171 if (m != NULL) 1172 m_freem(m); 1173 return NULL; 1174#undef WH4 1175} 1176 1177/* | 1089 if (key != NULL) { 1090 /* 1091 * IEEE 802.1X: send EAPOL frames always in the clear. 1092 * WPA/WPA2: encrypt EAPOL keys when pairwise keys are set. 1093 */ 1094 if ((m->m_flags & M_EAPOL) == 0 || 1095 ((vap->iv_flags & IEEE80211_F_WPA) && 1096 (vap->iv_opmode == IEEE80211_M_STA ? --- 30 unchanged lines hidden (view full) --- 1127bad: 1128 if (m != NULL) 1129 m_freem(m); 1130 return NULL; 1131#undef WH4 1132} 1133 1134/* |
1178 * Do Ethernet-LLC encapsulation for each payload in a fast frame 1179 * tunnel encapsulation. The frame is assumed to have an Ethernet 1180 * header at the front that must be stripped before prepending the 1181 * LLC followed by the Ethernet header passed in (with an Ethernet 1182 * type that specifies the payload size). 1183 */ 1184static struct mbuf * 1185ieee80211_encap1(struct ieee80211vap *vap, struct mbuf *m, 1186 const struct ether_header *eh) 1187{ 1188 struct llc *llc; 1189 uint16_t payload; 1190 1191 /* XXX optimize by combining m_adj+M_PREPEND */ 1192 m_adj(m, sizeof(struct ether_header) - sizeof(struct llc)); 1193 llc = mtod(m, struct llc *); 1194 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 1195 llc->llc_control = LLC_UI; 1196 llc->llc_snap.org_code[0] = 0; 1197 llc->llc_snap.org_code[1] = 0; 1198 llc->llc_snap.org_code[2] = 0; 1199 llc->llc_snap.ether_type = eh->ether_type; 1200 payload = m->m_pkthdr.len; /* NB: w/o Ethernet header */ 1201 1202 M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT); 1203 if (m == NULL) { /* XXX cannot happen */ 1204 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, 1205 "%s: no space for ether_header\n", __func__); 1206 vap->iv_stats.is_tx_nobuf++; 1207 return NULL; 1208 } 1209 ETHER_HEADER_COPY(mtod(m, void *), eh); 1210 mtod(m, struct ether_header *)->ether_type = htons(payload); 1211 return m; 1212} 1213 1214/* 1215 * Do fast frame tunnel encapsulation. The two frames and 1216 * Ethernet headers are supplied. The caller is assumed to 1217 * have arrange for space in the mbuf chains for encapsulating 1218 * headers (to avoid major mbuf fragmentation). 1219 * 1220 * The encapsulated frame is returned or NULL if there is a 1221 * problem (should not happen). 1222 */ 1223static struct mbuf * 1224ieee80211_encap_fastframe(struct ieee80211vap *vap, 1225 struct mbuf *m1, const struct ether_header *eh1, 1226 struct mbuf *m2, const struct ether_header *eh2) 1227{ 1228 struct llc *llc; 1229 struct mbuf *m; 1230 int pad; 1231 1232 /* 1233 * First, each frame gets a standard encapsulation. 1234 */ 1235 m1 = ieee80211_encap1(vap, m1, eh1); 1236 if (m1 == NULL) { 1237 m_freem(m2); 1238 return NULL; 1239 } 1240 m2 = ieee80211_encap1(vap, m2, eh2); 1241 if (m2 == NULL) { 1242 m_freem(m1); 1243 return NULL; 1244 } 1245 1246 /* 1247 * Pad leading frame to a 4-byte boundary. If there 1248 * is space at the end of the first frame, put it 1249 * there; otherwise prepend to the front of the second 1250 * frame. We know doing the second will always work 1251 * because we reserve space above. We prefer appending 1252 * as this typically has better DMA alignment properties. 1253 */ 1254 for (m = m1; m->m_next != NULL; m = m->m_next) 1255 ; 1256 pad = roundup2(m1->m_pkthdr.len, 4) - m1->m_pkthdr.len; 1257 if (pad) { 1258 if (M_TRAILINGSPACE(m) < pad) { /* prepend to second */ 1259 m2->m_data -= pad; 1260 m2->m_len += pad; 1261 m2->m_pkthdr.len += pad; 1262 } else { /* append to first */ 1263 m->m_len += pad; 1264 m1->m_pkthdr.len += pad; 1265 } 1266 } 1267 1268 /* 1269 * Now, stick 'em together and prepend the tunnel headers; 1270 * first the Atheros tunnel header (all zero for now) and 1271 * then a special fast frame LLC. 1272 * 1273 * XXX optimize by prepending together 1274 */ 1275 m->m_next = m2; /* NB: last mbuf from above */ 1276 m1->m_pkthdr.len += m2->m_pkthdr.len; 1277 M_PREPEND(m1, sizeof(uint32_t)+2, M_DONTWAIT); 1278 if (m1 == NULL) { /* XXX cannot happen */ 1279 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, 1280 "%s: no space for tunnel header\n", __func__); 1281 vap->iv_stats.is_tx_nobuf++; 1282 return NULL; 1283 } 1284 memset(mtod(m1, void *), 0, sizeof(uint32_t)+2); 1285 1286 M_PREPEND(m1, sizeof(struct llc), M_DONTWAIT); 1287 if (m1 == NULL) { /* XXX cannot happen */ 1288 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, 1289 "%s: no space for llc header\n", __func__); 1290 vap->iv_stats.is_tx_nobuf++; 1291 return NULL; 1292 } 1293 llc = mtod(m1, struct llc *); 1294 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 1295 llc->llc_control = LLC_UI; 1296 llc->llc_snap.org_code[0] = ATH_FF_SNAP_ORGCODE_0; 1297 llc->llc_snap.org_code[1] = ATH_FF_SNAP_ORGCODE_1; 1298 llc->llc_snap.org_code[2] = ATH_FF_SNAP_ORGCODE_2; 1299 llc->llc_snap.ether_type = htons(ATH_FF_ETH_TYPE); 1300 1301 vap->iv_stats.is_ff_encap++; 1302 1303 return m1; 1304} 1305 1306/* | |
1307 * Fragment the frame according to the specified mtu. 1308 * The size of the 802.11 header (w/o padding) is provided 1309 * so we don't need to recalculate it. We create a new 1310 * mbuf for each fragment and chain it through m_nextpkt; 1311 * we might be able to optimize this by reusing the original 1312 * packet's mbufs but that is significantly more complicated. 1313 */ 1314static int --- 248 unchanged lines hidden (view full) --- 1563 ADDSHORT(frm, ac->wmep_txopLimit); 1564 } 1565 return frm; 1566#undef SM 1567#undef ADDSHORT 1568} 1569#undef WME_OUI_BYTES 1570 | 1135 * Fragment the frame according to the specified mtu. 1136 * The size of the 802.11 header (w/o padding) is provided 1137 * so we don't need to recalculate it. We create a new 1138 * mbuf for each fragment and chain it through m_nextpkt; 1139 * we might be able to optimize this by reusing the original 1140 * packet's mbufs but that is significantly more complicated. 1141 */ 1142static int --- 248 unchanged lines hidden (view full) --- 1391 ADDSHORT(frm, ac->wmep_txopLimit); 1392 } 1393 return frm; 1394#undef SM 1395#undef ADDSHORT 1396} 1397#undef WME_OUI_BYTES 1398 |
1571#define ATH_OUI_BYTES 0x00, 0x03, 0x7f | |
1572/* | 1399/* |
1573 * Add a WME information element to a frame. 1574 */ 1575static uint8_t * 1576ieee80211_add_ath(uint8_t *frm, uint8_t caps, uint16_t defkeyix) 1577{ 1578 static const struct ieee80211_ath_ie info = { 1579 .ath_id = IEEE80211_ELEMID_VENDOR, 1580 .ath_len = sizeof(struct ieee80211_ath_ie) - 2, 1581 .ath_oui = { ATH_OUI_BYTES }, 1582 .ath_oui_type = ATH_OUI_TYPE, 1583 .ath_oui_subtype= ATH_OUI_SUBTYPE, 1584 .ath_version = ATH_OUI_VERSION, 1585 }; 1586 struct ieee80211_ath_ie *ath = (struct ieee80211_ath_ie *) frm; 1587 1588 memcpy(frm, &info, sizeof(info)); 1589 ath->ath_capability = caps; 1590 ath->ath_defkeyix[0] = (defkeyix & 0xff); 1591 ath->ath_defkeyix[1] = ((defkeyix >> 8) & 0xff); 1592 return frm + sizeof(info); 1593} 1594#undef ATH_OUI_BYTES 1595 1596/* | |
1597 * Add an 11h Power Constraint element to a frame. 1598 */ 1599static uint8_t * 1600ieee80211_add_powerconstraint(uint8_t *frm, struct ieee80211vap *vap) 1601{ 1602 const struct ieee80211_channel *c = vap->iv_bss->ni_chan; 1603 /* XXX per-vap tx power limit? */ 1604 int8_t limit = vap->iv_ic->ic_txpowlimit / 2; --- 367 unchanged lines hidden (view full) --- 1972 + 2 + IEEE80211_NWID_LEN 1973 + 2 + IEEE80211_RATE_SIZE 1974 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) 1975 + 4 1976 + 2 + 26 1977 + sizeof(struct ieee80211_wme_info) 1978 + sizeof(struct ieee80211_ie_htcap) 1979 + 4 + sizeof(struct ieee80211_ie_htcap) | 1400 * Add an 11h Power Constraint element to a frame. 1401 */ 1402static uint8_t * 1403ieee80211_add_powerconstraint(uint8_t *frm, struct ieee80211vap *vap) 1404{ 1405 const struct ieee80211_channel *c = vap->iv_bss->ni_chan; 1406 /* XXX per-vap tx power limit? */ 1407 int8_t limit = vap->iv_ic->ic_txpowlimit / 2; --- 367 unchanged lines hidden (view full) --- 1775 + 2 + IEEE80211_NWID_LEN 1776 + 2 + IEEE80211_RATE_SIZE 1777 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) 1778 + 4 1779 + 2 + 26 1780 + sizeof(struct ieee80211_wme_info) 1781 + sizeof(struct ieee80211_ie_htcap) 1782 + 4 + sizeof(struct ieee80211_ie_htcap) |
1783#ifdef IEEE80211_SUPPORT_SUPERG |
|
1980 + sizeof(struct ieee80211_ath_ie) | 1784 + sizeof(struct ieee80211_ath_ie) |
1785#endif |
|
1981 + (vap->iv_appie_wpa != NULL ? 1982 vap->iv_appie_wpa->ie_len : 0) 1983 + (vap->iv_appie_assocreq != NULL ? 1984 vap->iv_appie_assocreq->ie_len : 0) 1985 ); 1986 if (m == NULL) 1987 senderr(ENOMEM, is_tx_nobuf); 1988 --- 52 unchanged lines hidden (view full) --- 2041 } 2042 if ((ic->ic_flags & IEEE80211_F_WME) && 2043 ni->ni_ies.wme_ie != NULL) 2044 frm = ieee80211_add_wme_info(frm, &ic->ic_wme); 2045 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) && 2046 ni->ni_ies.htcap_ie != NULL && 2047 ni->ni_ies.htcap_ie[0] == IEEE80211_ELEMID_VENDOR) 2048 frm = ieee80211_add_htcap_vendor(frm, ni); | 1786 + (vap->iv_appie_wpa != NULL ? 1787 vap->iv_appie_wpa->ie_len : 0) 1788 + (vap->iv_appie_assocreq != NULL ? 1789 vap->iv_appie_assocreq->ie_len : 0) 1790 ); 1791 if (m == NULL) 1792 senderr(ENOMEM, is_tx_nobuf); 1793 --- 52 unchanged lines hidden (view full) --- 1846 } 1847 if ((ic->ic_flags & IEEE80211_F_WME) && 1848 ni->ni_ies.wme_ie != NULL) 1849 frm = ieee80211_add_wme_info(frm, &ic->ic_wme); 1850 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) && 1851 ni->ni_ies.htcap_ie != NULL && 1852 ni->ni_ies.htcap_ie[0] == IEEE80211_ELEMID_VENDOR) 1853 frm = ieee80211_add_htcap_vendor(frm, ni); |
1854#ifdef IEEE80211_SUPPORT_SUPERG |
|
2049 if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS)) 2050 frm = ieee80211_add_ath(frm, 2051 IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS), 2052 (vap->iv_flags & IEEE80211_F_WPA) == 0 && 2053 ni->ni_authmode != IEEE80211_AUTH_8021X && 2054 vap->iv_def_txkey != IEEE80211_KEYIX_NONE ? 2055 vap->iv_def_txkey : 0x7fff); | 1855 if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS)) 1856 frm = ieee80211_add_ath(frm, 1857 IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS), 1858 (vap->iv_flags & IEEE80211_F_WPA) == 0 && 1859 ni->ni_authmode != IEEE80211_AUTH_8021X && 1860 vap->iv_def_txkey != IEEE80211_KEYIX_NONE ? 1861 vap->iv_def_txkey : 0x7fff); |
1862#endif /* IEEE80211_SUPPORT_SUPERG */ |
|
2056 if (vap->iv_appie_assocreq != NULL) 2057 frm = add_appie(frm, vap->iv_appie_assocreq); 2058 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); 2059 2060 ieee80211_add_callback(m, ieee80211_tx_mgt_cb, 2061 (void *) vap->iv_state); 2062 break; 2063 --- 19 unchanged lines hidden (view full) --- 2083 sizeof(uint16_t) 2084 + sizeof(uint16_t) 2085 + sizeof(uint16_t) 2086 + 2 + IEEE80211_RATE_SIZE 2087 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) 2088 + sizeof(struct ieee80211_ie_htcap) + 4 2089 + sizeof(struct ieee80211_ie_htinfo) + 4 2090 + sizeof(struct ieee80211_wme_param) | 1863 if (vap->iv_appie_assocreq != NULL) 1864 frm = add_appie(frm, vap->iv_appie_assocreq); 1865 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); 1866 1867 ieee80211_add_callback(m, ieee80211_tx_mgt_cb, 1868 (void *) vap->iv_state); 1869 break; 1870 --- 19 unchanged lines hidden (view full) --- 1890 sizeof(uint16_t) 1891 + sizeof(uint16_t) 1892 + sizeof(uint16_t) 1893 + 2 + IEEE80211_RATE_SIZE 1894 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) 1895 + sizeof(struct ieee80211_ie_htcap) + 4 1896 + sizeof(struct ieee80211_ie_htinfo) + 4 1897 + sizeof(struct ieee80211_wme_param) |
1898#ifdef IEEE80211_SUPPORT_SUPERG |
|
2091 + sizeof(struct ieee80211_ath_ie) | 1899 + sizeof(struct ieee80211_ath_ie) |
1900#endif |
|
2092 + (vap->iv_appie_assocresp != NULL ? 2093 vap->iv_appie_assocresp->ie_len : 0) 2094 ); 2095 if (m == NULL) 2096 senderr(ENOMEM, is_tx_nobuf); 2097 2098 capinfo = getcapinfo(vap, bss->ni_chan); 2099 *(uint16_t *)frm = htole16(capinfo); --- 18 unchanged lines hidden (view full) --- 2118 } 2119 if ((vap->iv_flags & IEEE80211_F_WME) && 2120 ni->ni_ies.wme_ie != NULL) 2121 frm = ieee80211_add_wme_param(frm, &ic->ic_wme); 2122 if ((ni->ni_flags & HTFLAGS) == HTFLAGS) { 2123 frm = ieee80211_add_htcap_vendor(frm, ni); 2124 frm = ieee80211_add_htinfo_vendor(frm, ni); 2125 } | 1901 + (vap->iv_appie_assocresp != NULL ? 1902 vap->iv_appie_assocresp->ie_len : 0) 1903 ); 1904 if (m == NULL) 1905 senderr(ENOMEM, is_tx_nobuf); 1906 1907 capinfo = getcapinfo(vap, bss->ni_chan); 1908 *(uint16_t *)frm = htole16(capinfo); --- 18 unchanged lines hidden (view full) --- 1927 } 1928 if ((vap->iv_flags & IEEE80211_F_WME) && 1929 ni->ni_ies.wme_ie != NULL) 1930 frm = ieee80211_add_wme_param(frm, &ic->ic_wme); 1931 if ((ni->ni_flags & HTFLAGS) == HTFLAGS) { 1932 frm = ieee80211_add_htcap_vendor(frm, ni); 1933 frm = ieee80211_add_htinfo_vendor(frm, ni); 1934 } |
1935#ifdef IEEE80211_SUPPORT_SUPERG |
|
2126 if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS)) 2127 frm = ieee80211_add_ath(frm, 2128 IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS), 2129 ni->ni_ath_defkeyix); | 1936 if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS)) 1937 frm = ieee80211_add_ath(frm, 1938 IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS), 1939 ni->ni_ath_defkeyix); |
1940#endif /* IEEE80211_SUPPORT_SUPERG */ |
|
2130 if (vap->iv_appie_assocresp != NULL) 2131 frm = add_appie(frm, vap->iv_appie_assocresp); 2132 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); 2133 break; 2134 2135 case IEEE80211_FC0_SUBTYPE_DISASSOC: 2136 IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, 2137 "send station disassociate (reason %d)", arg); --- 84 unchanged lines hidden (view full) --- 2222 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) 2223 + sizeof(struct ieee80211_ie_wpa) 2224 + sizeof(struct ieee80211_ie_htcap) 2225 + sizeof(struct ieee80211_ie_htinfo) 2226 + sizeof(struct ieee80211_ie_wpa) 2227 + sizeof(struct ieee80211_wme_param) 2228 + 4 + sizeof(struct ieee80211_ie_htcap) 2229 + 4 + sizeof(struct ieee80211_ie_htinfo) | 1941 if (vap->iv_appie_assocresp != NULL) 1942 frm = add_appie(frm, vap->iv_appie_assocresp); 1943 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); 1944 break; 1945 1946 case IEEE80211_FC0_SUBTYPE_DISASSOC: 1947 IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, 1948 "send station disassociate (reason %d)", arg); --- 84 unchanged lines hidden (view full) --- 2033 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) 2034 + sizeof(struct ieee80211_ie_wpa) 2035 + sizeof(struct ieee80211_ie_htcap) 2036 + sizeof(struct ieee80211_ie_htinfo) 2037 + sizeof(struct ieee80211_ie_wpa) 2038 + sizeof(struct ieee80211_wme_param) 2039 + 4 + sizeof(struct ieee80211_ie_htcap) 2040 + 4 + sizeof(struct ieee80211_ie_htinfo) |
2041#ifdef IEEE80211_SUPPORT_SUPERG |
|
2230 + sizeof(struct ieee80211_ath_ie) | 2042 + sizeof(struct ieee80211_ath_ie) |
2043#endif |
|
2231 + (vap->iv_appie_proberesp != NULL ? 2232 vap->iv_appie_proberesp->ie_len : 0) 2233 ); 2234 if (m == NULL) { 2235 vap->iv_stats.is_tx_nobuf++; 2236 return NULL; 2237 } 2238 --- 66 unchanged lines hidden (view full) --- 2305 if (vap->iv_flags & IEEE80211_F_WME) 2306 frm = ieee80211_add_wme_param(frm, &ic->ic_wme); 2307 if (IEEE80211_IS_CHAN_HT(bss->ni_chan) && 2308 (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) && 2309 legacy != IEEE80211_SEND_LEGACY_11B) { 2310 frm = ieee80211_add_htcap_vendor(frm, bss); 2311 frm = ieee80211_add_htinfo_vendor(frm, bss); 2312 } | 2044 + (vap->iv_appie_proberesp != NULL ? 2045 vap->iv_appie_proberesp->ie_len : 0) 2046 ); 2047 if (m == NULL) { 2048 vap->iv_stats.is_tx_nobuf++; 2049 return NULL; 2050 } 2051 --- 66 unchanged lines hidden (view full) --- 2118 if (vap->iv_flags & IEEE80211_F_WME) 2119 frm = ieee80211_add_wme_param(frm, &ic->ic_wme); 2120 if (IEEE80211_IS_CHAN_HT(bss->ni_chan) && 2121 (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) && 2122 legacy != IEEE80211_SEND_LEGACY_11B) { 2123 frm = ieee80211_add_htcap_vendor(frm, bss); 2124 frm = ieee80211_add_htinfo_vendor(frm, bss); 2125 } |
2126#ifdef IEEE80211_SUPPORT_SUPERG |
|
2313 if (bss->ni_ies.ath_ie != NULL && legacy != IEEE80211_SEND_LEGACY_11B) 2314 frm = ieee80211_add_ath(frm, bss->ni_ath_flags, 2315 bss->ni_ath_defkeyix); | 2127 if (bss->ni_ies.ath_ie != NULL && legacy != IEEE80211_SEND_LEGACY_11B) 2128 frm = ieee80211_add_ath(frm, bss->ni_ath_flags, 2129 bss->ni_ath_defkeyix); |
2130#endif |
|
2316 if (vap->iv_appie_proberesp != NULL) 2317 frm = add_appie(frm, vap->iv_appie_proberesp); 2318 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); 2319 2320 return m; 2321} 2322 2323/* --- 622 unchanged lines hidden --- | 2131 if (vap->iv_appie_proberesp != NULL) 2132 frm = add_appie(frm, vap->iv_appie_proberesp); 2133 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); 2134 2135 return m; 2136} 2137 2138/* --- 622 unchanged lines hidden --- |