aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/sock.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-09 04:15:42 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-09 16:01:02 -0500
commit6e3e939f3b1bf8534b32ad09ff199d88800835a0 (patch)
tree78ec0638efbade2fdb0bebb7bad71410ded2e6c6 /net/core/sock.c
parent4fdbff0770bea059621bc4906fb7c7f5879f3ae1 (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 'net/core/sock.c')
-rw-r--r--net/core/sock.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index 4ed7b1d12f5e..cbdf51c0d5ac 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -740,6 +740,11 @@ set_rcvbuf:
740 case SO_RXQ_OVFL: 740 case SO_RXQ_OVFL:
741 sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool); 741 sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
742 break; 742 break;
743
744 case SO_WIFI_STATUS:
745 sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
746 break;
747
743 default: 748 default:
744 ret = -ENOPROTOOPT; 749 ret = -ENOPROTOOPT;
745 break; 750 break;
@@ -961,6 +966,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
961 v.val = !!sock_flag(sk, SOCK_RXQ_OVFL); 966 v.val = !!sock_flag(sk, SOCK_RXQ_OVFL);
962 break; 967 break;
963 968
969 case SO_WIFI_STATUS:
970 v.val = !!sock_flag(sk, SOCK_WIFI_STATUS);
971 break;
972
964 default: 973 default:
965 return -ENOPROTOOPT; 974 return -ENOPROTOOPT;
966 } 975 }