History

nl80211: Add CMD_CONTROL_PORT_FRAME API

This commit also adds cfg80211_rx_control_port function. This is used to generate a CMD_CONTROL_PORT_FRAME event out to userspace. The conn_owner_nlportid is used as the unicast destination. This means that userspace must specify NL80211_ATTR_SOCKET_OWNER flag if control port over nl80211 routing is requested in NL80211_CMD_CONNECT, NL80211_CMD_ASSOCIATE, NL80211_CMD_START_AP or IBSS/mesh join.

Denis Kenzior committed 8 years ago

Commit 6a671a51 parent 4d191c74 files · +114 −0Browse files

Unified · Split

4 files
  1. include/net/cfg80211.h +22 −0
  2. include/uapi/linux/nl80211.h +13 −0
  3. net/wireless/nl80211.c +58 −0
  4. net/wireless/trace.h +21 −0
include/net/cfg80211.h+22−0
@@ -5721,6 +5721,28 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, · 5720 unmodified lines
57215721 const u8 *buf, size_t len, bool ack, gfp_t gfp);
57225722
57235723
5724+/**
5725+ * cfg80211_rx_control_port - notification about a received control port frame
5726+ * @dev: The device the frame matched to
5727+ * @buf: control port frame
5728+ * @len: length of the frame data
5729+ * @addr: The peer from which the frame was received
5730+ * @proto: frame protocol, typically PAE or Pre-authentication
5731+ * @unencrypted: Whether the frame was received unencrypted
5732+ *
5733+ * This function is used to inform userspace about a received control port
5734+ * frame. It should only be used if userspace indicated it wants to receive
5735+ * control port frames over nl80211.
5736+ *
5737+ * The frame is the data portion of the 802.3 or 802.11 data frame with all
5738+ * network layer headers removed (e.g. the raw EAPoL frame).
5739+ *
5740+ * Return: %true if the frame was passed to userspace
5741+ */
5742+bool cfg80211_rx_control_port(struct net_device *dev,
5743+ const u8 *buf, size_t len,
5744+ const u8 *addr, u16 proto, bool unencrypted);
5745+
57245746 /**
57255747 * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event
57265748 * @dev: network device
include/uapi/linux/nl80211.h+13−0
@@ -990,6 +990,17 @@ · 989 unmodified lines
990990 * &NL80211_CMD_CONNECT or &NL80211_CMD_ROAM. If the 4 way handshake failed
991991 * &NL80211_CMD_DISCONNECT should be indicated instead.
992992 *
993+ * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
994+ * and RX notification. This command is used both as a request to transmit
995+ * a control port frame and as a notification that a control port frame
996+ * has been received. %NL80211_ATTR_FRAME is used to specify the
997+ * frame contents. The frame is the raw EAPoL data, without ethernet or
998+ * 802.11 headers.
999+ * When used as an event indication %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
1000+ * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT and %NL80211_ATTR_MAC are added
1001+ * indicating the protocol type of the received frame; whether the frame
1002+ * was received unencrypted and the MAC address of the peer respectively.
1003+ *
9931004 * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
9941005 *
9951006 * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host
@@ -1228,6 +1239,8 @@ enum nl80211_commands { · 232 unmodified lines
12281239
12291240 NL80211_CMD_STA_OPMODE_CHANGED,
12301241
1242+ NL80211_CMD_CONTROL_PORT_FRAME,
1243+
12311244 /* add new commands above here */
12321245
12331246 /* used to define NL80211_CMD_MAX below */
net/wireless/nl80211.c+58−0
@@ -14553,6 +14553,64 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, · 14552 unmodified lines
1455314553 }
1455414554 EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
1455514555
14556+static int __nl80211_rx_control_port(struct net_device *dev,
14557+ const u8 *buf, size_t len,
14558+ const u8 *addr, u16 proto,
14559+ bool unencrypted, gfp_t gfp)
14560+{
14561+ struct wireless_dev *wdev = dev->ieee80211_ptr;
14562+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
14563+ struct sk_buff *msg;
14564+ void *hdr;
14565+ u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
14566+
14567+ if (!nlportid)
14568+ return -ENOENT;
14569+
14570+ msg = nlmsg_new(100 + len, gfp);
14571+ if (!msg)
14572+ return -ENOMEM;
14573+
14574+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
14575+ if (!hdr) {
14576+ nlmsg_free(msg);
14577+ return -ENOBUFS;
14578+ }
14579+
14580+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14581+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14582+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14583+ NL80211_ATTR_PAD) ||
14584+ nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
14585+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
14586+ nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
14587+ (unencrypted && nla_put_flag(msg,
14588+ NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
14589+ goto nla_put_failure;
14590+
14591+ genlmsg_end(msg, hdr);
14592+
14593+ return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
14594+
14595+ nla_put_failure:
14596+ nlmsg_free(msg);
14597+ return -ENOBUFS;
14598+}
14599+
14600+bool cfg80211_rx_control_port(struct net_device *dev,
14601+ const u8 *buf, size_t len,
14602+ const u8 *addr, u16 proto, bool unencrypted)
14603+{
14604+ int ret;
14605+
14606+ trace_cfg80211_rx_control_port(dev, buf, len, addr, proto, unencrypted);
14607+ ret = __nl80211_rx_control_port(dev, buf, len, addr, proto,
14608+ unencrypted, GFP_ATOMIC);
14609+ trace_cfg80211_return_bool(ret == 0);
14610+ return ret == 0;
14611+}
14612+EXPORT_SYMBOL(cfg80211_rx_control_port);
14613+
1455614614 static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
1455714615 const char *mac, gfp_t gfp)
1455814616 {
net/wireless/trace.h+21−0
@@ -2600,6 +2600,27 @@ TRACE_EVENT(cfg80211_mgmt_tx_status, · 2599 unmodified lines
26002600 WDEV_PR_ARG, __entry->cookie, BOOL_TO_STR(__entry->ack))
26012601 );
26022602
2603+TRACE_EVENT(cfg80211_rx_control_port,
2604+ TP_PROTO(struct net_device *netdev, const u8 *buf, size_t len,
2605+ const u8 *addr, u16 proto, bool unencrypted),
2606+ TP_ARGS(netdev, buf, len, addr, proto, unencrypted),
2607+ TP_STRUCT__entry(
2608+ NETDEV_ENTRY
2609+ MAC_ENTRY(addr)
2610+ __field(u16, proto)
2611+ __field(bool, unencrypted)
2612+ ),
2613+ TP_fast_assign(
2614+ NETDEV_ASSIGN;
2615+ MAC_ASSIGN(addr, addr);
2616+ __entry->proto = proto;
2617+ __entry->unencrypted = unencrypted;
2618+ ),
2619+ TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT " proto: 0x%x, unencrypted: %s",
2620+ NETDEV_PR_ARG, MAC_PR_ARG(addr),
2621+ __entry->proto, BOOL_TO_STR(__entry->unencrypted))
2622+);
2623+
26032624 TRACE_EVENT(cfg80211_cqm_rssi_notify,
26042625 TP_PROTO(struct net_device *netdev,
26052626 enum nl80211_cqm_rssi_threshold_event rssi_event,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t