Skip to content

Commit

Permalink
nl80211: advertise GTK rekey support, new triggers
Browse files Browse the repository at this point in the history
Since we now have the necessary API in place to support
GTK rekeying, applications will need to know whether it
is supported by a device. Add a pseudo-trigger that is
used only to advertise that capability. Also, add some
new triggers that match what iwlagn devices can do.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jul 15, 2011
1 parent 95acac6 commit 77dbbb1
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 6 deletions.
19 changes: 17 additions & 2 deletions include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -989,8 +989,8 @@ enum nl80211_commands {
* driving the peer link management state machine.
* @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled.
*
* @NL80211_ATTR_WOWLAN_SUPPORTED: indicates, as part of the wiphy capabilities,
* the supported WoWLAN triggers
* @NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: indicates, as part of the wiphy
* capabilities, the supported WoWLAN triggers
* @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to
* indicate which WoW triggers should be enabled. This is also
* used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN
Expand Down Expand Up @@ -2255,6 +2255,16 @@ struct nl80211_wowlan_pattern_support {
*
* In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
* carrying a &struct nl80211_wowlan_pattern_support.
* @NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED: Not a real trigger, and cannot be
* used when setting, used only to indicate that GTK rekeying is supported
* by the device (flag)
* @NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE: wake up on GTK rekey failure (if
* done by the device) (flag)
* @NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST: wake up on EAP Identity Request
* packet (flag)
* @NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE: wake up on 4-way handshake (flag)
* @NL80211_WOWLAN_TRIG_RFKILL_RELEASE: wake up when rfkill is released
* (on devices that have rfkill in the device) (flag)
* @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers
* @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number
*/
Expand All @@ -2264,6 +2274,11 @@ enum nl80211_wowlan_triggers {
NL80211_WOWLAN_TRIG_DISCONNECT,
NL80211_WOWLAN_TRIG_MAGIC_PKT,
NL80211_WOWLAN_TRIG_PKT_PATTERN,
NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED,
NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE,
NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST,
NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE,
NL80211_WOWLAN_TRIG_RFKILL_RELEASE,

/* keep last */
NUM_NL80211_WOWLAN_TRIG,
Expand Down
24 changes: 20 additions & 4 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1146,9 +1146,15 @@ struct cfg80211_wowlan_trig_pkt_pattern {
* @magic_pkt: wake up on receiving magic packet
* @patterns: wake up on receiving packet matching a pattern
* @n_patterns: number of patterns
* @gtk_rekey_failure: wake up on GTK rekey failure
* @eap_identity_req: wake up on EAP identity request packet
* @four_way_handshake: wake up on 4-way handshake
* @rfkill_release: wake up when rfkill is released
*/
struct cfg80211_wowlan {
bool any, disconnect, magic_pkt;
bool any, disconnect, magic_pkt, gtk_rekey_failure,
eap_identity_req, four_way_handshake,
rfkill_release;
struct cfg80211_wowlan_trig_pkt_pattern *patterns;
int n_patterns;
};
Expand Down Expand Up @@ -1673,11 +1679,21 @@ struct ieee80211_txrx_stypes {
* @WIPHY_WOWLAN_MAGIC_PKT: supports wakeup on magic packet
* (see nl80211.h)
* @WIPHY_WOWLAN_DISCONNECT: supports wakeup on disconnect
* @WIPHY_WOWLAN_SUPPORTS_GTK_REKEY: supports GTK rekeying while asleep
* @WIPHY_WOWLAN_GTK_REKEY_FAILURE: supports wakeup on GTK rekey failure
* @WIPHY_WOWLAN_EAP_IDENTITY_REQ: supports wakeup on EAP identity request
* @WIPHY_WOWLAN_4WAY_HANDSHAKE: supports wakeup on 4-way handshake failure
* @WIPHY_WOWLAN_RFKILL_RELEASE: supports wakeup on RF-kill release
*/
enum wiphy_wowlan_support_flags {
WIPHY_WOWLAN_ANY = BIT(0),
WIPHY_WOWLAN_MAGIC_PKT = BIT(1),
WIPHY_WOWLAN_DISCONNECT = BIT(2),
WIPHY_WOWLAN_ANY = BIT(0),
WIPHY_WOWLAN_MAGIC_PKT = BIT(1),
WIPHY_WOWLAN_DISCONNECT = BIT(2),
WIPHY_WOWLAN_SUPPORTS_GTK_REKEY = BIT(3),
WIPHY_WOWLAN_GTK_REKEY_FAILURE = BIT(4),
WIPHY_WOWLAN_EAP_IDENTITY_REQ = BIT(5),
WIPHY_WOWLAN_4WAY_HANDSHAKE = BIT(6),
WIPHY_WOWLAN_RFKILL_RELEASE = BIT(7),
};

/**
Expand Down
4 changes: 4 additions & 0 deletions net/wireless/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,10 @@ int wiphy_register(struct wiphy *wiphy)
int i;
u16 ifmodes = wiphy->interface_modes;

if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
!(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
return -EINVAL;

if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
return -EINVAL;

Expand Down
49 changes: 49 additions & 0 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
[NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
[NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
[NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
[NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
};

/* policy for GTK rekey offload attributes */
Expand Down Expand Up @@ -929,6 +933,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED);
if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
if (dev->wiphy.wowlan.n_patterns) {
struct nl80211_wowlan_pattern_support pat = {
.max_patterns = dev->wiphy.wowlan.n_patterns,
Expand Down Expand Up @@ -5272,6 +5286,14 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
if (rdev->wowlan->magic_pkt)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
if (rdev->wowlan->gtk_rekey_failure)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
if (rdev->wowlan->eap_identity_req)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
if (rdev->wowlan->four_way_handshake)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
if (rdev->wowlan->rfkill_release)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
if (rdev->wowlan->n_patterns) {
struct nlattr *nl_pats, *nl_pat;
int i, pat_len;
Expand Down Expand Up @@ -5348,6 +5370,33 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
new_triggers.magic_pkt = true;
}

if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
return -EINVAL;

if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
return -EINVAL;
new_triggers.gtk_rekey_failure = true;
}

if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
return -EINVAL;
new_triggers.eap_identity_req = true;
}

if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
return -EINVAL;
new_triggers.four_way_handshake = true;
}

if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
return -EINVAL;
new_triggers.rfkill_release = true;
}

if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
struct nlattr *pat;
int n_patterns = 0;
Expand Down

0 comments on commit 77dbbb1

Please sign in to comment.