Commit 2a0e047e authored by Johannes Berg's avatar Johannes Berg

cfg80211: configuration for WoWLAN over TCP

Intel Wireless devices are able to make a TCP connection
after suspending, sending some data and waking up when
the connection receives wakeup data (or breaks). Add the
WoWLAN configuration and feature advertising API for it.
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent a0497f9f
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/nl80211.h> #include <linux/nl80211.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/ieee80211.h> #include <linux/ieee80211.h>
#include <linux/net.h>
#include <net/regulatory.h> #include <net/regulatory.h>
/** /**
...@@ -1587,6 +1588,41 @@ struct cfg80211_wowlan_trig_pkt_pattern { ...@@ -1587,6 +1588,41 @@ struct cfg80211_wowlan_trig_pkt_pattern {
int pkt_offset; int pkt_offset;
}; };
/**
* struct cfg80211_wowlan_tcp - TCP connection parameters
*
* @sock: (internal) socket for source port allocation
* @src: source IP address
* @dst: destination IP address
* @dst_mac: destination MAC address
* @src_port: source port
* @dst_port: destination port
* @payload_len: data payload length
* @payload: data payload buffer
* @payload_seq: payload sequence stamping configuration
* @data_interval: interval at which to send data packets
* @wake_len: wakeup payload match length
* @wake_data: wakeup payload match data
* @wake_mask: wakeup payload match mask
* @tokens_size: length of the tokens buffer
* @payload_tok: payload token usage configuration
*/
struct cfg80211_wowlan_tcp {
struct socket *sock;
__be32 src, dst;
u16 src_port, dst_port;
u8 dst_mac[ETH_ALEN];
int payload_len;
const u8 *payload;
struct nl80211_wowlan_tcp_data_seq payload_seq;
u32 data_interval;
u32 wake_len;
const u8 *wake_data, *wake_mask;
u32 tokens_size;
/* must be last, variable member */
struct nl80211_wowlan_tcp_data_token payload_tok;
};
/** /**
* struct cfg80211_wowlan - Wake on Wireless-LAN support info * struct cfg80211_wowlan - Wake on Wireless-LAN support info
* *
...@@ -1601,12 +1637,15 @@ struct cfg80211_wowlan_trig_pkt_pattern { ...@@ -1601,12 +1637,15 @@ struct cfg80211_wowlan_trig_pkt_pattern {
* @eap_identity_req: wake up on EAP identity request packet * @eap_identity_req: wake up on EAP identity request packet
* @four_way_handshake: wake up on 4-way handshake * @four_way_handshake: wake up on 4-way handshake
* @rfkill_release: wake up when rfkill is released * @rfkill_release: wake up when rfkill is released
* @tcp: TCP connection establishment/wakeup parameters, see nl80211.h.
* NULL if not configured.
*/ */
struct cfg80211_wowlan { struct cfg80211_wowlan {
bool any, disconnect, magic_pkt, gtk_rekey_failure, bool any, disconnect, magic_pkt, gtk_rekey_failure,
eap_identity_req, four_way_handshake, eap_identity_req, four_way_handshake,
rfkill_release; rfkill_release;
struct cfg80211_wowlan_trig_pkt_pattern *patterns; struct cfg80211_wowlan_trig_pkt_pattern *patterns;
struct cfg80211_wowlan_tcp *tcp;
int n_patterns; int n_patterns;
}; };
...@@ -1626,11 +1665,15 @@ struct cfg80211_wowlan { ...@@ -1626,11 +1665,15 @@ struct cfg80211_wowlan {
* frame triggers an 802.3 frame should be reported, for * frame triggers an 802.3 frame should be reported, for
* disconnect due to deauth 802.11 frame. This indicates which * disconnect due to deauth 802.11 frame. This indicates which
* it is. * it is.
* @tcp_match: TCP wakeup packet received
* @tcp_connlost: TCP connection lost or failed to establish
* @tcp_nomoretokens: TCP data ran out of tokens
*/ */
struct cfg80211_wowlan_wakeup { struct cfg80211_wowlan_wakeup {
bool disconnect, magic_pkt, gtk_rekey_failure, bool disconnect, magic_pkt, gtk_rekey_failure,
eap_identity_req, four_way_handshake, eap_identity_req, four_way_handshake,
rfkill_release, packet_80211; rfkill_release, packet_80211,
tcp_match, tcp_connlost, tcp_nomoretokens;
s32 pattern_idx; s32 pattern_idx;
u32 packet_present_len, packet_len; u32 packet_present_len, packet_len;
const void *packet; const void *packet;
...@@ -2285,6 +2328,14 @@ enum wiphy_wowlan_support_flags { ...@@ -2285,6 +2328,14 @@ enum wiphy_wowlan_support_flags {
WIPHY_WOWLAN_RFKILL_RELEASE = BIT(7), WIPHY_WOWLAN_RFKILL_RELEASE = BIT(7),
}; };
struct wiphy_wowlan_tcp_support {
const struct nl80211_wowlan_tcp_data_token_feature *tok;
u32 data_payload_max;
u32 data_interval_max;
u32 wake_payload_max;
bool seq;
};
/** /**
* struct wiphy_wowlan_support - WoWLAN support data * struct wiphy_wowlan_support - WoWLAN support data
* @flags: see &enum wiphy_wowlan_support_flags * @flags: see &enum wiphy_wowlan_support_flags
...@@ -2293,6 +2344,7 @@ enum wiphy_wowlan_support_flags { ...@@ -2293,6 +2344,7 @@ enum wiphy_wowlan_support_flags {
* @pattern_max_len: maximum length of each pattern * @pattern_max_len: maximum length of each pattern
* @pattern_min_len: minimum length of each pattern * @pattern_min_len: minimum length of each pattern
* @max_pkt_offset: maximum Rx packet offset * @max_pkt_offset: maximum Rx packet offset
* @tcp: TCP wakeup support information
*/ */
struct wiphy_wowlan_support { struct wiphy_wowlan_support {
u32 flags; u32 flags;
...@@ -2300,6 +2352,7 @@ struct wiphy_wowlan_support { ...@@ -2300,6 +2352,7 @@ struct wiphy_wowlan_support {
int pattern_max_len; int pattern_max_len;
int pattern_min_len; int pattern_min_len;
int max_pkt_offset; int max_pkt_offset;
const struct wiphy_wowlan_tcp_support *tcp;
}; };
/** /**
......
...@@ -2991,6 +2991,17 @@ struct nl80211_wowlan_pattern_support { ...@@ -2991,6 +2991,17 @@ struct nl80211_wowlan_pattern_support {
* @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN: Original length of the 802.3 * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN: Original length of the 802.3
* packet, may be bigger than the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 * packet, may be bigger than the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023
* attribute if the packet was truncated somewhere. * attribute if the packet was truncated somewhere.
* @NL80211_WOWLAN_TRIG_TCP_CONNECTION: TCP connection wake, see DOC section
* "TCP connection wakeup" for more details. This is a nested attribute
* containing the exact information for establishing and keeping alive
* the TCP connection.
* @NL80211_WOWLAN_TRIG_TCP_WAKEUP_MATCH: For wakeup reporting only, the
* wakeup packet was received on the TCP connection
* @NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST: For wakeup reporting only, the
* TCP connection was lost or failed to be established
* @NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS: For wakeup reporting only,
* the TCP connection ran out of tokens to use for data to send to the
* service
* @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers
* @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number
* *
...@@ -3012,12 +3023,126 @@ enum nl80211_wowlan_triggers { ...@@ -3012,12 +3023,126 @@ enum nl80211_wowlan_triggers {
NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN, NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN,
NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023, NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023,
NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN, NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN,
NL80211_WOWLAN_TRIG_TCP_CONNECTION,
NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH,
NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST,
NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS,
/* keep last */ /* keep last */
NUM_NL80211_WOWLAN_TRIG, NUM_NL80211_WOWLAN_TRIG,
MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1 MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1
}; };
/**
* DOC: TCP connection wakeup
*
* Some devices can establish a TCP connection in order to be woken up by a
* packet coming in from outside their network segment, or behind NAT. If
* configured, the device will establish a TCP connection to the given
* service, and periodically send data to that service. The first data
* packet is usually transmitted after SYN/ACK, also ACKing the SYN/ACK.
* The data packets can optionally include a (little endian) sequence
* number (in the TCP payload!) that is generated by the device, and, also
* optionally, a token from a list of tokens. This serves as a keep-alive
* with the service, and for NATed connections, etc.
*
* During this keep-alive period, the server doesn't send any data to the
* client. When receiving data, it is compared against the wakeup pattern
* (and mask) and if it matches, the host is woken up. Similarly, if the
* connection breaks or cannot be established to start with, the host is
* also woken up.
*
* Developer's note: ARP offload is required for this, otherwise TCP
* response packets might not go through correctly.
*/
/**
* struct nl80211_wowlan_tcp_data_seq - WoWLAN TCP data sequence
* @start: starting value
* @offset: offset of sequence number in packet
* @len: length of the sequence value to write, 1 through 4
*
* Note: don't confuse with the TCP sequence number(s), this is for the
* keepalive packet payload. The actual value is written into the packet
* in little endian.
*/
struct nl80211_wowlan_tcp_data_seq {
__u32 start, offset, len;
};
/**
* struct nl80211_wowlan_tcp_data_token - WoWLAN TCP data token config
* @offset: offset of token in packet
* @len: length of each token
* @token_stream: stream of data to be used for the tokens, the length must
* be a multiple of @len for this to make sense
*/
struct nl80211_wowlan_tcp_data_token {
__u32 offset, len;
__u8 token_stream[];
};
/**
* struct nl80211_wowlan_tcp_data_token_feature - data token features
* @min_len: minimum token length
* @max_len: maximum token length
* @bufsize: total available token buffer size (max size of @token_stream)
*/
struct nl80211_wowlan_tcp_data_token_feature {
__u32 min_len, max_len, bufsize;
};
/**
* enum nl80211_wowlan_tcp_attrs - WoWLAN TCP connection parameters
* @__NL80211_WOWLAN_TCP_INVALID: invalid number for nested attributes
* @NL80211_WOWLAN_TCP_SRC_IPV4: source IPv4 address (in network byte order)
* @NL80211_WOWLAN_TCP_DST_IPV4: destination IPv4 address
* (in network byte order)
* @NL80211_WOWLAN_TCP_DST_MAC: destination MAC address, this is given because
* route lookup when configured might be invalid by the time we suspend,
* and doing a route lookup when suspending is no longer possible as it
* might require ARP querying.
* @NL80211_WOWLAN_TCP_SRC_PORT: source port (u16); optional, if not given a
* socket and port will be allocated
* @NL80211_WOWLAN_TCP_DST_PORT: destination port (u16)
* @NL80211_WOWLAN_TCP_DATA_PAYLOAD: data packet payload, at least one byte.
* For feature advertising, a u32 attribute holding the maximum length
* of the data payload.
* @NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ: data packet sequence configuration
* (if desired), a &struct nl80211_wowlan_tcp_data_seq. For feature
* advertising it is just a flag
* @NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN: data packet token configuration,
* see &struct nl80211_wowlan_tcp_data_token and for advertising see
* &struct nl80211_wowlan_tcp_data_token_feature.
* @NL80211_WOWLAN_TCP_DATA_INTERVAL: data interval in seconds, maximum
* interval in feature advertising (u32)
* @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a
* u32 attribute holding the maximum length
* @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for
* feature advertising. The mask works like @NL80211_WOWLAN_PKTPAT_MASK
* but on the TCP payload only.
* @NUM_NL80211_WOWLAN_TCP: number of TCP attributes
* @MAX_NL80211_WOWLAN_TCP: highest attribute number
*/
enum nl80211_wowlan_tcp_attrs {
__NL80211_WOWLAN_TCP_INVALID,
NL80211_WOWLAN_TCP_SRC_IPV4,
NL80211_WOWLAN_TCP_DST_IPV4,
NL80211_WOWLAN_TCP_DST_MAC,
NL80211_WOWLAN_TCP_SRC_PORT,
NL80211_WOWLAN_TCP_DST_PORT,
NL80211_WOWLAN_TCP_DATA_PAYLOAD,
NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
NL80211_WOWLAN_TCP_DATA_INTERVAL,
NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
NL80211_WOWLAN_TCP_WAKE_MASK,
/* keep last */
NUM_NL80211_WOWLAN_TCP,
MAX_NL80211_WOWLAN_TCP = NUM_NL80211_WOWLAN_TCP - 1
};
/** /**
* enum nl80211_iface_limit_attrs - limit attributes * enum nl80211_iface_limit_attrs - limit attributes
* @NL80211_IFACE_LIMIT_UNSPEC: (reserved) * @NL80211_IFACE_LIMIT_UNSPEC: (reserved)
......
...@@ -108,6 +108,9 @@ cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev) ...@@ -108,6 +108,9 @@ cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
for (i = 0; i < rdev->wowlan->n_patterns; i++) for (i = 0; i < rdev->wowlan->n_patterns; i++)
kfree(rdev->wowlan->patterns[i].mask); kfree(rdev->wowlan->patterns[i].mask);
kfree(rdev->wowlan->patterns); kfree(rdev->wowlan->patterns);
if (rdev->wowlan->tcp && rdev->wowlan->tcp->sock)
sock_release(rdev->wowlan->tcp->sock);
kfree(rdev->wowlan->tcp);
kfree(rdev->wowlan); kfree(rdev->wowlan);
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment