mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-04 10:40:58 +01:00
wifi: add nl80211 Critical Protocol indication support
At critical times during the connection process, especially during DHCP and EAPOL, the driver can increase the reliability of communication in an attempt to increase the possibility of success. This could be done by suppressing bluetooth for a short period, or locking in a low (and thus more reliable) bitrate, or enforcing some other interference protection. The 3.10 kernel added nl80211 support for this, so lets use it if we can.
This commit is contained in:
parent
07edeabbc3
commit
d18f524984
5 changed files with 66 additions and 0 deletions
20
configure.ac
20
configure.ac
|
|
@ -175,6 +175,26 @@ if test "$ac_have_nl80211" = no; then
|
|||
AC_MSG_ERROR(Linux kernel development header linux/nl80211.h not installed or not functional)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([Linux kernel nl80211 Critical Protocol Start/Stop])
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#ifndef __user
|
||||
#define __user
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <linux/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/nl80211.h>]],
|
||||
[[unsigned int a = NL80211_CMD_CRIT_PROTOCOL_START; a++;]])],
|
||||
[ac_have_nl80211_critproto=yes],
|
||||
[ac_have_nl80211_critproto=no])
|
||||
AC_MSG_RESULT($ac_have_nl80211_critproto)
|
||||
if test "$ac_have_nl80211_critproto" = yes; then
|
||||
AC_DEFINE(HAVE_NL80211_CRITICAL_PROTOCOL_CMDS, 1, [Define if nl80211 has critical protocol support])
|
||||
else
|
||||
AC_DEFINE(HAVE_NL80211_CRITICAL_PROTOCOL_CMDS, 0, [Define if nl80211 has critical protocol support])
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Default to using WEXT but allow it to be disabled
|
||||
dnl
|
||||
|
|
|
|||
|
|
@ -555,6 +555,36 @@ wifi_nl80211_get_qual (WifiData *data)
|
|||
return sta_info.signal;
|
||||
}
|
||||
|
||||
#if HAVE_NL80211_CRITICAL_PROTOCOL_CMDS
|
||||
static gboolean
|
||||
wifi_nl80211_indicate_addressing_running (WifiData *data, gboolean running)
|
||||
{
|
||||
WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data;
|
||||
struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
msg = nl80211_alloc_msg (nl80211,
|
||||
running ? NL80211_CMD_CRIT_PROTOCOL_START :
|
||||
NL80211_CMD_CRIT_PROTOCOL_STOP,
|
||||
0);
|
||||
/* Despite the DHCP name, we're using this for any type of IP addressing,
|
||||
* DHCPv4, DHCPv6, and IPv6 SLAAC.
|
||||
*/
|
||||
NLA_PUT_U16 (msg, NL80211_ATTR_CRIT_PROT_ID, NL80211_CRIT_PROTO_DHCP);
|
||||
if (running) {
|
||||
/* Give DHCP 5 seconds to complete */
|
||||
NLA_PUT_U16 (msg, NL80211_ATTR_MAX_CRIT_PROT_DURATION, 5000);
|
||||
}
|
||||
|
||||
err = nl80211_send_and_recv (nl80211, msg, NULL, NULL);
|
||||
return err ? FALSE : TRUE;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free (msg);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct nl80211_device_info {
|
||||
guint32 *freqs;
|
||||
int num_freqs;
|
||||
|
|
@ -742,6 +772,9 @@ wifi_nl80211_init (const char *iface, int ifindex)
|
|||
nl80211->parent.get_bssid = wifi_nl80211_get_bssid;
|
||||
nl80211->parent.get_rate = wifi_nl80211_get_rate;
|
||||
nl80211->parent.get_qual = wifi_nl80211_get_qual;
|
||||
#if HAVE_NL80211_CRITICAL_PROTOCOL_CMDS
|
||||
nl80211->parent.indicate_addressing_running = wifi_nl80211_indicate_addressing_running;
|
||||
#endif
|
||||
nl80211->parent.deinit = wifi_nl80211_deinit;
|
||||
|
||||
nl80211->nl_sock = nl_socket_alloc ();
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ struct WifiData {
|
|||
|
||||
/* ssid == NULL means "auto SSID" */
|
||||
gboolean (*set_mesh_ssid) (WifiData *data, const GByteArray *ssid);
|
||||
|
||||
gboolean (*indicate_addressing_running) (WifiData *data, gboolean running);
|
||||
};
|
||||
|
||||
gpointer wifi_data_new (const char *iface, int ifindex, gsize len);
|
||||
|
|
|
|||
|
|
@ -205,3 +205,12 @@ wifi_utils_set_mesh_ssid (WifiData *data, const GByteArray *ssid)
|
|||
return data->set_mesh_ssid (data, ssid);
|
||||
}
|
||||
|
||||
gboolean
|
||||
wifi_utils_indicate_addressing_running (WifiData *data, gboolean running)
|
||||
{
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
if (data->indicate_addressing_running)
|
||||
return data->indicate_addressing_running (data, running);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,4 +67,6 @@ gboolean wifi_utils_set_mesh_channel (WifiData *data, guint32 channel);
|
|||
|
||||
gboolean wifi_utils_set_mesh_ssid (WifiData *data, const GByteArray *ssid);
|
||||
|
||||
gboolean wifi_utils_indicate_addressing_running (WifiData *data, gboolean running);
|
||||
|
||||
#endif /* WIFI_UTILS_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue