aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h55
-rw-r--r--include/uapi/linux/nl80211.h125
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/nl80211.c295
4 files changed, 474 insertions, 4 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d3a73818e44c..7e6569e1f16f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -19,6 +19,7 @@
19#include <linux/nl80211.h> 19#include <linux/nl80211.h>
20#include <linux/if_ether.h> 20#include <linux/if_ether.h>
21#include <linux/ieee80211.h> 21#include <linux/ieee80211.h>
22#include <linux/net.h>
22#include <net/regulatory.h> 23#include <net/regulatory.h>
23 24
24/** 25/**
@@ -1588,6 +1589,41 @@ struct cfg80211_wowlan_trig_pkt_pattern {
1588}; 1589};
1589 1590
1590/** 1591/**
1592 * struct cfg80211_wowlan_tcp - TCP connection parameters
1593 *
1594 * @sock: (internal) socket for source port allocation
1595 * @src: source IP address
1596 * @dst: destination IP address
1597 * @dst_mac: destination MAC address
1598 * @src_port: source port
1599 * @dst_port: destination port
1600 * @payload_len: data payload length
1601 * @payload: data payload buffer
1602 * @payload_seq: payload sequence stamping configuration
1603 * @data_interval: interval at which to send data packets
1604 * @wake_len: wakeup payload match length
1605 * @wake_data: wakeup payload match data
1606 * @wake_mask: wakeup payload match mask
1607 * @tokens_size: length of the tokens buffer
1608 * @payload_tok: payload token usage configuration
1609 */
1610struct cfg80211_wowlan_tcp {
1611 struct socket *sock;
1612 __be32 src, dst;
1613 u16 src_port, dst_port;
1614 u8 dst_mac[ETH_ALEN];
1615 int payload_len;
1616 const u8 *payload;
1617 struct nl80211_wowlan_tcp_data_seq payload_seq;
1618 u32 data_interval;
1619 u32 wake_len;
1620 const u8 *wake_data, *wake_mask;
1621 u32 tokens_size;
1622 /* must be last, variable member */
1623 struct nl80211_wowlan_tcp_data_token payload_tok;
1624};
1625
1626/**
1591 * struct cfg80211_wowlan - Wake on Wireless-LAN support info 1627 * struct cfg80211_wowlan - Wake on Wireless-LAN support info
1592 * 1628 *
1593 * This structure defines the enabled WoWLAN triggers for the device. 1629 * This structure defines the enabled WoWLAN triggers for the device.
@@ -1601,12 +1637,15 @@ struct cfg80211_wowlan_trig_pkt_pattern {
1601 * @eap_identity_req: wake up on EAP identity request packet 1637 * @eap_identity_req: wake up on EAP identity request packet
1602 * @four_way_handshake: wake up on 4-way handshake 1638 * @four_way_handshake: wake up on 4-way handshake
1603 * @rfkill_release: wake up when rfkill is released 1639 * @rfkill_release: wake up when rfkill is released
1640 * @tcp: TCP connection establishment/wakeup parameters, see nl80211.h.
1641 * NULL if not configured.
1604 */ 1642 */
1605struct cfg80211_wowlan { 1643struct cfg80211_wowlan {
1606 bool any, disconnect, magic_pkt, gtk_rekey_failure, 1644 bool any, disconnect, magic_pkt, gtk_rekey_failure,
1607 eap_identity_req, four_way_handshake, 1645 eap_identity_req, four_way_handshake,
1608 rfkill_release; 1646 rfkill_release;
1609 struct cfg80211_wowlan_trig_pkt_pattern *patterns; 1647 struct cfg80211_wowlan_trig_pkt_pattern *patterns;
1648 struct cfg80211_wowlan_tcp *tcp;
1610 int n_patterns; 1649 int n_patterns;
1611}; 1650};
1612 1651
@@ -1626,11 +1665,15 @@ struct cfg80211_wowlan {
1626 * frame triggers an 802.3 frame should be reported, for 1665 * frame triggers an 802.3 frame should be reported, for
1627 * disconnect due to deauth 802.11 frame. This indicates which 1666 * disconnect due to deauth 802.11 frame. This indicates which
1628 * it is. 1667 * it is.
1668 * @tcp_match: TCP wakeup packet received
1669 * @tcp_connlost: TCP connection lost or failed to establish
1670 * @tcp_nomoretokens: TCP data ran out of tokens
1629 */ 1671 */
1630struct cfg80211_wowlan_wakeup { 1672struct cfg80211_wowlan_wakeup {
1631 bool disconnect, magic_pkt, gtk_rekey_failure, 1673 bool disconnect, magic_pkt, gtk_rekey_failure,
1632 eap_identity_req, four_way_handshake, 1674 eap_identity_req, four_way_handshake,
1633 rfkill_release, packet_80211; 1675 rfkill_release, packet_80211,
1676 tcp_match, tcp_connlost, tcp_nomoretokens;
1634 s32 pattern_idx; 1677 s32 pattern_idx;
1635 u32 packet_present_len, packet_len; 1678 u32 packet_present_len, packet_len;
1636 const void *packet; 1679 const void *packet;
@@ -2285,6 +2328,14 @@ enum wiphy_wowlan_support_flags {
2285 WIPHY_WOWLAN_RFKILL_RELEASE = BIT(7), 2328 WIPHY_WOWLAN_RFKILL_RELEASE = BIT(7),
2286}; 2329};
2287 2330
2331struct wiphy_wowlan_tcp_support {
2332 const struct nl80211_wowlan_tcp_data_token_feature *tok;
2333 u32 data_payload_max;
2334 u32 data_interval_max;
2335 u32 wake_payload_max;
2336 bool seq;
2337};
2338
2288/** 2339/**
2289 * struct wiphy_wowlan_support - WoWLAN support data 2340 * struct wiphy_wowlan_support - WoWLAN support data
2290 * @flags: see &enum wiphy_wowlan_support_flags 2341 * @flags: see &enum wiphy_wowlan_support_flags
@@ -2293,6 +2344,7 @@ enum wiphy_wowlan_support_flags {
2293 * @pattern_max_len: maximum length of each pattern 2344 * @pattern_max_len: maximum length of each pattern
2294 * @pattern_min_len: minimum length of each pattern 2345 * @pattern_min_len: minimum length of each pattern
2295 * @max_pkt_offset: maximum Rx packet offset 2346 * @max_pkt_offset: maximum Rx packet offset
2347 * @tcp: TCP wakeup support information
2296 */ 2348 */
2297struct wiphy_wowlan_support { 2349struct wiphy_wowlan_support {
2298 u32 flags; 2350 u32 flags;
@@ -2300,6 +2352,7 @@ struct wiphy_wowlan_support {
2300 int pattern_max_len; 2352 int pattern_max_len;
2301 int pattern_min_len; 2353 int pattern_min_len;
2302 int max_pkt_offset; 2354 int max_pkt_offset;
2355 const struct wiphy_wowlan_tcp_support *tcp;
2303}; 2356};
2304 2357
2305/** 2358/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index eb7b32247ec5..5309b34930ea 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2991,6 +2991,17 @@ struct nl80211_wowlan_pattern_support {
2991 * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN: Original length of the 802.3 2991 * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN: Original length of the 802.3
2992 * packet, may be bigger than the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 2992 * packet, may be bigger than the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023
2993 * attribute if the packet was truncated somewhere. 2993 * attribute if the packet was truncated somewhere.
2994 * @NL80211_WOWLAN_TRIG_TCP_CONNECTION: TCP connection wake, see DOC section
2995 * "TCP connection wakeup" for more details. This is a nested attribute
2996 * containing the exact information for establishing and keeping alive
2997 * the TCP connection.
2998 * @NL80211_WOWLAN_TRIG_TCP_WAKEUP_MATCH: For wakeup reporting only, the
2999 * wakeup packet was received on the TCP connection
3000 * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST: For wakeup reporting only, the
3001 * TCP connection was lost or failed to be established
3002 * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS: For wakeup reporting only,
3003 * the TCP connection ran out of tokens to use for data to send to the
3004 * service
2994 * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers 3005 * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers
2995 * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number 3006 * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number
2996 * 3007 *
@@ -3012,6 +3023,10 @@ enum nl80211_wowlan_triggers {
3012 NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN, 3023 NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN,
3013 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023, 3024 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023,
3014 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN, 3025 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN,
3026 NL80211_WOWLAN_TRIG_TCP_CONNECTION,
3027 NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH,
3028 NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST,
3029 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS,
3015 3030
3016 /* keep last */ 3031 /* keep last */
3017 NUM_NL80211_WOWLAN_TRIG, 3032 NUM_NL80211_WOWLAN_TRIG,
@@ -3019,6 +3034,116 @@ enum nl80211_wowlan_triggers {
3019}; 3034};
3020 3035
3021/** 3036/**
3037 * DOC: TCP connection wakeup
3038 *
3039 * Some devices can establish a TCP connection in order to be woken up by a
3040 * packet coming in from outside their network segment, or behind NAT. If
3041 * configured, the device will establish a TCP connection to the given
3042 * service, and periodically send data to that service. The first data
3043 * packet is usually transmitted after SYN/ACK, also ACKing the SYN/ACK.
3044 * The data packets can optionally include a (little endian) sequence
3045 * number (in the TCP payload!) that is generated by the device, and, also
3046 * optionally, a token from a list of tokens. This serves as a keep-alive
3047 * with the service, and for NATed connections, etc.
3048 *
3049 * During this keep-alive period, the server doesn't send any data to the
3050 * client. When receiving data, it is compared against the wakeup pattern
3051 * (and mask) and if it matches, the host is woken up. Similarly, if the
3052 * connection breaks or cannot be established to start with, the host is
3053 * also woken up.
3054 *
3055 * Developer's note: ARP offload is required for this, otherwise TCP
3056 * response packets might not go through correctly.
3057 */
3058
3059/**
3060 * struct nl80211_wowlan_tcp_data_seq - WoWLAN TCP data sequence
3061 * @start: starting value
3062 * @offset: offset of sequence number in packet
3063 * @len: length of the sequence value to write, 1 through 4
3064 *
3065 * Note: don't confuse with the TCP sequence number(s), this is for the
3066 * keepalive packet payload. The actual value is written into the packet
3067 * in little endian.
3068 */
3069struct nl80211_wowlan_tcp_data_seq {
3070 __u32 start, offset, len;
3071};
3072
3073/**
3074 * struct nl80211_wowlan_tcp_data_token - WoWLAN TCP data token config
3075 * @offset: offset of token in packet
3076 * @len: length of each token
3077 * @token_stream: stream of data to be used for the tokens, the length must
3078 * be a multiple of @len for this to make sense
3079 */
3080struct nl80211_wowlan_tcp_data_token {
3081 __u32 offset, len;
3082 __u8 token_stream[];
3083};
3084
3085/**
3086 * struct nl80211_wowlan_tcp_data_token_feature - data token features
3087 * @min_len: minimum token length
3088 * @max_len: maximum token length
3089 * @bufsize: total available token buffer size (max size of @token_stream)
3090 */
3091struct nl80211_wowlan_tcp_data_token_feature {
3092 __u32 min_len, max_len, bufsize;
3093};
3094
3095/**
3096 * enum nl80211_wowlan_tcp_attrs - WoWLAN TCP connection parameters
3097 * @__NL80211_WOWLAN_TCP_INVALID: invalid number for nested attributes
3098 * @NL80211_WOWLAN_TCP_SRC_IPV4: source IPv4 address (in network byte order)
3099 * @NL80211_WOWLAN_TCP_DST_IPV4: destination IPv4 address
3100 * (in network byte order)
3101 * @NL80211_WOWLAN_TCP_DST_MAC: destination MAC address, this is given because
3102 * route lookup when configured might be invalid by the time we suspend,
3103 * and doing a route lookup when suspending is no longer possible as it
3104 * might require ARP querying.
3105 * @NL80211_WOWLAN_TCP_SRC_PORT: source port (u16); optional, if not given a
3106 * socket and port will be allocated
3107 * @NL80211_WOWLAN_TCP_DST_PORT: destination port (u16)
3108 * @NL80211_WOWLAN_TCP_DATA_PAYLOAD: data packet payload, at least one byte.
3109 * For feature advertising, a u32 attribute holding the maximum length
3110 * of the data payload.
3111 * @NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ: data packet sequence configuration
3112 * (if desired), a &struct nl80211_wowlan_tcp_data_seq. For feature
3113 * advertising it is just a flag
3114 * @NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN: data packet token configuration,
3115 * see &struct nl80211_wowlan_tcp_data_token and for advertising see
3116 * &struct nl80211_wowlan_tcp_data_token_feature.
3117 * @NL80211_WOWLAN_TCP_DATA_INTERVAL: data interval in seconds, maximum
3118 * interval in feature advertising (u32)
3119 * @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a
3120 * u32 attribute holding the maximum length
3121 * @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for
3122 * feature advertising. The mask works like @NL80211_WOWLAN_PKTPAT_MASK
3123 * but on the TCP payload only.
3124 * @NUM_NL80211_WOWLAN_TCP: number of TCP attributes
3125 * @MAX_NL80211_WOWLAN_TCP: highest attribute number
3126 */
3127enum nl80211_wowlan_tcp_attrs {
3128 __NL80211_WOWLAN_TCP_INVALID,
3129 NL80211_WOWLAN_TCP_SRC_IPV4,
3130 NL80211_WOWLAN_TCP_DST_IPV4,
3131 NL80211_WOWLAN_TCP_DST_MAC,
3132 NL80211_WOWLAN_TCP_SRC_PORT,
3133 NL80211_WOWLAN_TCP_DST_PORT,
3134 NL80211_WOWLAN_TCP_DATA_PAYLOAD,
3135 NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
3136 NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
3137 NL80211_WOWLAN_TCP_DATA_INTERVAL,
3138 NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
3139 NL80211_WOWLAN_TCP_WAKE_MASK,
3140
3141 /* keep last */
3142 NUM_NL80211_WOWLAN_TCP,
3143 MAX_NL80211_WOWLAN_TCP = NUM_NL80211_WOWLAN_TCP - 1
3144};
3145
3146/**
3022 * enum nl80211_iface_limit_attrs - limit attributes 3147 * enum nl80211_iface_limit_attrs - limit attributes
3023 * @NL80211_IFACE_LIMIT_UNSPEC: (reserved) 3148 * @NL80211_IFACE_LIMIT_UNSPEC: (reserved)
3024 * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that 3149 * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 37d70dc2fe82..949c9573d8d7 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -108,6 +108,9 @@ cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
108 for (i = 0; i < rdev->wowlan->n_patterns; i++) 108 for (i = 0; i < rdev->wowlan->n_patterns; i++)
109 kfree(rdev->wowlan->patterns[i].mask); 109 kfree(rdev->wowlan->patterns[i].mask);
110 kfree(rdev->wowlan->patterns); 110 kfree(rdev->wowlan->patterns);
111 if (rdev->wowlan->tcp && rdev->wowlan->tcp->sock)
112 sock_release(rdev->wowlan->tcp->sock);
113 kfree(rdev->wowlan->tcp);
111 kfree(rdev->wowlan); 114 kfree(rdev->wowlan);
112} 115}
113 116
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cc0fad30b8c9..d29a461b4981 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -19,6 +19,7 @@
19#include <net/genetlink.h> 19#include <net/genetlink.h>
20#include <net/cfg80211.h> 20#include <net/cfg80211.h>
21#include <net/sock.h> 21#include <net/sock.h>
22#include <net/inet_connection_sock.h>
22#include "core.h" 23#include "core.h"
23#include "nl80211.h" 24#include "nl80211.h"
24#include "reg.h" 25#include "reg.h"
@@ -399,6 +400,26 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
399 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG }, 400 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
400 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG }, 401 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
401 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG }, 402 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
403 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
404};
405
406static const struct nla_policy
407nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
408 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
409 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
410 [NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
411 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
412 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
413 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
414 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
415 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
416 },
417 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
418 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
419 },
420 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
421 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
422 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
402}; 423};
403 424
404/* policy for GTK rekey offload attributes */ 425/* policy for GTK rekey offload attributes */
@@ -872,6 +893,48 @@ nla_put_failure:
872 return -ENOBUFS; 893 return -ENOBUFS;
873} 894}
874 895
896#ifdef CONFIG_PM
897static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
898 struct sk_buff *msg)
899{
900 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp;
901 struct nlattr *nl_tcp;
902
903 if (!tcp)
904 return 0;
905
906 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
907 if (!nl_tcp)
908 return -ENOBUFS;
909
910 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
911 tcp->data_payload_max))
912 return -ENOBUFS;
913
914 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
915 tcp->data_payload_max))
916 return -ENOBUFS;
917
918 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
919 return -ENOBUFS;
920
921 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
922 sizeof(*tcp->tok), tcp->tok))
923 return -ENOBUFS;
924
925 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
926 tcp->data_interval_max))
927 return -ENOBUFS;
928
929 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
930 tcp->wake_payload_max))
931 return -ENOBUFS;
932
933 nla_nest_end(msg, nl_tcp);
934 return 0;
935}
936#endif
937
875static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, 938static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags,
876 struct cfg80211_registered_device *dev) 939 struct cfg80211_registered_device *dev)
877{ 940{
@@ -1246,6 +1309,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
1246 goto nla_put_failure; 1309 goto nla_put_failure;
1247 } 1310 }
1248 1311
1312 if (nl80211_send_wowlan_tcp_caps(dev, msg))
1313 goto nla_put_failure;
1314
1249 nla_nest_end(msg, nl_wowlan); 1315 nla_nest_end(msg, nl_wowlan);
1250 } 1316 }
1251#endif 1317#endif
@@ -6930,16 +6996,67 @@ static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
6930 return 0; 6996 return 0;
6931} 6997}
6932 6998
6999static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
7000 struct cfg80211_wowlan_tcp *tcp)
7001{
7002 struct nlattr *nl_tcp;
7003
7004 if (!tcp)
7005 return 0;
7006
7007 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
7008 if (!nl_tcp)
7009 return -ENOBUFS;
7010
7011 if (nla_put_be32(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
7012 nla_put_be32(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
7013 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
7014 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
7015 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
7016 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
7017 tcp->payload_len, tcp->payload) ||
7018 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
7019 tcp->data_interval) ||
7020 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
7021 tcp->wake_len, tcp->wake_data) ||
7022 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
7023 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
7024 return -ENOBUFS;
7025
7026 if (tcp->payload_seq.len &&
7027 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
7028 sizeof(tcp->payload_seq), &tcp->payload_seq))
7029 return -ENOBUFS;
7030
7031 if (tcp->payload_tok.len &&
7032 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
7033 sizeof(tcp->payload_tok) + tcp->tokens_size,
7034 &tcp->payload_tok))
7035 return -ENOBUFS;
7036
7037 return 0;
7038}
7039
6933static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) 7040static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
6934{ 7041{
6935 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 7042 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6936 struct sk_buff *msg; 7043 struct sk_buff *msg;
6937 void *hdr; 7044 void *hdr;
7045 u32 size = NLMSG_DEFAULT_SIZE;
6938 7046
6939 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) 7047 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
7048 !rdev->wiphy.wowlan.tcp)
6940 return -EOPNOTSUPP; 7049 return -EOPNOTSUPP;
6941 7050
6942 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7051 if (rdev->wowlan && rdev->wowlan->tcp) {
7052 /* adjust size to have room for all the data */
7053 size += rdev->wowlan->tcp->tokens_size +
7054 rdev->wowlan->tcp->payload_len +
7055 rdev->wowlan->tcp->wake_len +
7056 rdev->wowlan->tcp->wake_len / 8;
7057 }
7058
7059 msg = nlmsg_new(size, GFP_KERNEL);
6943 if (!msg) 7060 if (!msg)
6944 return -ENOMEM; 7061 return -ENOMEM;
6945 7062
@@ -6970,8 +7087,13 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
6970 (rdev->wowlan->rfkill_release && 7087 (rdev->wowlan->rfkill_release &&
6971 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) 7088 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
6972 goto nla_put_failure; 7089 goto nla_put_failure;
7090
6973 if (nl80211_send_wowlan_patterns(msg, rdev)) 7091 if (nl80211_send_wowlan_patterns(msg, rdev))
6974 goto nla_put_failure; 7092 goto nla_put_failure;
7093
7094 if (nl80211_send_wowlan_tcp(msg, rdev->wowlan->tcp))
7095 goto nla_put_failure;
7096
6975 nla_nest_end(msg, nl_wowlan); 7097 nla_nest_end(msg, nl_wowlan);
6976 } 7098 }
6977 7099
@@ -6983,6 +7105,150 @@ nla_put_failure:
6983 return -ENOBUFS; 7105 return -ENOBUFS;
6984} 7106}
6985 7107
7108static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
7109 struct nlattr *attr,
7110 struct cfg80211_wowlan *trig)
7111{
7112 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
7113 struct cfg80211_wowlan_tcp *cfg;
7114 struct nl80211_wowlan_tcp_data_token *tok = NULL;
7115 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
7116 u32 size;
7117 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
7118 int err, port;
7119
7120 if (!rdev->wiphy.wowlan.tcp)
7121 return -EINVAL;
7122
7123 err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP,
7124 nla_data(attr), nla_len(attr),
7125 nl80211_wowlan_tcp_policy);
7126 if (err)
7127 return err;
7128
7129 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
7130 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
7131 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
7132 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
7133 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
7134 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
7135 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
7136 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
7137 return -EINVAL;
7138
7139 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
7140 if (data_size > rdev->wiphy.wowlan.tcp->data_payload_max)
7141 return -EINVAL;
7142
7143 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
7144 rdev->wiphy.wowlan.tcp->data_interval_max)
7145 return -EINVAL;
7146
7147 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
7148 if (wake_size > rdev->wiphy.wowlan.tcp->wake_payload_max)
7149 return -EINVAL;
7150
7151 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
7152 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
7153 return -EINVAL;
7154
7155 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
7156 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
7157
7158 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
7159 tokens_size = tokln - sizeof(*tok);
7160
7161 if (!tok->len || tokens_size % tok->len)
7162 return -EINVAL;
7163 if (!rdev->wiphy.wowlan.tcp->tok)
7164 return -EINVAL;
7165 if (tok->len > rdev->wiphy.wowlan.tcp->tok->max_len)
7166 return -EINVAL;
7167 if (tok->len < rdev->wiphy.wowlan.tcp->tok->min_len)
7168 return -EINVAL;
7169 if (tokens_size > rdev->wiphy.wowlan.tcp->tok->bufsize)
7170 return -EINVAL;
7171 if (tok->offset + tok->len > data_size)
7172 return -EINVAL;
7173 }
7174
7175 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
7176 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
7177 if (!rdev->wiphy.wowlan.tcp->seq)
7178 return -EINVAL;
7179 if (seq->len == 0 || seq->len > 4)
7180 return -EINVAL;
7181 if (seq->len + seq->offset > data_size)
7182 return -EINVAL;
7183 }
7184
7185 size = sizeof(*cfg);
7186 size += data_size;
7187 size += wake_size + wake_mask_size;
7188 size += tokens_size;
7189
7190 cfg = kzalloc(size, GFP_KERNEL);
7191 if (!cfg)
7192 return -ENOMEM;
7193 cfg->src = nla_get_be32(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
7194 cfg->dst = nla_get_be32(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
7195 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
7196 ETH_ALEN);
7197 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
7198 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
7199 else
7200 port = 0;
7201#ifdef CONFIG_INET
7202 /* allocate a socket and port for it and use it */
7203 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
7204 IPPROTO_TCP, &cfg->sock, 1);
7205 if (err) {
7206 kfree(cfg);
7207 return err;
7208 }
7209 if (inet_csk_get_port(cfg->sock->sk, port)) {
7210 sock_release(cfg->sock);
7211 kfree(cfg);
7212 return -EADDRINUSE;
7213 }
7214 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
7215#else
7216 if (!port) {
7217 kfree(cfg);
7218 return -EINVAL;
7219 }
7220 cfg->src_port = port;
7221#endif
7222
7223 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
7224 cfg->payload_len = data_size;
7225 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
7226 memcpy((void *)cfg->payload,
7227 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
7228 data_size);
7229 if (seq)
7230 cfg->payload_seq = *seq;
7231 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
7232 cfg->wake_len = wake_size;
7233 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
7234 memcpy((void *)cfg->wake_data,
7235 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
7236 wake_size);
7237 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
7238 data_size + wake_size;
7239 memcpy((void *)cfg->wake_mask,
7240 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
7241 wake_mask_size);
7242 if (tok) {
7243 cfg->tokens_size = tokens_size;
7244 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
7245 }
7246
7247 trig->tcp = cfg;
7248
7249 return 0;
7250}
7251
6986static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) 7252static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
6987{ 7253{
6988 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 7254 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6993,7 +7259,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
6993 int err, i; 7259 int err, i;
6994 bool prev_enabled = rdev->wowlan; 7260 bool prev_enabled = rdev->wowlan;
6995 7261
6996 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) 7262 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
7263 !rdev->wiphy.wowlan.tcp)
6997 return -EOPNOTSUPP; 7264 return -EOPNOTSUPP;
6998 7265
6999 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { 7266 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
@@ -7120,6 +7387,14 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7120 } 7387 }
7121 } 7388 }
7122 7389
7390 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
7391 err = nl80211_parse_wowlan_tcp(
7392 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
7393 &new_triggers);
7394 if (err)
7395 goto error;
7396 }
7397
7123 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL); 7398 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
7124 if (!ntrig) { 7399 if (!ntrig) {
7125 err = -ENOMEM; 7400 err = -ENOMEM;
@@ -7137,6 +7412,9 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7137 for (i = 0; i < new_triggers.n_patterns; i++) 7412 for (i = 0; i < new_triggers.n_patterns; i++)
7138 kfree(new_triggers.patterns[i].mask); 7413 kfree(new_triggers.patterns[i].mask);
7139 kfree(new_triggers.patterns); 7414 kfree(new_triggers.patterns);
7415 if (new_triggers.tcp && new_triggers.tcp->sock)
7416 sock_release(new_triggers.tcp->sock);
7417 kfree(new_triggers.tcp);
7140 return err; 7418 return err;
7141} 7419}
7142#endif 7420#endif
@@ -9418,6 +9696,17 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
9418 wakeup->pattern_idx)) 9696 wakeup->pattern_idx))
9419 goto free_msg; 9697 goto free_msg;
9420 9698
9699 if (wakeup->tcp_match)
9700 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH);
9701
9702 if (wakeup->tcp_connlost)
9703 nla_put_flag(msg,
9704 NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST);
9705
9706 if (wakeup->tcp_nomoretokens)
9707 nla_put_flag(msg,
9708 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS);
9709
9421 if (wakeup->packet) { 9710 if (wakeup->packet) {
9422 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211; 9711 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
9423 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN; 9712 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;