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.
Unified · Split
| @@ -5721,6 +5721,28 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, · 5720 unmodified lines | |||
| 5721 | const u8 *buf, size_t len, bool ack, gfp_t gfp); | 5721 | const u8 *buf, size_t len, bool ack, gfp_t gfp); |
| 5722 | 5722 | ||
| 5723 | 5723 | ||
| 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 | |||
| 5724 | /** | 5746 | /** |
| 5725 | * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event | 5747 | * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event |
| 5726 | * @dev: network device | 5748 | * @dev: network device |
| @@ -990,6 +990,17 @@ · 989 unmodified lines | |||
| 990 | * &NL80211_CMD_CONNECT or &NL80211_CMD_ROAM. If the 4 way handshake failed | 990 | * &NL80211_CMD_CONNECT or &NL80211_CMD_ROAM. If the 4 way handshake failed |
| 991 | * &NL80211_CMD_DISCONNECT should be indicated instead. | 991 | * &NL80211_CMD_DISCONNECT should be indicated instead. |
| 992 | * | 992 | * |
| 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 | * | ||
| 993 | * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded. | 1004 | * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded. |
| 994 | * | 1005 | * |
| 995 | * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host | 1006 | * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host |
| @@ -1228,6 +1239,8 @@ enum nl80211_commands { · 232 unmodified lines | |||
| 1228 | 1239 | ||
| 1229 | NL80211_CMD_STA_OPMODE_CHANGED, | 1240 | NL80211_CMD_STA_OPMODE_CHANGED, |
| 1230 | 1241 | ||
| 1242 | NL80211_CMD_CONTROL_PORT_FRAME, | ||
| 1243 | |||
| 1231 | /* add new commands above here */ | 1244 | /* add new commands above here */ |
| 1232 | 1245 | ||
| 1233 | /* used to define NL80211_CMD_MAX below */ | 1246 | /* used to define NL80211_CMD_MAX below */ |
| @@ -14553,6 +14553,64 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, · 14552 unmodified lines | |||
| 14553 | } | 14553 | } |
| 14554 | EXPORT_SYMBOL(cfg80211_mgmt_tx_status); | 14554 | EXPORT_SYMBOL(cfg80211_mgmt_tx_status); |
| 14555 | 14555 | ||
| 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 | |||
| 14556 | static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev, | 14614 | static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev, |
| 14557 | const char *mac, gfp_t gfp) | 14615 | const char *mac, gfp_t gfp) |
| 14558 | { | 14616 | { |
| @@ -2600,6 +2600,27 @@ TRACE_EVENT(cfg80211_mgmt_tx_status, · 2599 unmodified lines | |||
| 2600 | WDEV_PR_ARG, __entry->cookie, BOOL_TO_STR(__entry->ack)) | 2600 | WDEV_PR_ARG, __entry->cookie, BOOL_TO_STR(__entry->ack)) |
| 2601 | ); | 2601 | ); |
| 2602 | 2602 | ||
| 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 | |||
| 2603 | TRACE_EVENT(cfg80211_cqm_rssi_notify, | 2624 | TRACE_EVENT(cfg80211_cqm_rssi_notify, |
| 2604 | TP_PROTO(struct net_device *netdev, | 2625 | TP_PROTO(struct net_device *netdev, |
| 2605 | enum nl80211_cqm_rssi_threshold_event rssi_event, | 2626 | enum nl80211_cqm_rssi_threshold_event rssi_event, |