nl80211: Handle control port TX status events over nl80211
In order to retransmit faster in AP mode, hostapd can handle TX status notifications. When using nl80211, this is currently only possible with socket control messages. Add support for receiving such events directly over nl80211 and detecting, if this feature is supported. This finally allows for a clean separation between management/control path (over nl80211) and in-kernel data path. A follow up commit enables the feature in AP mode. Control port TX status contains the original frame content for matching with the current hostapd code. Furthermore, a cookie is included, which allows for matching against outstanding cookies in the future. This commit only prints the cookie value for debugging purposes on TX status receive. Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
This commit is contained in:
parent
f7c657b79f
commit
6f19cc4d78
4 changed files with 43 additions and 0 deletions
|
@ -1931,6 +1931,8 @@ struct wpa_driver_capa {
|
|||
|
||||
/** Driver supports a separate control port RX for EAPOL frames */
|
||||
#define WPA_DRIVER_FLAGS2_CONTROL_PORT_RX 0x0000000000000001ULL
|
||||
/** Driver supports TX status reports for EAPOL frames through control port */
|
||||
#define WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS 0x0000000000000002ULL
|
||||
u64 flags2;
|
||||
|
||||
#define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
|
||||
|
|
|
@ -328,6 +328,7 @@ const char * driver_flag2_to_string(u64 flag2)
|
|||
#define DF2S(x) case WPA_DRIVER_FLAGS2_ ## x: return #x
|
||||
switch (flag2) {
|
||||
DF2S(CONTROL_PORT_RX);
|
||||
DF2S(CONTROL_PORT_TX_STATUS);
|
||||
}
|
||||
return "UNKNOWN";
|
||||
#undef DF2S
|
||||
|
|
|
@ -620,6 +620,10 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
|
|||
if (ext_feature_isset(ext_features, len,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH))
|
||||
capa->flags2 |= WPA_DRIVER_FLAGS2_CONTROL_PORT_RX;
|
||||
if (ext_feature_isset(
|
||||
ext_features, len,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS))
|
||||
capa->flags2 |= WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS;
|
||||
|
||||
if (ext_feature_isset(ext_features, len,
|
||||
NL80211_EXT_FEATURE_VLAN_OFFLOAD))
|
||||
|
|
|
@ -138,6 +138,8 @@ static const char * nl80211_command_to_string(enum nl80211_commands cmd)
|
|||
C2S(NL80211_CMD_CONTROL_PORT_FRAME)
|
||||
C2S(NL80211_CMD_UPDATE_OWE_INFO)
|
||||
C2S(NL80211_CMD_UNPROT_BEACON)
|
||||
C2S(NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS)
|
||||
|
||||
default:
|
||||
return "NL80211_CMD_UNKNOWN";
|
||||
}
|
||||
|
@ -2557,6 +2559,37 @@ static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
nl80211_control_port_frame_tx_status(struct wpa_driver_nl80211_data *drv,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
bool acked = tb[NL80211_ATTR_ACK];
|
||||
union wpa_event_data event;
|
||||
const u8 *frame;
|
||||
size_t frame_len;
|
||||
|
||||
if (!tb[NL80211_ATTR_FRAME] || !tb[NL80211_ATTR_COOKIE])
|
||||
return;
|
||||
|
||||
frame = nla_data(tb[NL80211_ATTR_FRAME]);
|
||||
frame_len = nla_len(tb[NL80211_ATTR_FRAME]);
|
||||
if (frame_len < ETH_HLEN)
|
||||
return;
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Control port TX status (ack=%d), cookie=%llu",
|
||||
acked, (long long unsigned int)
|
||||
nla_get_u64(tb[NL80211_ATTR_COOKIE]));
|
||||
|
||||
os_memset(&event, 0, sizeof(event));
|
||||
event.eapol_tx_status.dst = frame;
|
||||
event.eapol_tx_status.data = frame + ETH_HLEN;
|
||||
event.eapol_tx_status.data_len = frame_len - ETH_HLEN;
|
||||
event.eapol_tx_status.ack = acked;
|
||||
wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event);
|
||||
}
|
||||
|
||||
|
||||
static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
|
@ -2775,6 +2808,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
|||
mlme_event_unprot_beacon(drv, nla_data(frame),
|
||||
nla_len(frame));
|
||||
break;
|
||||
case NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS:
|
||||
nl80211_control_port_frame_tx_status(drv, tb);
|
||||
break;
|
||||
default:
|
||||
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
|
||||
"(cmd=%d)", cmd);
|
||||
|
|
Loading…
Reference in a new issue