mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 14:42:37 +02:00
update network protcol to support bcm direct
This commit is contained in:
parent
6caae043e1
commit
cd57be725d
|
|
@ -604,6 +604,21 @@ enum nl80211_commands {
|
|||
NL80211_CMD_STOP_SCHED_SCAN,
|
||||
NL80211_CMD_SCHED_SCAN_RESULTS,
|
||||
NL80211_CMD_SCHED_SCAN_STOPPED,
|
||||
//==============gwl=======================
|
||||
|
||||
NL80211_CMD_SET_REKEY_OFFLOAD,
|
||||
|
||||
NL80211_CMD_PMKSA_CANDIDATE,
|
||||
|
||||
NL80211_CMD_TDLS_OPER,
|
||||
NL80211_CMD_TDLS_MGMT,
|
||||
|
||||
NL80211_CMD_UNEXPECTED_FRAME,
|
||||
|
||||
NL80211_CMD_PROBE_CLIENT,
|
||||
|
||||
NL80211_CMD_REGISTER_BEACONS,
|
||||
//=====================================
|
||||
|
||||
/* add new commands above here */
|
||||
|
||||
|
|
@ -1238,6 +1253,19 @@ enum nl80211_attrs {
|
|||
NL80211_ATTR_SCHED_SCAN_MATCH,
|
||||
NL80211_ATTR_MAX_MATCH_SETS,
|
||||
|
||||
//=============== gwl =============
|
||||
NL80211_ATTR_PMKSA_CANDIDATE,
|
||||
|
||||
NL80211_ATTR_TX_NO_CCK_RATE,
|
||||
|
||||
NL80211_ATTR_TDLS_ACTION,
|
||||
NL80211_ATTR_TDLS_DIALOG_TOKEN,
|
||||
NL80211_ATTR_TDLS_OPERATION,
|
||||
NL80211_ATTR_TDLS_SUPPORT,
|
||||
NL80211_ATTR_TDLS_EXTERNAL_SETUP,
|
||||
|
||||
NL80211_ATTR_DEVICE_AP_SME,
|
||||
//===================================
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
|
|
@ -2312,6 +2340,13 @@ enum nl80211_wowlan_triggers {
|
|||
NL80211_WOWLAN_TRIG_DISCONNECT,
|
||||
NL80211_WOWLAN_TRIG_MAGIC_PKT,
|
||||
NL80211_WOWLAN_TRIG_PKT_PATTERN,
|
||||
//======== gwl ===============
|
||||
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,
|
||||
|
|
@ -2424,5 +2459,55 @@ enum nl80211_plink_state {
|
|||
NUM_NL80211_PLINK_STATES,
|
||||
MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1
|
||||
};
|
||||
// gwl=========================
|
||||
#define NL80211_KCK_LEN 16
|
||||
#define NL80211_KEK_LEN 16
|
||||
#define NL80211_REPLAY_CTR_LEN 8
|
||||
|
||||
enum nl80211_rekey_data {
|
||||
__NL80211_REKEY_DATA_INVALID,
|
||||
NL80211_REKEY_DATA_KEK,
|
||||
NL80211_REKEY_DATA_KCK,
|
||||
NL80211_REKEY_DATA_REPLAY_CTR,
|
||||
|
||||
/* keep last */
|
||||
NUM_NL80211_REKEY_DATA,
|
||||
MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1
|
||||
};
|
||||
|
||||
enum nl80211_hidden_ssid {
|
||||
NL80211_HIDDEN_SSID_NOT_IN_USE,
|
||||
NL80211_HIDDEN_SSID_ZERO_LEN,
|
||||
NL80211_HIDDEN_SSID_ZERO_CONTENTS
|
||||
};
|
||||
|
||||
enum nl80211_sta_wme_attr {
|
||||
__NL80211_STA_WME_INVALID,
|
||||
NL80211_STA_WME_UAPSD_QUEUES,
|
||||
NL80211_STA_WME_MAX_SP,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_STA_WME_AFTER_LAST,
|
||||
NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
enum nl80211_pmksa_candidate_attr {
|
||||
__NL80211_PMKSA_CANDIDATE_INVALID,
|
||||
NL80211_PMKSA_CANDIDATE_INDEX,
|
||||
NL80211_PMKSA_CANDIDATE_BSSID,
|
||||
NL80211_PMKSA_CANDIDATE_PREAUTH,
|
||||
|
||||
/* keep last */
|
||||
NUM_NL80211_PMKSA_CANDIDATE,
|
||||
MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1
|
||||
};
|
||||
|
||||
enum nl80211_tdls_operation {
|
||||
NL80211_TDLS_DISCOVERY_REQ,
|
||||
NL80211_TDLS_SETUP,
|
||||
NL80211_TDLS_TEARDOWN,
|
||||
NL80211_TDLS_ENABLE_LINK,
|
||||
NL80211_TDLS_DISABLE_LINK,
|
||||
};
|
||||
|
||||
#endif /* __LINUX_NL80211_H */
|
||||
|
|
|
|||
|
|
@ -1178,11 +1178,21 @@ struct cfg80211_wowlan_trig_pkt_pattern {
|
|||
* @patterns: wake up on receiving packet matching a pattern
|
||||
* @n_patterns: number of patterns
|
||||
*/
|
||||
// gwl
|
||||
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;
|
||||
};
|
||||
//======= gwl ======
|
||||
struct cfg80211_gtk_rekey_data {
|
||||
u8 kek[NL80211_KEK_LEN];
|
||||
u8 kck[NL80211_KCK_LEN];
|
||||
u8 replay_ctr[NL80211_REPLAY_CTR_LEN];
|
||||
};
|
||||
//=============
|
||||
|
||||
/**
|
||||
* struct cfg80211_ops - backend description for wireless configuration
|
||||
|
|
@ -1521,6 +1531,20 @@ struct cfg80211_ops {
|
|||
struct net_device *dev,
|
||||
struct cfg80211_sched_scan_request *request);
|
||||
int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev);
|
||||
|
||||
//========= gwl ================
|
||||
int (*set_rekey_data)(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_gtk_rekey_data *data);
|
||||
|
||||
int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev,
|
||||
u8 *peer, u8 action_code, u8 dialog_token,
|
||||
u16 status_code, const u8 *buf, size_t len);
|
||||
int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev,
|
||||
u8 *peer, enum nl80211_tdls_operation oper);
|
||||
|
||||
int (*probe_client)(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u64 *cookie);
|
||||
//===========================
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -1584,6 +1608,14 @@ enum wiphy_flags {
|
|||
WIPHY_FLAG_MESH_AUTH = BIT(10),
|
||||
WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11),
|
||||
WIPHY_FLAG_ENFORCE_COMBINATIONS = BIT(12),
|
||||
//========= gwl =================
|
||||
WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13),
|
||||
WIPHY_FLAG_AP_UAPSD = BIT(14),
|
||||
WIPHY_FLAG_SUPPORTS_TDLS = BIT(15),
|
||||
WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16),
|
||||
WIPHY_FLAG_HAVE_AP_SME = BIT(17),
|
||||
WIPHY_FLAG_REPORTS_OBSS = BIT(18),
|
||||
//==============================
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1683,6 +1715,13 @@ enum wiphy_wowlan_support_flags {
|
|||
WIPHY_WOWLAN_ANY = BIT(0),
|
||||
WIPHY_WOWLAN_MAGIC_PKT = BIT(1),
|
||||
WIPHY_WOWLAN_DISCONNECT = BIT(2),
|
||||
//=========== gwl ===========
|
||||
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),
|
||||
//=========================
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1803,7 +1842,9 @@ struct wiphy {
|
|||
u16 interface_modes;
|
||||
|
||||
u32 flags;
|
||||
|
||||
// gwl
|
||||
u32 ap_sme_capa;
|
||||
//======
|
||||
enum cfg80211_signal_type signal_type;
|
||||
|
||||
int bss_priv_size;
|
||||
|
|
@ -2053,7 +2094,9 @@ struct wireless_dev {
|
|||
int ps_timeout;
|
||||
|
||||
int beacon_interval;
|
||||
|
||||
// gwl
|
||||
u32 ap_unexpected_nlpid;
|
||||
//=====
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
/* wext data */
|
||||
struct {
|
||||
|
|
@ -3063,6 +3106,70 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
|
|||
void cfg80211_cqm_pktloss_notify(struct net_device *dev,
|
||||
const u8 *peer, u32 num_packets, gfp_t gfp);
|
||||
|
||||
//============ gwl =================
|
||||
/**
|
||||
* cfg80211_gtk_rekey_notify - notify userspace about driver rekeying
|
||||
* @dev: network device
|
||||
* @bssid: BSSID of AP (to avoid races)
|
||||
* @replay_ctr: new replay counter
|
||||
*/
|
||||
void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
|
||||
const u8 *replay_ctr, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_pmksa_candidate_notify - notify about PMKSA caching candidate
|
||||
* @dev: network device
|
||||
* @index: candidate index (the smaller the index, the higher the priority)
|
||||
* @bssid: BSSID of AP
|
||||
* @preauth: Whether AP advertises support for RSN pre-authentication
|
||||
* @gfp: allocation flags
|
||||
*/
|
||||
void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
|
||||
const u8 *bssid, bool preauth, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_rx_spurious_frame - inform userspace about a spurious frame
|
||||
* @dev: The device the frame matched to
|
||||
* @addr: the transmitter address
|
||||
* @gfp: context flags
|
||||
*
|
||||
* This function is used in AP mode (only!) to inform userspace that
|
||||
* a spurious class 3 frame was received, to be able to deauth the
|
||||
* sender.
|
||||
* Returns %true if the frame was passed to userspace (or this failed
|
||||
* for a reason other than not having a subscription.)
|
||||
*/
|
||||
bool cfg80211_rx_spurious_frame(struct net_device *dev,
|
||||
const u8 *addr, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_probe_status - notify userspace about probe status
|
||||
* @dev: the device the probe was sent on
|
||||
* @addr: the address of the peer
|
||||
* @cookie: the cookie filled in @probe_client previously
|
||||
* @acked: indicates whether probe was acked or not
|
||||
* @gfp: allocation flags
|
||||
*/
|
||||
void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
||||
u64 cookie, bool acked, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_report_obss_beacon - report beacon from other APs
|
||||
* @wiphy: The wiphy that received the beacon
|
||||
* @frame: the frame
|
||||
* @len: length of the frame
|
||||
* @freq: frequency the frame was received on
|
||||
* @gfp: allocation flags
|
||||
*
|
||||
* Use this function to report to userspace when a beacon was
|
||||
* received. It is not useful to call this when there is no
|
||||
* netdev that is in AP/GO mode.
|
||||
*/
|
||||
void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
||||
const u8 *frame, size_t len,
|
||||
int freq, gfp_t gfp);
|
||||
//=========================================
|
||||
|
||||
/* Logging, debugging and troubleshooting/diagnostic helpers. */
|
||||
|
||||
/* wiphy_printk helpers, similar to dev_printk */
|
||||
|
|
|
|||
|
|
@ -487,6 +487,15 @@ int wiphy_register(struct wiphy *wiphy)
|
|||
bool have_band = false;
|
||||
int i;
|
||||
u16 ifmodes = wiphy->interface_modes;
|
||||
//========= gwl ========
|
||||
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->ap_sme_capa &&
|
||||
!(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME)))
|
||||
return -EINVAL;
|
||||
//===================
|
||||
|
||||
if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,9 @@ struct cfg80211_registered_device {
|
|||
int devlist_generation;
|
||||
int opencount; /* also protected by devlist_mtx */
|
||||
wait_queue_head_t dev_wait;
|
||||
|
||||
//gwl
|
||||
u32 ap_beacons_nlpid;
|
||||
//=========
|
||||
/* BSSes/scanning */
|
||||
spinlock_t bss_lock;
|
||||
struct list_head bss_list;
|
||||
|
|
|
|||
|
|
@ -877,6 +877,10 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
|
|||
}
|
||||
|
||||
spin_unlock_bh(&wdev->mgmt_registrations_lock);
|
||||
//gwl
|
||||
if (nlpid == wdev->ap_unexpected_nlpid)
|
||||
wdev->ap_unexpected_nlpid = 0;
|
||||
//======
|
||||
}
|
||||
|
||||
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
|
||||
|
|
@ -1082,3 +1086,38 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev,
|
|||
nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
|
||||
// gwl ====================
|
||||
void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
|
||||
const u8 *replay_ctr, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
|
||||
nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
|
||||
|
||||
void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
|
||||
const u8 *bssid, bool preauth, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
|
||||
nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
|
||||
|
||||
bool cfg80211_rx_spurious_frame(struct net_device *dev,
|
||||
const u8 *addr, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
|
||||
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO))
|
||||
return false;
|
||||
|
||||
return nl80211_unexpected_frame(dev, addr, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
|
||||
|
|
|
|||
|
|
@ -184,6 +184,14 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
|||
.len = IEEE80211_MAX_DATA_LEN },
|
||||
[NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
|
||||
// gwl ================
|
||||
[NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
|
||||
//===============
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
|
|
@ -212,6 +220,12 @@ 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 },
|
||||
// gwl ==============
|
||||
[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 },
|
||||
//===================
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
|
|
@ -220,6 +234,16 @@ nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
|
|||
.len = IEEE80211_MAX_SSID_LEN },
|
||||
};
|
||||
|
||||
// gwl ===============
|
||||
/* policy for GTK rekey offload attributes */
|
||||
static const struct nla_policy
|
||||
nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
|
||||
[NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
|
||||
[NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
|
||||
[NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
|
||||
};
|
||||
// ================
|
||||
|
||||
/* ifidx get helper */
|
||||
static int nl80211_get_ifidx(struct netlink_callback *cb)
|
||||
{
|
||||
|
|
@ -710,6 +734,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
|
|||
NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH)
|
||||
NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
|
||||
// gwl ==================
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD)
|
||||
NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD);
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)
|
||||
NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT);
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS)
|
||||
NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_SUPPORT);
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)
|
||||
NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP);
|
||||
//=======================
|
||||
|
||||
NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
|
||||
sizeof(u32) * dev->wiphy.n_cipher_suites,
|
||||
|
|
@ -852,8 +886,21 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
|
|||
}
|
||||
CMD(set_channel, SET_CHANNEL);
|
||||
CMD(set_wds_peer, SET_WDS_PEER);
|
||||
// gwl ======
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
|
||||
CMD(tdls_mgmt, TDLS_MGMT);
|
||||
CMD(tdls_oper, TDLS_OPER);
|
||||
}
|
||||
//===========
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
|
||||
CMD(sched_scan_start, START_SCHED_SCAN);
|
||||
// gwl ======
|
||||
CMD(probe_client, PROBE_CLIENT);
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
|
||||
i++;
|
||||
NLA_PUT_U32(msg, i, NL80211_CMD_REGISTER_BEACONS);
|
||||
}
|
||||
//============
|
||||
|
||||
#undef CMD
|
||||
|
||||
|
|
@ -940,6 +987,18 @@ 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);
|
||||
// gwl =================
|
||||
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,
|
||||
|
|
@ -961,6 +1020,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
|
|||
|
||||
if (nl80211_put_iface_combinations(&dev->wiphy, msg))
|
||||
goto nla_put_failure;
|
||||
// gwl ==============
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME)
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_DEVICE_AP_SME,
|
||||
dev->wiphy.ap_sme_capa);
|
||||
//=================
|
||||
|
||||
return genlmsg_end(msg, hdr);
|
||||
|
||||
|
|
@ -1206,6 +1270,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
|||
result = -ENETDOWN;
|
||||
goto bad_res;
|
||||
}
|
||||
// gwl ===========
|
||||
if (!netif_running(netdev)) {
|
||||
result = -ENETDOWN;
|
||||
goto bad_res;
|
||||
}
|
||||
//=================
|
||||
|
||||
nla_for_each_nested(nl_txq_params,
|
||||
info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
|
||||
|
|
@ -4723,6 +4793,58 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
|
|||
return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
|
||||
}
|
||||
|
||||
// gwl=================
|
||||
static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
u8 action_code, dialog_token;
|
||||
u16 status_code;
|
||||
u8 *peer;
|
||||
|
||||
if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
|
||||
!rdev->ops->tdls_mgmt)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
|
||||
!info->attrs[NL80211_ATTR_STATUS_CODE] ||
|
||||
!info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
|
||||
!info->attrs[NL80211_ATTR_IE] ||
|
||||
!info->attrs[NL80211_ATTR_MAC])
|
||||
return -EINVAL;
|
||||
|
||||
peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
|
||||
status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
|
||||
dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
|
||||
|
||||
return rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
|
||||
dialog_token, status_code,
|
||||
nla_data(info->attrs[NL80211_ATTR_IE]),
|
||||
nla_len(info->attrs[NL80211_ATTR_IE]));
|
||||
}
|
||||
|
||||
static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
enum nl80211_tdls_operation operation;
|
||||
u8 *peer;
|
||||
|
||||
if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
|
||||
!rdev->ops->tdls_oper)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
|
||||
!info->attrs[NL80211_ATTR_MAC])
|
||||
return -EINVAL;
|
||||
|
||||
operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
|
||||
peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
|
||||
return rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, operation);
|
||||
}
|
||||
// =================
|
||||
static int nl80211_remain_on_channel(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
|
|
@ -5253,6 +5375,16 @@ 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);
|
||||
// gwl =============
|
||||
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;
|
||||
|
|
@ -5329,6 +5461,34 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
|
|||
new_triggers.magic_pkt = true;
|
||||
}
|
||||
|
||||
// gwl =============
|
||||
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;
|
||||
|
|
@ -5410,6 +5570,144 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
|
|||
return err;
|
||||
}
|
||||
|
||||
// gwl ================
|
||||
static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct nlattr *tb[NUM_NL80211_REKEY_DATA];
|
||||
struct cfg80211_gtk_rekey_data rekey_data;
|
||||
int err;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_REKEY_DATA])
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse(tb, MAX_NL80211_REKEY_DATA,
|
||||
nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]),
|
||||
nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]),
|
||||
nl80211_rekey_policy);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
|
||||
return -ERANGE;
|
||||
if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
|
||||
return -ERANGE;
|
||||
if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
|
||||
return -ERANGE;
|
||||
|
||||
memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]),
|
||||
NL80211_KEK_LEN);
|
||||
memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]),
|
||||
NL80211_KCK_LEN);
|
||||
memcpy(rekey_data.replay_ctr,
|
||||
nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]),
|
||||
NL80211_REPLAY_CTR_LEN);
|
||||
|
||||
wdev_lock(wdev);
|
||||
if (!wdev->current_bss) {
|
||||
err = -ENOTCONN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!rdev->ops->set_rekey_data) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = rdev->ops->set_rekey_data(&rdev->wiphy, dev, &rekey_data);
|
||||
out:
|
||||
wdev_unlock(wdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nl80211_register_unexpected_frame(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
|
||||
if (wdev->iftype != NL80211_IFTYPE_AP &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO)
|
||||
return -EINVAL;
|
||||
|
||||
if (wdev->ap_unexpected_nlpid)
|
||||
return -EBUSY;
|
||||
|
||||
wdev->ap_unexpected_nlpid = info->snd_pid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nl80211_probe_client(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
const u8 *addr;
|
||||
u64 cookie;
|
||||
int err;
|
||||
|
||||
if (wdev->iftype != NL80211_IFTYPE_AP &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_MAC])
|
||||
return -EINVAL;
|
||||
|
||||
if (!rdev->ops->probe_client)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
|
||||
NL80211_CMD_PROBE_CLIENT);
|
||||
|
||||
if (IS_ERR(hdr)) {
|
||||
err = PTR_ERR(hdr);
|
||||
goto free_msg;
|
||||
}
|
||||
|
||||
addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
|
||||
err = rdev->ops->probe_client(&rdev->wiphy, dev, addr, &cookie);
|
||||
if (err)
|
||||
goto free_msg;
|
||||
|
||||
NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
return genlmsg_reply(msg, info);
|
||||
|
||||
nla_put_failure:
|
||||
err = -ENOBUFS;
|
||||
free_msg:
|
||||
nlmsg_free(msg);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
|
||||
if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (rdev->ap_beacons_nlpid)
|
||||
return -EBUSY;
|
||||
|
||||
rdev->ap_beacons_nlpid = info->snd_pid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
// =====================
|
||||
|
||||
#define NL80211_FLAG_NEED_WIPHY 0x01
|
||||
#define NL80211_FLAG_NEED_NETDEV 0x02
|
||||
#define NL80211_FLAG_NEED_RTNL 0x04
|
||||
|
|
@ -5940,6 +6238,56 @@ static struct genl_ops nl80211_ops[] = {
|
|||
.internal_flags = NL80211_FLAG_NEED_WIPHY |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
// gwl ===============
|
||||
{
|
||||
.cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
|
||||
.doit = nl80211_set_rekey_data,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_TDLS_MGMT,
|
||||
.doit = nl80211_tdls_mgmt,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_TDLS_OPER,
|
||||
.doit = nl80211_tdls_oper,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_UNEXPECTED_FRAME,
|
||||
.doit = nl80211_register_unexpected_frame,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_PROBE_CLIENT,
|
||||
.doit = nl80211_probe_client,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_REGISTER_BEACONS,
|
||||
.doit = nl80211_register_beacons,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.internal_flags = NL80211_FLAG_NEED_WIPHY |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
//=======================
|
||||
};
|
||||
|
||||
static struct genl_multicast_group nl80211_mlme_mcgrp = {
|
||||
|
|
@ -6760,6 +7108,48 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
|
|||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
// gwl ==============
|
||||
bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
int err;
|
||||
u32 nlpid = ACCESS_ONCE(wdev->ap_unexpected_nlpid);
|
||||
|
||||
if (!nlpid)
|
||||
return false;
|
||||
|
||||
msg = nlmsg_new(100, gfp);
|
||||
if (!msg)
|
||||
return true;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UNEXPECTED_FRAME);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
|
||||
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
|
||||
|
||||
err = genlmsg_end(msg, hdr);
|
||||
if (err < 0) {
|
||||
nlmsg_free(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
|
||||
return true;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
return true;
|
||||
}
|
||||
// ==================
|
||||
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, u32 nlpid,
|
||||
int freq, const u8 *buf, size_t len, gfp_t gfp)
|
||||
|
|
@ -6884,6 +7274,99 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
|
|||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
// gwl ============
|
||||
void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *bssid,
|
||||
const u8 *replay_ctr, gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
struct nlattr *rekey_attr;
|
||||
void *hdr;
|
||||
|
||||
msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
|
||||
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
|
||||
|
||||
rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
|
||||
if (!rekey_attr)
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR,
|
||||
NL80211_REPLAY_CTR_LEN, replay_ctr);
|
||||
|
||||
nla_nest_end(msg, rekey_attr);
|
||||
|
||||
if (genlmsg_end(msg, hdr) < 0) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
|
||||
nl80211_mlme_mcgrp.id, gfp);
|
||||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, int index,
|
||||
const u8 *bssid, bool preauth, gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
struct nlattr *attr;
|
||||
void *hdr;
|
||||
|
||||
msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
|
||||
|
||||
attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
|
||||
if (!attr)
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index);
|
||||
NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid);
|
||||
if (preauth)
|
||||
NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH);
|
||||
|
||||
nla_nest_end(msg, attr);
|
||||
|
||||
if (genlmsg_end(msg, hdr) < 0) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
|
||||
nl80211_mlme_mcgrp.id, gfp);
|
||||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
//=======================
|
||||
|
||||
void
|
||||
nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *peer,
|
||||
|
|
@ -6929,6 +7412,88 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
|
|||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
// gwl ===============
|
||||
void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
||||
u64 cookie, bool acked, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
int err;
|
||||
|
||||
msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
|
||||
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
|
||||
NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
|
||||
if (acked)
|
||||
NLA_PUT_FLAG(msg, NL80211_ATTR_ACK);
|
||||
|
||||
err = genlmsg_end(msg, hdr);
|
||||
if (err < 0) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
|
||||
nl80211_mlme_mcgrp.id, gfp);
|
||||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_probe_status);
|
||||
|
||||
void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
||||
const u8 *frame, size_t len,
|
||||
int freq, gfp_t gfp)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
u32 nlpid = ACCESS_ONCE(rdev->ap_beacons_nlpid);
|
||||
|
||||
if (!nlpid)
|
||||
return;
|
||||
|
||||
msg = nlmsg_new(len + 100, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
|
||||
if (freq)
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
|
||||
NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame);
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
|
||||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_report_obss_beacon);
|
||||
// ==================
|
||||
|
||||
static int nl80211_netlink_notify(struct notifier_block * nb,
|
||||
unsigned long state,
|
||||
void *_notify)
|
||||
|
|
@ -6941,10 +7506,13 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
|
|||
return NOTIFY_DONE;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list)
|
||||
// gwl
|
||||
list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
|
||||
list_for_each_entry_rcu(wdev, &rdev->netdev_list, list)
|
||||
cfg80211_mlme_unregister_socket(wdev, notify->pid);
|
||||
if (rdev->ap_beacons_nlpid == notify->pid)
|
||||
rdev->ap_beacons_nlpid = 0;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
|
|
|
|||
|
|
@ -109,4 +109,16 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
|
|||
struct net_device *netdev, const u8 *peer,
|
||||
u32 num_packets, gfp_t gfp);
|
||||
|
||||
// gwl =======
|
||||
void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *bssid,
|
||||
const u8 *replay_ctr, gfp_t gfp);
|
||||
|
||||
void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, int index,
|
||||
const u8 *bssid, bool preauth, gfp_t gfp);
|
||||
|
||||
bool nl80211_unexpected_frame(struct net_device *dev,
|
||||
const u8 *addr, gfp_t gfp);
|
||||
//=================
|
||||
#endif /* __NET_WIRELESS_NL80211_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user