diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-11-09 04:15:42 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-09 16:01:02 -0500 |
commit | 6e3e939f3b1bf8534b32ad09ff199d88800835a0 (patch) | |
tree | 78ec0638efbade2fdb0bebb7bad71410ded2e6c6 /include/linux | |
parent | 4fdbff0770bea059621bc4906fb7c7f5879f3ae1 (diff) |
net: add wireless TX status socket option
The 802.1X EAPOL handshake hostapd does requires
knowing whether the frame was ack'ed by the peer.
Currently, we fudge this pretty badly by not even
transmitting the frame as a normal data frame but
injecting it with radiotap and getting the status
out of radiotap monitor as well. This is rather
complex, confuses users (mon.wlan0 presence) and
doesn't work with all hardware.
To get rid of that hack, introduce a real wifi TX
status option for data frame transmissions.
This works similar to the existing TX timestamping
in that it reflects the SKB back to the socket's
error queue with a SCM_WIFI_STATUS cmsg that has
an int indicating ACK status (0/1).
Since it is possible that at some point we will
want to have TX timestamping and wifi status in a
single errqueue SKB (there's little point in not
doing that), redefine SO_EE_ORIGIN_TIMESTAMPING
to SO_EE_ORIGIN_TXSTATUS which can collect more
than just the timestamp; keep the old constant
as an alias of course. Currently the internal APIs
don't make that possible, but it wouldn't be hard
to split them up in a way that makes it possible.
Thanks to Neil Horman for helping me figure out
the functions that add the control messages.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/errqueue.h | 3 | ||||
-rw-r--r-- | include/linux/skbuff.h | 19 |
2 files changed, 19 insertions, 3 deletions
diff --git a/include/linux/errqueue.h b/include/linux/errqueue.h index 034072cea853..c9f522bd17e4 100644 --- a/include/linux/errqueue.h +++ b/include/linux/errqueue.h | |||
@@ -17,7 +17,8 @@ struct sock_extended_err { | |||
17 | #define SO_EE_ORIGIN_LOCAL 1 | 17 | #define SO_EE_ORIGIN_LOCAL 1 |
18 | #define SO_EE_ORIGIN_ICMP 2 | 18 | #define SO_EE_ORIGIN_ICMP 2 |
19 | #define SO_EE_ORIGIN_ICMP6 3 | 19 | #define SO_EE_ORIGIN_ICMP6 3 |
20 | #define SO_EE_ORIGIN_TIMESTAMPING 4 | 20 | #define SO_EE_ORIGIN_TXSTATUS 4 |
21 | #define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS | ||
21 | 22 | ||
22 | #define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1)) | 23 | #define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1)) |
23 | 24 | ||
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 6a6b352326d7..ff7e1306a2d2 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -218,6 +218,9 @@ enum { | |||
218 | 218 | ||
219 | /* device driver supports TX zero-copy buffers */ | 219 | /* device driver supports TX zero-copy buffers */ |
220 | SKBTX_DEV_ZEROCOPY = 1 << 4, | 220 | SKBTX_DEV_ZEROCOPY = 1 << 4, |
221 | |||
222 | /* generate wifi status information (where possible) */ | ||
223 | SKBTX_WIFI_STATUS = 1 << 5, | ||
221 | }; | 224 | }; |
222 | 225 | ||
223 | /* | 226 | /* |
@@ -352,6 +355,8 @@ typedef unsigned char *sk_buff_data_t; | |||
352 | * @ooo_okay: allow the mapping of a socket to a queue to be changed | 355 | * @ooo_okay: allow the mapping of a socket to a queue to be changed |
353 | * @l4_rxhash: indicate rxhash is a canonical 4-tuple hash over transport | 356 | * @l4_rxhash: indicate rxhash is a canonical 4-tuple hash over transport |
354 | * ports. | 357 | * ports. |
358 | * @wifi_acked_valid: wifi_acked was set | ||
359 | * @wifi_acked: whether frame was acked on wifi or not | ||
355 | * @dma_cookie: a cookie to one of several possible DMA operations | 360 | * @dma_cookie: a cookie to one of several possible DMA operations |
356 | * done by skb DMA functions | 361 | * done by skb DMA functions |
357 | * @secmark: security marking | 362 | * @secmark: security marking |
@@ -445,10 +450,11 @@ struct sk_buff { | |||
445 | #endif | 450 | #endif |
446 | __u8 ooo_okay:1; | 451 | __u8 ooo_okay:1; |
447 | __u8 l4_rxhash:1; | 452 | __u8 l4_rxhash:1; |
453 | __u8 wifi_acked_valid:1; | ||
454 | __u8 wifi_acked:1; | ||
455 | /* 10/12 bit hole (depending on ndisc_nodetype presence) */ | ||
448 | kmemcheck_bitfield_end(flags2); | 456 | kmemcheck_bitfield_end(flags2); |
449 | 457 | ||
450 | /* 0/13 bit hole */ | ||
451 | |||
452 | #ifdef CONFIG_NET_DMA | 458 | #ifdef CONFIG_NET_DMA |
453 | dma_cookie_t dma_cookie; | 459 | dma_cookie_t dma_cookie; |
454 | #endif | 460 | #endif |
@@ -2263,6 +2269,15 @@ static inline void skb_tx_timestamp(struct sk_buff *skb) | |||
2263 | sw_tx_timestamp(skb); | 2269 | sw_tx_timestamp(skb); |
2264 | } | 2270 | } |
2265 | 2271 | ||
2272 | /** | ||
2273 | * skb_complete_wifi_ack - deliver skb with wifi status | ||
2274 | * | ||
2275 | * @skb: the original outgoing packet | ||
2276 | * @acked: ack status | ||
2277 | * | ||
2278 | */ | ||
2279 | void skb_complete_wifi_ack(struct sk_buff *skb, bool acked); | ||
2280 | |||
2266 | extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len); | 2281 | extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len); |
2267 | extern __sum16 __skb_checksum_complete(struct sk_buff *skb); | 2282 | extern __sum16 __skb_checksum_complete(struct sk_buff *skb); |
2268 | 2283 | ||