aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-10-07 08:01:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-10-11 16:41:19 -0400
commit73b9f03a813d66484105c4ed648a1aa66fa267aa (patch)
tree37a60a9c61f4537c898a5d863e93f1b445864d7d
parenta26eb27ab430147a82e4a9f2f1ebfadf03d99550 (diff)
mac80211: parse radiotap header earlier
We can now move the radiotap header parsing into ieee80211_monitor_start_xmit(). This moves it out of the hotpath, and also helps the code since now the radiotap header will no longer be present in ieee80211_xmit() etc. which is easier to understand. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/net/mac80211.h4
-rw-r--r--net/mac80211/tx.c201
2 files changed, 89 insertions, 116 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 05f102197cfe..021317367d55 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -349,8 +349,6 @@ struct ieee80211_bss_conf {
349 * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted 349 * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted
350 * after TX status because the destination was asleep, it must not 350 * after TX status because the destination was asleep, it must not
351 * be modified again (no seqno assignment, crypto, etc.) 351 * be modified again (no seqno assignment, crypto, etc.)
352 * @IEEE80211_TX_INTFL_HAS_RADIOTAP: This frame was injected and still
353 * has a radiotap header at skb->data.
354 * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211 352 * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211
355 * MLME command (internal to mac80211 to figure out whether to send TX 353 * MLME command (internal to mac80211 to figure out whether to send TX
356 * status to user space) 354 * status to user space)
@@ -402,7 +400,7 @@ enum mac80211_tx_control_flags {
402 IEEE80211_TX_CTL_POLL_RESPONSE = BIT(17), 400 IEEE80211_TX_CTL_POLL_RESPONSE = BIT(17),
403 IEEE80211_TX_CTL_MORE_FRAMES = BIT(18), 401 IEEE80211_TX_CTL_MORE_FRAMES = BIT(18),
404 IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19), 402 IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19),
405 IEEE80211_TX_INTFL_HAS_RADIOTAP = BIT(20), 403 /* hole at 20, use later */
406 IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21), 404 IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21),
407 IEEE80211_TX_CTL_LDPC = BIT(22), 405 IEEE80211_TX_CTL_LDPC = BIT(22),
408 IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24), 406 IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24),
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7f7d45cf77d1..3d2b6b2749f6 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1035,103 +1035,6 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
1035 1035
1036/* actual transmit path */ 1036/* actual transmit path */
1037 1037
1038/*
1039 * deal with packet injection down monitor interface
1040 * with Radiotap Header -- only called for monitor mode interface
1041 */
1042static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
1043 struct sk_buff *skb)
1044{
1045 /*
1046 * this is the moment to interpret and discard the radiotap header that
1047 * must be at the start of the packet injected in Monitor mode
1048 *
1049 * Need to take some care with endian-ness since radiotap
1050 * args are little-endian
1051 */
1052
1053 struct ieee80211_radiotap_iterator iterator;
1054 struct ieee80211_radiotap_header *rthdr =
1055 (struct ieee80211_radiotap_header *) skb->data;
1056 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1057 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
1058 NULL);
1059 u16 txflags;
1060
1061 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
1062 IEEE80211_TX_CTL_DONTFRAG;
1063
1064 /*
1065 * for every radiotap entry that is present
1066 * (ieee80211_radiotap_iterator_next returns -ENOENT when no more
1067 * entries present, or -EINVAL on error)
1068 */
1069
1070 while (!ret) {
1071 ret = ieee80211_radiotap_iterator_next(&iterator);
1072
1073 if (ret)
1074 continue;
1075
1076 /* see if this argument is something we can use */
1077 switch (iterator.this_arg_index) {
1078 /*
1079 * You must take care when dereferencing iterator.this_arg
1080 * for multibyte types... the pointer is not aligned. Use
1081 * get_unaligned((type *)iterator.this_arg) to dereference
1082 * iterator.this_arg for type "type" safely on all arches.
1083 */
1084 case IEEE80211_RADIOTAP_FLAGS:
1085 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) {
1086 /*
1087 * this indicates that the skb we have been
1088 * handed has the 32-bit FCS CRC at the end...
1089 * we should react to that by snipping it off
1090 * because it will be recomputed and added
1091 * on transmission
1092 */
1093 if (skb->len < (iterator._max_length + FCS_LEN))
1094 return false;
1095
1096 skb_trim(skb, skb->len - FCS_LEN);
1097 }
1098 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
1099 info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
1100 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
1101 info->flags &= ~IEEE80211_TX_CTL_DONTFRAG;
1102 break;
1103
1104 case IEEE80211_RADIOTAP_TX_FLAGS:
1105 txflags = le16_to_cpu(get_unaligned((__le16*)
1106 iterator.this_arg));
1107 if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK)
1108 info->flags |= IEEE80211_TX_CTL_NO_ACK;
1109 break;
1110
1111 /*
1112 * Please update the file
1113 * Documentation/networking/mac80211-injection.txt
1114 * when parsing new fields here.
1115 */
1116
1117 default:
1118 break;
1119 }
1120 }
1121
1122 if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
1123 return false;
1124
1125 /*
1126 * remove the radiotap header
1127 * iterator->_max_length was sanity-checked against
1128 * skb->len by iterator init
1129 */
1130 skb_pull(skb, iterator._max_length);
1131
1132 return true;
1133}
1134
1135static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, 1038static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
1136 struct sk_buff *skb, 1039 struct sk_buff *skb,
1137 struct ieee80211_tx_info *info, 1040 struct ieee80211_tx_info *info,
@@ -1205,19 +1108,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1205 tx->sdata = sdata; 1108 tx->sdata = sdata;
1206 tx->channel = local->hw.conf.channel; 1109 tx->channel = local->hw.conf.channel;
1207 1110
1208 /* process and remove the injection radiotap header */
1209 if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) {
1210 if (!__ieee80211_parse_tx_radiotap(tx, skb))
1211 return TX_DROP;
1212
1213 /*
1214 * __ieee80211_parse_tx_radiotap has now removed
1215 * the radiotap header that was present and pre-filled
1216 * 'tx' with tx control information.
1217 */
1218 info->flags &= ~IEEE80211_TX_INTFL_HAS_RADIOTAP;
1219 }
1220
1221 /* 1111 /*
1222 * If this flag is set to true anywhere, and we get here, 1112 * If this flag is set to true anywhere, and we get here,
1223 * we are doing the needed processing, so remove the flag 1113 * we are doing the needed processing, so remove the flag
@@ -1559,6 +1449,89 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
1559 rcu_read_unlock(); 1449 rcu_read_unlock();
1560} 1450}
1561 1451
1452static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb)
1453{
1454 struct ieee80211_radiotap_iterator iterator;
1455 struct ieee80211_radiotap_header *rthdr =
1456 (struct ieee80211_radiotap_header *) skb->data;
1457 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1458 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
1459 NULL);
1460 u16 txflags;
1461
1462 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
1463 IEEE80211_TX_CTL_DONTFRAG;
1464
1465 /*
1466 * for every radiotap entry that is present
1467 * (ieee80211_radiotap_iterator_next returns -ENOENT when no more
1468 * entries present, or -EINVAL on error)
1469 */
1470
1471 while (!ret) {
1472 ret = ieee80211_radiotap_iterator_next(&iterator);
1473
1474 if (ret)
1475 continue;
1476
1477 /* see if this argument is something we can use */
1478 switch (iterator.this_arg_index) {
1479 /*
1480 * You must take care when dereferencing iterator.this_arg
1481 * for multibyte types... the pointer is not aligned. Use
1482 * get_unaligned((type *)iterator.this_arg) to dereference
1483 * iterator.this_arg for type "type" safely on all arches.
1484 */
1485 case IEEE80211_RADIOTAP_FLAGS:
1486 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) {
1487 /*
1488 * this indicates that the skb we have been
1489 * handed has the 32-bit FCS CRC at the end...
1490 * we should react to that by snipping it off
1491 * because it will be recomputed and added
1492 * on transmission
1493 */
1494 if (skb->len < (iterator._max_length + FCS_LEN))
1495 return false;
1496
1497 skb_trim(skb, skb->len - FCS_LEN);
1498 }
1499 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
1500 info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
1501 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
1502 info->flags &= ~IEEE80211_TX_CTL_DONTFRAG;
1503 break;
1504
1505 case IEEE80211_RADIOTAP_TX_FLAGS:
1506 txflags = get_unaligned_le16(iterator.this_arg);
1507 if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK)
1508 info->flags |= IEEE80211_TX_CTL_NO_ACK;
1509 break;
1510
1511 /*
1512 * Please update the file
1513 * Documentation/networking/mac80211-injection.txt
1514 * when parsing new fields here.
1515 */
1516
1517 default:
1518 break;
1519 }
1520 }
1521
1522 if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
1523 return false;
1524
1525 /*
1526 * remove the radiotap header
1527 * iterator->_max_length was sanity-checked against
1528 * skb->len by iterator init
1529 */
1530 skb_pull(skb, iterator._max_length);
1531
1532 return true;
1533}
1534
1562netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, 1535netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1563 struct net_device *dev) 1536 struct net_device *dev)
1564{ 1537{
@@ -1646,8 +1619,11 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1646 memset(info, 0, sizeof(*info)); 1619 memset(info, 0, sizeof(*info));
1647 1620
1648 info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS | 1621 info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
1649 IEEE80211_TX_CTL_INJECTED | 1622 IEEE80211_TX_CTL_INJECTED;
1650 IEEE80211_TX_INTFL_HAS_RADIOTAP; 1623
1624 /* process and remove the injection radiotap header */
1625 if (!ieee80211_parse_tx_radiotap(skb))
1626 goto fail;
1651 1627
1652 rcu_read_lock(); 1628 rcu_read_lock();
1653 1629
@@ -1674,7 +1650,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1674 } 1650 }
1675 } 1651 }
1676 1652
1677 /* pass the radiotap header up to xmit */
1678 ieee80211_xmit(sdata, skb); 1653 ieee80211_xmit(sdata, skb);
1679 rcu_read_unlock(); 1654 rcu_read_unlock();
1680 1655