diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-15 19:50:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-15 19:50:46 -0400 |
commit | d3502d7f25b22cfc9762bf1781faa9db1bb3be2e (patch) | |
tree | e1d0195704efaafa14caf6965c8f2b6b00cbcb83 /net/mac80211/ieee80211.c | |
parent | d2a9a8ded48bec153f08ee87a40626c8d0737f79 (diff) | |
parent | 0a9f2a467d8dacaf7e97469dba99ed2d07287d80 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (53 commits)
[TCP]: Verify the presence of RETRANS bit when leaving FRTO
[IPV6]: Call inet6addr_chain notifiers on link down
[NET_SCHED]: Kill CONFIG_NET_CLS_POLICE
[NET_SCHED]: act_api: qdisc internal reclassify support
[NET_SCHED]: sch_dsmark: act_api support
[NET_SCHED]: sch_atm: act_api support
[NET_SCHED]: sch_atm: Lindent
[IPV6]: MSG_ERRQUEUE messages do not pass to connected raw sockets
[IPV4]: Cleanup call to __neigh_lookup()
[NET_SCHED]: Revert "avoid transmit softirq on watchdog wakeup" optimization
[NETFILTER]: nf_conntrack: UDPLITE support
[NETFILTER]: nf_conntrack: mark protocols __read_mostly
[NETFILTER]: x_tables: add connlimit match
[NETFILTER]: Lower *tables printk severity
[NETFILTER]: nf_conntrack: Don't track locally generated special ICMP error
[NETFILTER]: nf_conntrack: Introduces nf_ct_get_tuplepr and uses it
[NETFILTER]: nf_conntrack: make l3proto->prepare() generic and renames it
[NETFILTER]: nf_conntrack: Increment error count on parsing IPv4 header
[NET]: Add ethtool support for NETIF_F_IPV6_CSUM devices.
[AF_IUCV]: Add lock when updating accept_q
...
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r-- | net/mac80211/ieee80211.c | 449 |
1 files changed, 363 insertions, 86 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 4e84f24fd439..2ddf4ef4065e 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | #include <linux/bitmap.h> | 25 | #include <linux/bitmap.h> |
26 | #include <net/cfg80211.h> | 26 | #include <net/cfg80211.h> |
27 | #include <asm/unaligned.h> | ||
27 | 28 | ||
28 | #include "ieee80211_common.h" | 29 | #include "ieee80211_common.h" |
29 | #include "ieee80211_i.h" | 30 | #include "ieee80211_i.h" |
@@ -56,6 +57,17 @@ static const unsigned char eapol_header[] = | |||
56 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e }; | 57 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e }; |
57 | 58 | ||
58 | 59 | ||
60 | /* | ||
61 | * For seeing transmitted packets on monitor interfaces | ||
62 | * we have a radiotap header too. | ||
63 | */ | ||
64 | struct ieee80211_tx_status_rtap_hdr { | ||
65 | struct ieee80211_radiotap_header hdr; | ||
66 | __le16 tx_flags; | ||
67 | u8 data_retries; | ||
68 | } __attribute__ ((packed)); | ||
69 | |||
70 | |||
59 | static inline void ieee80211_include_sequence(struct ieee80211_sub_if_data *sdata, | 71 | static inline void ieee80211_include_sequence(struct ieee80211_sub_if_data *sdata, |
60 | struct ieee80211_hdr *hdr) | 72 | struct ieee80211_hdr *hdr) |
61 | { | 73 | { |
@@ -430,7 +442,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) | |||
430 | if (!tx->u.tx.rate) | 442 | if (!tx->u.tx.rate) |
431 | return TXRX_DROP; | 443 | return TXRX_DROP; |
432 | if (tx->u.tx.mode->mode == MODE_IEEE80211G && | 444 | if (tx->u.tx.mode->mode == MODE_IEEE80211G && |
433 | tx->local->cts_protect_erp_frames && tx->fragmented && | 445 | tx->sdata->use_protection && tx->fragmented && |
434 | extra.nonerp) { | 446 | extra.nonerp) { |
435 | tx->u.tx.last_frag_rate = tx->u.tx.rate; | 447 | tx->u.tx.last_frag_rate = tx->u.tx.rate; |
436 | tx->u.tx.probe_last_frag = extra.probe ? 1 : 0; | 448 | tx->u.tx.probe_last_frag = extra.probe ? 1 : 0; |
@@ -528,7 +540,7 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx) | |||
528 | /* reserve enough extra head and tail room for possible | 540 | /* reserve enough extra head and tail room for possible |
529 | * encryption */ | 541 | * encryption */ |
530 | frag = frags[i] = | 542 | frag = frags[i] = |
531 | dev_alloc_skb(tx->local->hw.extra_tx_headroom + | 543 | dev_alloc_skb(tx->local->tx_headroom + |
532 | frag_threshold + | 544 | frag_threshold + |
533 | IEEE80211_ENCRYPT_HEADROOM + | 545 | IEEE80211_ENCRYPT_HEADROOM + |
534 | IEEE80211_ENCRYPT_TAILROOM); | 546 | IEEE80211_ENCRYPT_TAILROOM); |
@@ -537,8 +549,8 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx) | |||
537 | /* Make sure that all fragments use the same priority so | 549 | /* Make sure that all fragments use the same priority so |
538 | * that they end up using the same TX queue */ | 550 | * that they end up using the same TX queue */ |
539 | frag->priority = first->priority; | 551 | frag->priority = first->priority; |
540 | skb_reserve(frag, tx->local->hw.extra_tx_headroom + | 552 | skb_reserve(frag, tx->local->tx_headroom + |
541 | IEEE80211_ENCRYPT_HEADROOM); | 553 | IEEE80211_ENCRYPT_HEADROOM); |
542 | fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); | 554 | fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); |
543 | memcpy(fhdr, first->data, hdrlen); | 555 | memcpy(fhdr, first->data, hdrlen); |
544 | if (i == num_fragm - 2) | 556 | if (i == num_fragm - 2) |
@@ -856,8 +868,7 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
856 | * for the frame. */ | 868 | * for the frame. */ |
857 | if (mode->mode == MODE_IEEE80211G && | 869 | if (mode->mode == MODE_IEEE80211G && |
858 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) && | 870 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) && |
859 | tx->u.tx.unicast && | 871 | tx->u.tx.unicast && tx->sdata->use_protection && |
860 | tx->local->cts_protect_erp_frames && | ||
861 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) | 872 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) |
862 | control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT; | 873 | control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT; |
863 | 874 | ||
@@ -1118,7 +1129,138 @@ ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx) | |||
1118 | } | 1129 | } |
1119 | 1130 | ||
1120 | 1131 | ||
1121 | static void inline | 1132 | /* |
1133 | * deal with packet injection down monitor interface | ||
1134 | * with Radiotap Header -- only called for monitor mode interface | ||
1135 | */ | ||
1136 | |||
1137 | static ieee80211_txrx_result | ||
1138 | __ieee80211_parse_tx_radiotap( | ||
1139 | struct ieee80211_txrx_data *tx, | ||
1140 | struct sk_buff *skb, struct ieee80211_tx_control *control) | ||
1141 | { | ||
1142 | /* | ||
1143 | * this is the moment to interpret and discard the radiotap header that | ||
1144 | * must be at the start of the packet injected in Monitor mode | ||
1145 | * | ||
1146 | * Need to take some care with endian-ness since radiotap | ||
1147 | * args are little-endian | ||
1148 | */ | ||
1149 | |||
1150 | struct ieee80211_radiotap_iterator iterator; | ||
1151 | struct ieee80211_radiotap_header *rthdr = | ||
1152 | (struct ieee80211_radiotap_header *) skb->data; | ||
1153 | struct ieee80211_hw_mode *mode = tx->local->hw.conf.mode; | ||
1154 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | ||
1155 | |||
1156 | /* | ||
1157 | * default control situation for all injected packets | ||
1158 | * FIXME: this does not suit all usage cases, expand to allow control | ||
1159 | */ | ||
1160 | |||
1161 | control->retry_limit = 1; /* no retry */ | ||
1162 | control->key_idx = -1; /* no encryption key */ | ||
1163 | control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS | | ||
1164 | IEEE80211_TXCTL_USE_CTS_PROTECT); | ||
1165 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT | | ||
1166 | IEEE80211_TXCTL_NO_ACK; | ||
1167 | control->antenna_sel_tx = 0; /* default to default antenna */ | ||
1168 | |||
1169 | /* | ||
1170 | * for every radiotap entry that is present | ||
1171 | * (ieee80211_radiotap_iterator_next returns -ENOENT when no more | ||
1172 | * entries present, or -EINVAL on error) | ||
1173 | */ | ||
1174 | |||
1175 | while (!ret) { | ||
1176 | int i, target_rate; | ||
1177 | |||
1178 | ret = ieee80211_radiotap_iterator_next(&iterator); | ||
1179 | |||
1180 | if (ret) | ||
1181 | continue; | ||
1182 | |||
1183 | /* see if this argument is something we can use */ | ||
1184 | switch (iterator.this_arg_index) { | ||
1185 | /* | ||
1186 | * You must take care when dereferencing iterator.this_arg | ||
1187 | * for multibyte types... the pointer is not aligned. Use | ||
1188 | * get_unaligned((type *)iterator.this_arg) to dereference | ||
1189 | * iterator.this_arg for type "type" safely on all arches. | ||
1190 | */ | ||
1191 | case IEEE80211_RADIOTAP_RATE: | ||
1192 | /* | ||
1193 | * radiotap rate u8 is in 500kbps units eg, 0x02=1Mbps | ||
1194 | * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps | ||
1195 | */ | ||
1196 | target_rate = (*iterator.this_arg) * 5; | ||
1197 | for (i = 0; i < mode->num_rates; i++) { | ||
1198 | struct ieee80211_rate *r = &mode->rates[i]; | ||
1199 | |||
1200 | if (r->rate > target_rate) | ||
1201 | continue; | ||
1202 | |||
1203 | control->rate = r; | ||
1204 | |||
1205 | if (r->flags & IEEE80211_RATE_PREAMBLE2) | ||
1206 | control->tx_rate = r->val2; | ||
1207 | else | ||
1208 | control->tx_rate = r->val; | ||
1209 | |||
1210 | /* end on exact match */ | ||
1211 | if (r->rate == target_rate) | ||
1212 | i = mode->num_rates; | ||
1213 | } | ||
1214 | break; | ||
1215 | |||
1216 | case IEEE80211_RADIOTAP_ANTENNA: | ||
1217 | /* | ||
1218 | * radiotap uses 0 for 1st ant, mac80211 is 1 for | ||
1219 | * 1st ant | ||
1220 | */ | ||
1221 | control->antenna_sel_tx = (*iterator.this_arg) + 1; | ||
1222 | break; | ||
1223 | |||
1224 | case IEEE80211_RADIOTAP_DBM_TX_POWER: | ||
1225 | control->power_level = *iterator.this_arg; | ||
1226 | break; | ||
1227 | |||
1228 | case IEEE80211_RADIOTAP_FLAGS: | ||
1229 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { | ||
1230 | /* | ||
1231 | * this indicates that the skb we have been | ||
1232 | * handed has the 32-bit FCS CRC at the end... | ||
1233 | * we should react to that by snipping it off | ||
1234 | * because it will be recomputed and added | ||
1235 | * on transmission | ||
1236 | */ | ||
1237 | if (skb->len < (iterator.max_length + FCS_LEN)) | ||
1238 | return TXRX_DROP; | ||
1239 | |||
1240 | skb_trim(skb, skb->len - FCS_LEN); | ||
1241 | } | ||
1242 | break; | ||
1243 | |||
1244 | default: | ||
1245 | break; | ||
1246 | } | ||
1247 | } | ||
1248 | |||
1249 | if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ | ||
1250 | return TXRX_DROP; | ||
1251 | |||
1252 | /* | ||
1253 | * remove the radiotap header | ||
1254 | * iterator->max_length was sanity-checked against | ||
1255 | * skb->len by iterator init | ||
1256 | */ | ||
1257 | skb_pull(skb, iterator.max_length); | ||
1258 | |||
1259 | return TXRX_CONTINUE; | ||
1260 | } | ||
1261 | |||
1262 | |||
1263 | static ieee80211_txrx_result inline | ||
1122 | __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, | 1264 | __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, |
1123 | struct sk_buff *skb, | 1265 | struct sk_buff *skb, |
1124 | struct net_device *dev, | 1266 | struct net_device *dev, |
@@ -1126,6 +1268,9 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, | |||
1126 | { | 1268 | { |
1127 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1269 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1128 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1270 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1271 | struct ieee80211_sub_if_data *sdata; | ||
1272 | ieee80211_txrx_result res = TXRX_CONTINUE; | ||
1273 | |||
1129 | int hdrlen; | 1274 | int hdrlen; |
1130 | 1275 | ||
1131 | memset(tx, 0, sizeof(*tx)); | 1276 | memset(tx, 0, sizeof(*tx)); |
@@ -1135,7 +1280,32 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, | |||
1135 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1280 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1136 | tx->sta = sta_info_get(local, hdr->addr1); | 1281 | tx->sta = sta_info_get(local, hdr->addr1); |
1137 | tx->fc = le16_to_cpu(hdr->frame_control); | 1282 | tx->fc = le16_to_cpu(hdr->frame_control); |
1283 | |||
1284 | /* | ||
1285 | * set defaults for things that can be set by | ||
1286 | * injected radiotap headers | ||
1287 | */ | ||
1138 | control->power_level = local->hw.conf.power_level; | 1288 | control->power_level = local->hw.conf.power_level; |
1289 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
1290 | if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta) | ||
1291 | control->antenna_sel_tx = tx->sta->antenna_sel_tx; | ||
1292 | |||
1293 | /* process and remove the injection radiotap header */ | ||
1294 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1295 | if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) { | ||
1296 | if (__ieee80211_parse_tx_radiotap(tx, skb, control) == | ||
1297 | TXRX_DROP) { | ||
1298 | return TXRX_DROP; | ||
1299 | } | ||
1300 | /* | ||
1301 | * we removed the radiotap header after this point, | ||
1302 | * we filled control with what we could use | ||
1303 | * set to the actual ieee header now | ||
1304 | */ | ||
1305 | hdr = (struct ieee80211_hdr *) skb->data; | ||
1306 | res = TXRX_QUEUED; /* indication it was monitor packet */ | ||
1307 | } | ||
1308 | |||
1139 | tx->u.tx.control = control; | 1309 | tx->u.tx.control = control; |
1140 | tx->u.tx.unicast = !is_multicast_ether_addr(hdr->addr1); | 1310 | tx->u.tx.unicast = !is_multicast_ether_addr(hdr->addr1); |
1141 | if (is_multicast_ether_addr(hdr->addr1)) | 1311 | if (is_multicast_ether_addr(hdr->addr1)) |
@@ -1152,9 +1322,6 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, | |||
1152 | control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; | 1322 | control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; |
1153 | tx->sta->clear_dst_mask = 0; | 1323 | tx->sta->clear_dst_mask = 0; |
1154 | } | 1324 | } |
1155 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
1156 | if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta) | ||
1157 | control->antenna_sel_tx = tx->sta->antenna_sel_tx; | ||
1158 | hdrlen = ieee80211_get_hdrlen(tx->fc); | 1325 | hdrlen = ieee80211_get_hdrlen(tx->fc); |
1159 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { | 1326 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { |
1160 | u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; | 1327 | u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; |
@@ -1162,6 +1329,7 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, | |||
1162 | } | 1329 | } |
1163 | control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT; | 1330 | control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT; |
1164 | 1331 | ||
1332 | return res; | ||
1165 | } | 1333 | } |
1166 | 1334 | ||
1167 | static int inline is_ieee80211_device(struct net_device *dev, | 1335 | static int inline is_ieee80211_device(struct net_device *dev, |
@@ -1274,7 +1442,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1274 | struct sta_info *sta; | 1442 | struct sta_info *sta; |
1275 | ieee80211_tx_handler *handler; | 1443 | ieee80211_tx_handler *handler; |
1276 | struct ieee80211_txrx_data tx; | 1444 | struct ieee80211_txrx_data tx; |
1277 | ieee80211_txrx_result res = TXRX_DROP; | 1445 | ieee80211_txrx_result res = TXRX_DROP, res_prepare; |
1278 | int ret, i; | 1446 | int ret, i; |
1279 | 1447 | ||
1280 | WARN_ON(__ieee80211_queue_pending(local, control->queue)); | 1448 | WARN_ON(__ieee80211_queue_pending(local, control->queue)); |
@@ -1284,15 +1452,26 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1284 | return 0; | 1452 | return 0; |
1285 | } | 1453 | } |
1286 | 1454 | ||
1287 | __ieee80211_tx_prepare(&tx, skb, dev, control); | 1455 | res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control); |
1456 | |||
1457 | if (res_prepare == TXRX_DROP) { | ||
1458 | dev_kfree_skb(skb); | ||
1459 | return 0; | ||
1460 | } | ||
1461 | |||
1288 | sta = tx.sta; | 1462 | sta = tx.sta; |
1289 | tx.u.tx.mgmt_interface = mgmt; | 1463 | tx.u.tx.mgmt_interface = mgmt; |
1290 | tx.u.tx.mode = local->hw.conf.mode; | 1464 | tx.u.tx.mode = local->hw.conf.mode; |
1291 | 1465 | ||
1292 | for (handler = local->tx_handlers; *handler != NULL; handler++) { | 1466 | if (res_prepare == TXRX_QUEUED) { /* if it was an injected packet */ |
1293 | res = (*handler)(&tx); | 1467 | res = TXRX_CONTINUE; |
1294 | if (res != TXRX_CONTINUE) | 1468 | } else { |
1295 | break; | 1469 | for (handler = local->tx_handlers; *handler != NULL; |
1470 | handler++) { | ||
1471 | res = (*handler)(&tx); | ||
1472 | if (res != TXRX_CONTINUE) | ||
1473 | break; | ||
1474 | } | ||
1296 | } | 1475 | } |
1297 | 1476 | ||
1298 | skb = tx.skb; /* handlers are allowed to change skb */ | 1477 | skb = tx.skb; /* handlers are allowed to change skb */ |
@@ -1467,8 +1646,7 @@ static int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
1467 | } | 1646 | } |
1468 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); | 1647 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); |
1469 | 1648 | ||
1470 | headroom = osdata->local->hw.extra_tx_headroom + | 1649 | headroom = osdata->local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM; |
1471 | IEEE80211_ENCRYPT_HEADROOM; | ||
1472 | if (skb_headroom(skb) < headroom) { | 1650 | if (skb_headroom(skb) < headroom) { |
1473 | if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) { | 1651 | if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) { |
1474 | dev_kfree_skb(skb); | 1652 | dev_kfree_skb(skb); |
@@ -1494,6 +1672,56 @@ static int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
1494 | } | 1672 | } |
1495 | 1673 | ||
1496 | 1674 | ||
1675 | int ieee80211_monitor_start_xmit(struct sk_buff *skb, | ||
1676 | struct net_device *dev) | ||
1677 | { | ||
1678 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1679 | struct ieee80211_tx_packet_data *pkt_data; | ||
1680 | struct ieee80211_radiotap_header *prthdr = | ||
1681 | (struct ieee80211_radiotap_header *)skb->data; | ||
1682 | u16 len; | ||
1683 | |||
1684 | /* | ||
1685 | * there must be a radiotap header at the | ||
1686 | * start in this case | ||
1687 | */ | ||
1688 | if (unlikely(prthdr->it_version)) { | ||
1689 | /* only version 0 is supported */ | ||
1690 | dev_kfree_skb(skb); | ||
1691 | return NETDEV_TX_OK; | ||
1692 | } | ||
1693 | |||
1694 | skb->dev = local->mdev; | ||
1695 | |||
1696 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | ||
1697 | memset(pkt_data, 0, sizeof(*pkt_data)); | ||
1698 | pkt_data->ifindex = dev->ifindex; | ||
1699 | pkt_data->mgmt_iface = 0; | ||
1700 | pkt_data->do_not_encrypt = 1; | ||
1701 | |||
1702 | /* above needed because we set skb device to master */ | ||
1703 | |||
1704 | /* | ||
1705 | * fix up the pointers accounting for the radiotap | ||
1706 | * header still being in there. We are being given | ||
1707 | * a precooked IEEE80211 header so no need for | ||
1708 | * normal processing | ||
1709 | */ | ||
1710 | len = le16_to_cpu(get_unaligned(&prthdr->it_len)); | ||
1711 | skb_set_mac_header(skb, len); | ||
1712 | skb_set_network_header(skb, len + sizeof(struct ieee80211_hdr)); | ||
1713 | skb_set_transport_header(skb, len + sizeof(struct ieee80211_hdr)); | ||
1714 | |||
1715 | /* | ||
1716 | * pass the radiotap header up to | ||
1717 | * the next stage intact | ||
1718 | */ | ||
1719 | dev_queue_xmit(skb); | ||
1720 | |||
1721 | return NETDEV_TX_OK; | ||
1722 | } | ||
1723 | |||
1724 | |||
1497 | /** | 1725 | /** |
1498 | * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type | 1726 | * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type |
1499 | * subinterfaces (wlan#, WDS, and VLAN interfaces) | 1727 | * subinterfaces (wlan#, WDS, and VLAN interfaces) |
@@ -1509,8 +1737,8 @@ static int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
1509 | * encapsulated packet will then be passed to master interface, wlan#.11, for | 1737 | * encapsulated packet will then be passed to master interface, wlan#.11, for |
1510 | * transmission (through low-level driver). | 1738 | * transmission (through low-level driver). |
1511 | */ | 1739 | */ |
1512 | static int ieee80211_subif_start_xmit(struct sk_buff *skb, | 1740 | int ieee80211_subif_start_xmit(struct sk_buff *skb, |
1513 | struct net_device *dev) | 1741 | struct net_device *dev) |
1514 | { | 1742 | { |
1515 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1743 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1516 | struct ieee80211_tx_packet_data *pkt_data; | 1744 | struct ieee80211_tx_packet_data *pkt_data; |
@@ -1619,7 +1847,7 @@ static int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1619 | * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and | 1847 | * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and |
1620 | * alloc_skb() (net/core/skbuff.c) | 1848 | * alloc_skb() (net/core/skbuff.c) |
1621 | */ | 1849 | */ |
1622 | head_need = hdrlen + encaps_len + local->hw.extra_tx_headroom; | 1850 | head_need = hdrlen + encaps_len + local->tx_headroom; |
1623 | head_need -= skb_headroom(skb); | 1851 | head_need -= skb_headroom(skb); |
1624 | 1852 | ||
1625 | /* We are going to modify skb data, so make a copy of it if happens to | 1853 | /* We are going to modify skb data, so make a copy of it if happens to |
@@ -1658,7 +1886,7 @@ static int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1658 | 1886 | ||
1659 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1887 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; |
1660 | memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); | 1888 | memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); |
1661 | pkt_data->ifindex = sdata->dev->ifindex; | 1889 | pkt_data->ifindex = dev->ifindex; |
1662 | pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT); | 1890 | pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT); |
1663 | pkt_data->do_not_encrypt = no_encrypt; | 1891 | pkt_data->do_not_encrypt = no_encrypt; |
1664 | 1892 | ||
@@ -1706,9 +1934,9 @@ ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1706 | return 0; | 1934 | return 0; |
1707 | } | 1935 | } |
1708 | 1936 | ||
1709 | if (skb_headroom(skb) < sdata->local->hw.extra_tx_headroom) { | 1937 | if (skb_headroom(skb) < sdata->local->tx_headroom) { |
1710 | if (pskb_expand_head(skb, | 1938 | if (pskb_expand_head(skb, sdata->local->tx_headroom, |
1711 | sdata->local->hw.extra_tx_headroom, 0, GFP_ATOMIC)) { | 1939 | 0, GFP_ATOMIC)) { |
1712 | dev_kfree_skb(skb); | 1940 | dev_kfree_skb(skb); |
1713 | return 0; | 1941 | return 0; |
1714 | } | 1942 | } |
@@ -1847,12 +2075,12 @@ struct sk_buff * ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id, | |||
1847 | bh_len = ap->beacon_head_len; | 2075 | bh_len = ap->beacon_head_len; |
1848 | bt_len = ap->beacon_tail_len; | 2076 | bt_len = ap->beacon_tail_len; |
1849 | 2077 | ||
1850 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 2078 | skb = dev_alloc_skb(local->tx_headroom + |
1851 | bh_len + bt_len + 256 /* maximum TIM len */); | 2079 | bh_len + bt_len + 256 /* maximum TIM len */); |
1852 | if (!skb) | 2080 | if (!skb) |
1853 | return NULL; | 2081 | return NULL; |
1854 | 2082 | ||
1855 | skb_reserve(skb, local->hw.extra_tx_headroom); | 2083 | skb_reserve(skb, local->tx_headroom); |
1856 | memcpy(skb_put(skb, bh_len), b_head, bh_len); | 2084 | memcpy(skb_put(skb, bh_len), b_head, bh_len); |
1857 | 2085 | ||
1858 | ieee80211_include_sequence(sdata, (struct ieee80211_hdr *)skb->data); | 2086 | ieee80211_include_sequence(sdata, (struct ieee80211_hdr *)skb->data); |
@@ -2376,8 +2604,7 @@ static void ieee80211_start_hard_monitor(struct ieee80211_local *local) | |||
2376 | struct ieee80211_if_init_conf conf; | 2604 | struct ieee80211_if_init_conf conf; |
2377 | 2605 | ||
2378 | if (local->open_count && local->open_count == local->monitors && | 2606 | if (local->open_count && local->open_count == local->monitors && |
2379 | !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) && | 2607 | !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) { |
2380 | local->ops->add_interface) { | ||
2381 | conf.if_id = -1; | 2608 | conf.if_id = -1; |
2382 | conf.type = IEEE80211_IF_TYPE_MNTR; | 2609 | conf.type = IEEE80211_IF_TYPE_MNTR; |
2383 | conf.mac_addr = NULL; | 2610 | conf.mac_addr = NULL; |
@@ -2420,21 +2647,14 @@ static int ieee80211_open(struct net_device *dev) | |||
2420 | } | 2647 | } |
2421 | ieee80211_start_soft_monitor(local); | 2648 | ieee80211_start_soft_monitor(local); |
2422 | 2649 | ||
2423 | if (local->ops->add_interface) { | 2650 | conf.if_id = dev->ifindex; |
2424 | conf.if_id = dev->ifindex; | 2651 | conf.type = sdata->type; |
2425 | conf.type = sdata->type; | 2652 | conf.mac_addr = dev->dev_addr; |
2426 | conf.mac_addr = dev->dev_addr; | 2653 | res = local->ops->add_interface(local_to_hw(local), &conf); |
2427 | res = local->ops->add_interface(local_to_hw(local), &conf); | 2654 | if (res) { |
2428 | if (res) { | 2655 | if (sdata->type == IEEE80211_IF_TYPE_MNTR) |
2429 | if (sdata->type == IEEE80211_IF_TYPE_MNTR) | 2656 | ieee80211_start_hard_monitor(local); |
2430 | ieee80211_start_hard_monitor(local); | 2657 | return res; |
2431 | return res; | ||
2432 | } | ||
2433 | } else { | ||
2434 | if (sdata->type != IEEE80211_IF_TYPE_STA) | ||
2435 | return -EOPNOTSUPP; | ||
2436 | if (local->open_count > 0) | ||
2437 | return -ENOBUFS; | ||
2438 | } | 2658 | } |
2439 | 2659 | ||
2440 | if (local->open_count == 0) { | 2660 | if (local->open_count == 0) { |
@@ -2941,34 +3161,6 @@ int ieee80211_radar_status(struct ieee80211_hw *hw, int channel, | |||
2941 | } | 3161 | } |
2942 | EXPORT_SYMBOL(ieee80211_radar_status); | 3162 | EXPORT_SYMBOL(ieee80211_radar_status); |
2943 | 3163 | ||
2944 | int ieee80211_set_aid_for_sta(struct ieee80211_hw *hw, u8 *peer_address, | ||
2945 | u16 aid) | ||
2946 | { | ||
2947 | struct sk_buff *skb; | ||
2948 | struct ieee80211_msg_set_aid_for_sta *msg; | ||
2949 | struct ieee80211_local *local = hw_to_local(hw); | ||
2950 | |||
2951 | /* unlikely because if this event only happens for APs, | ||
2952 | * which require an open ap device. */ | ||
2953 | if (unlikely(!local->apdev)) | ||
2954 | return 0; | ||
2955 | |||
2956 | skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) + | ||
2957 | sizeof(struct ieee80211_msg_set_aid_for_sta)); | ||
2958 | |||
2959 | if (!skb) | ||
2960 | return -ENOMEM; | ||
2961 | skb_reserve(skb, sizeof(struct ieee80211_frame_info)); | ||
2962 | |||
2963 | msg = (struct ieee80211_msg_set_aid_for_sta *) | ||
2964 | skb_put(skb, sizeof(struct ieee80211_msg_set_aid_for_sta)); | ||
2965 | memcpy(msg->sta_address, peer_address, ETH_ALEN); | ||
2966 | msg->aid = aid; | ||
2967 | |||
2968 | ieee80211_rx_mgmt(local, skb, NULL, ieee80211_msg_set_aid_for_sta); | ||
2969 | return 0; | ||
2970 | } | ||
2971 | EXPORT_SYMBOL(ieee80211_set_aid_for_sta); | ||
2972 | 3164 | ||
2973 | static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) | 3165 | static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) |
2974 | { | 3166 | { |
@@ -4284,6 +4476,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
4284 | struct ieee80211_local *local = hw_to_local(hw); | 4476 | struct ieee80211_local *local = hw_to_local(hw); |
4285 | u16 frag, type; | 4477 | u16 frag, type; |
4286 | u32 msg_type; | 4478 | u32 msg_type; |
4479 | struct ieee80211_tx_status_rtap_hdr *rthdr; | ||
4480 | struct ieee80211_sub_if_data *sdata; | ||
4481 | int monitors; | ||
4287 | 4482 | ||
4288 | if (!status) { | 4483 | if (!status) { |
4289 | printk(KERN_ERR | 4484 | printk(KERN_ERR |
@@ -4395,27 +4590,100 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
4395 | local->dot11FailedCount++; | 4590 | local->dot11FailedCount++; |
4396 | } | 4591 | } |
4397 | 4592 | ||
4398 | if (!(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS) | 4593 | msg_type = (status->flags & IEEE80211_TX_STATUS_ACK) ? |
4399 | || unlikely(!local->apdev)) { | 4594 | ieee80211_msg_tx_callback_ack : ieee80211_msg_tx_callback_fail; |
4595 | |||
4596 | /* this was a transmitted frame, but now we want to reuse it */ | ||
4597 | skb_orphan(skb); | ||
4598 | |||
4599 | if ((status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS) && | ||
4600 | local->apdev) { | ||
4601 | if (local->monitors) { | ||
4602 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
4603 | } else { | ||
4604 | skb2 = skb; | ||
4605 | skb = NULL; | ||
4606 | } | ||
4607 | |||
4608 | if (skb2) | ||
4609 | /* Send frame to hostapd */ | ||
4610 | ieee80211_rx_mgmt(local, skb2, NULL, msg_type); | ||
4611 | |||
4612 | if (!skb) | ||
4613 | return; | ||
4614 | } | ||
4615 | |||
4616 | if (!local->monitors) { | ||
4400 | dev_kfree_skb(skb); | 4617 | dev_kfree_skb(skb); |
4401 | return; | 4618 | return; |
4402 | } | 4619 | } |
4403 | 4620 | ||
4404 | msg_type = (status->flags & IEEE80211_TX_STATUS_ACK) ? | 4621 | /* send frame to monitor interfaces now */ |
4405 | ieee80211_msg_tx_callback_ack : ieee80211_msg_tx_callback_fail; | ||
4406 | 4622 | ||
4407 | /* skb was the original skb used for TX. Clone it and give the clone | 4623 | if (skb_headroom(skb) < sizeof(*rthdr)) { |
4408 | * to netif_rx(). Free original skb. */ | 4624 | printk(KERN_ERR "ieee80211_tx_status: headroom too small\n"); |
4409 | skb2 = skb_copy(skb, GFP_ATOMIC); | ||
4410 | if (!skb2) { | ||
4411 | dev_kfree_skb(skb); | 4625 | dev_kfree_skb(skb); |
4412 | return; | 4626 | return; |
4413 | } | 4627 | } |
4414 | dev_kfree_skb(skb); | ||
4415 | skb = skb2; | ||
4416 | 4628 | ||
4417 | /* Send frame to hostapd */ | 4629 | rthdr = (struct ieee80211_tx_status_rtap_hdr*) |
4418 | ieee80211_rx_mgmt(local, skb, NULL, msg_type); | 4630 | skb_push(skb, sizeof(*rthdr)); |
4631 | |||
4632 | memset(rthdr, 0, sizeof(*rthdr)); | ||
4633 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | ||
4634 | rthdr->hdr.it_present = | ||
4635 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | ||
4636 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | ||
4637 | |||
4638 | if (!(status->flags & IEEE80211_TX_STATUS_ACK) && | ||
4639 | !is_multicast_ether_addr(hdr->addr1)) | ||
4640 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | ||
4641 | |||
4642 | if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) && | ||
4643 | (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) | ||
4644 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | ||
4645 | else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) | ||
4646 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | ||
4647 | |||
4648 | rthdr->data_retries = status->retry_count; | ||
4649 | |||
4650 | read_lock(&local->sub_if_lock); | ||
4651 | monitors = local->monitors; | ||
4652 | list_for_each_entry(sdata, &local->sub_if_list, list) { | ||
4653 | /* | ||
4654 | * Using the monitors counter is possibly racy, but | ||
4655 | * if the value is wrong we simply either clone the skb | ||
4656 | * once too much or forget sending it to one monitor iface | ||
4657 | * The latter case isn't nice but fixing the race is much | ||
4658 | * more complicated. | ||
4659 | */ | ||
4660 | if (!monitors || !skb) | ||
4661 | goto out; | ||
4662 | |||
4663 | if (sdata->type == IEEE80211_IF_TYPE_MNTR) { | ||
4664 | if (!netif_running(sdata->dev)) | ||
4665 | continue; | ||
4666 | monitors--; | ||
4667 | if (monitors) | ||
4668 | skb2 = skb_clone(skb, GFP_KERNEL); | ||
4669 | else | ||
4670 | skb2 = NULL; | ||
4671 | skb->dev = sdata->dev; | ||
4672 | /* XXX: is this sufficient for BPF? */ | ||
4673 | skb_set_mac_header(skb, 0); | ||
4674 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
4675 | skb->pkt_type = PACKET_OTHERHOST; | ||
4676 | skb->protocol = htons(ETH_P_802_2); | ||
4677 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
4678 | netif_rx(skb); | ||
4679 | skb = skb2; | ||
4680 | break; | ||
4681 | } | ||
4682 | } | ||
4683 | out: | ||
4684 | read_unlock(&local->sub_if_lock); | ||
4685 | if (skb) | ||
4686 | dev_kfree_skb(skb); | ||
4419 | } | 4687 | } |
4420 | EXPORT_SYMBOL(ieee80211_tx_status); | 4688 | EXPORT_SYMBOL(ieee80211_tx_status); |
4421 | 4689 | ||
@@ -4619,6 +4887,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
4619 | ((sizeof(struct ieee80211_local) + | 4887 | ((sizeof(struct ieee80211_local) + |
4620 | NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); | 4888 | NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); |
4621 | 4889 | ||
4890 | BUG_ON(!ops->tx); | ||
4891 | BUG_ON(!ops->config); | ||
4892 | BUG_ON(!ops->add_interface); | ||
4622 | local->ops = ops; | 4893 | local->ops = ops; |
4623 | 4894 | ||
4624 | /* for now, mdev needs sub_if_data :/ */ | 4895 | /* for now, mdev needs sub_if_data :/ */ |
@@ -4647,8 +4918,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
4647 | local->short_retry_limit = 7; | 4918 | local->short_retry_limit = 7; |
4648 | local->long_retry_limit = 4; | 4919 | local->long_retry_limit = 4; |
4649 | local->hw.conf.radio_enabled = 1; | 4920 | local->hw.conf.radio_enabled = 1; |
4650 | local->rate_ctrl_num_up = RATE_CONTROL_NUM_UP; | ||
4651 | local->rate_ctrl_num_down = RATE_CONTROL_NUM_DOWN; | ||
4652 | 4921 | ||
4653 | local->enabled_modes = (unsigned int) -1; | 4922 | local->enabled_modes = (unsigned int) -1; |
4654 | 4923 | ||
@@ -4712,6 +4981,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
4712 | goto fail_workqueue; | 4981 | goto fail_workqueue; |
4713 | } | 4982 | } |
4714 | 4983 | ||
4984 | /* | ||
4985 | * The hardware needs headroom for sending the frame, | ||
4986 | * and we need some headroom for passing the frame to monitor | ||
4987 | * interfaces, but never both at the same time. | ||
4988 | */ | ||
4989 | local->tx_headroom = max(local->hw.extra_tx_headroom, | ||
4990 | sizeof(struct ieee80211_tx_status_rtap_hdr)); | ||
4991 | |||
4715 | debugfs_hw_add(local); | 4992 | debugfs_hw_add(local); |
4716 | 4993 | ||
4717 | local->hw.conf.beacon_int = 1000; | 4994 | local->hw.conf.beacon_int = 1000; |