platform: merge branch 'th/wifi-cleanup'

https://github.com/NetworkManager/NetworkManager/pull/58
This commit is contained in:
Thomas Haller 2018-01-15 20:29:36 +01:00
commit 07d8431ae5
14 changed files with 311 additions and 351 deletions

View file

@ -1374,6 +1374,9 @@ src_libNetworkManagerBase_la_SOURCES = \
src/NetworkManagerUtils.c \
src/NetworkManagerUtils.h \
\
src/platform/nm-netlink.c \
src/platform/nm-netlink.h \
\
src/platform/nmp-netns.c \
src/platform/nmp-netns.h \
src/platform/nmp-object.c \

View file

@ -38,9 +38,6 @@
/* Define to 1 if libsystemd is available */
#mesondefine HAVE_LIBSYSTEMD
/* Define if nl80211 has critical protocol support */
#mesondefine HAVE_NL80211_CRITICAL_PROTOCOL_CMDS
/* Define to 1 if you have the `secure_getenv' function. */
#mesondefine HAVE_SECURE_GETENV

View file

@ -199,73 +199,12 @@ if test x"$ac_with_wext" = x"yes"; then
if test "$enable_wifi" != "yes"; then
AC_MSG_ERROR(Enabling WEXT support and disabling Wi-Fi makes no sense)
fi
AC_MSG_CHECKING([Linux kernel WEXT headers])
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/wireless.h>]],
[[#ifndef IWEVGENIE
#error "not found"
#endif]])],
[ac_have_iwevgenie=yes],
[ac_have_iwevgenie=no])
AC_MSG_RESULT($ac_have_iwevgenie)
if test "$ac_have_iwevgenie" = no; then
AC_MSG_ERROR(Linux kernel development header linux/wireless.h not installed or not functional)
fi
AC_DEFINE(HAVE_WEXT, 1, [Define if you have Linux Wireless Extensions support])
else
AC_DEFINE(HAVE_WEXT, 0, [Define if you have Linux Wireless Extensions support])
fi
AM_CONDITIONAL(WITH_WEXT, test x"${ac_with_wext}" = x"yes")
AC_MSG_CHECKING([Linux kernel nl80211 headers])
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>]],
[[int a = NL80211_RATE_INFO_BITRATE; a++;]])],
[ac_have_nl80211=yes],
[ac_have_nl80211=no])
AC_MSG_RESULT($ac_have_nl80211)
if test "$ac_have_nl80211" = no; then
AC_MSG_ERROR(Linux kernel development header linux/nl80211.h not installed or not functional)
fi
if test "$with_wifi" = "yes"; then
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 a = NL80211_CMD_CRIT_PROTOCOL_START; a++;]])],
[ac_have_nl80211_critproto=yes],
[ac_have_nl80211_critproto=no])
AC_MSG_RESULT($ac_have_nl80211_critproto)
else
ac_have_nl80211_critproto='no'
fi
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 wpa_supplicant but allow IWD as wifi backend
dnl

View file

@ -269,39 +269,6 @@ if dist_version != ''
endif
enable_wifi = get_option('wifi')
if enable_wifi
nl80211_src = '''
#ifndef __user
#define __user
#endif
#include <sys/types.h>
#include <linux/types.h>
#include <sys/socket.h>
#include <linux/nl80211.h>
int main() {
int a = NL80211_RATE_INFO_BITRATE;
a++;
}
'''
assert(cc.compiles(nl80211_src), 'Linux kernel development header linux/nl80211.h not installed or not functional')
nl80211_crit_proto_src = '''
#ifndef __user
#define __user
#endif
#include <sys/types.h>
#include <linux/types.h>
#include <sys/socket.h>
#include <linux/nl80211.h>
int main() {
unsigned a = NL80211_CMD_CRIT_PROTOCOL_START;
a++;
}
'''
config_h.set10('HAVE_NL80211_CRITICAL_PROTOCOL_CMDS', cc.compiles(nl80211_crit_proto_src))
endif
config_h.set10('WITH_WIFI', enable_wifi)
enable_iwd = get_option('iwd')
@ -310,25 +277,7 @@ if enable_iwd
endif
config_h.set10('WITH_IWD', enable_iwd)
# Default to using WEXT but allow it to be disabled
enable_wext = get_option('wext')
if enable_wext
assert(enable_wifi, 'Enabling WEXT support and disabling Wi-Fi makes no sense')
iwevgenie_src = '''
#ifndef __user
#define __user
#endif
#include <sys/types.h>
#include <linux/types.h>
#include <sys/socket.h>
#include <linux/wireless.h>
#ifndef IWEVGENIE
#error "not found"
#endif
'''
assert(cc.compiles(iwevgenie_src), 'Linux kernel development header linux/wireless.h not installed or not functional')
endif
config_h.set10('HAVE_WEXT', enable_wext)
# Checks for libdl - on certain platforms its part of libc

View file

@ -54,6 +54,7 @@ sources = files(
'dhcp/nm-dhcp-utils.c',
'ndisc/nm-lndp-ndisc.c',
'ndisc/nm-ndisc.c',
'platform/nm-netlink.c',
'platform/wifi/wifi-utils-nl80211.c',
'platform/wifi/wifi-utils.c',
'platform/nm-linux-platform.c',

View file

@ -938,7 +938,6 @@ wifi_find_frequency (NMPlatform *platform, int ifindex, const guint32 *freqs)
static void
wifi_indicate_addressing_running (NMPlatform *platform, int ifindex, gboolean running)
{
;
}
static guint32

View file

@ -37,14 +37,13 @@
#include <linux/if_tun.h>
#include <linux/if_tunnel.h>
#include <linux/ip6_tunnel.h>
#include <netlink/netlink.h>
#include <netlink/msg.h>
#include <libudev.h>
#include "nm-utils.h"
#include "nm-core-internal.h"
#include "nm-setting-vlan.h"
#include "nm-netlink.h"
#include "nm-core-utils.h"
#include "nmp-object.h"
#include "nmp-netns.h"
@ -952,13 +951,6 @@ _nl_addattr_l (struct nlmsghdr *n,
return TRUE;
}
static void
_nm_auto_nl_msg_cleanup (void *ptr)
{
nlmsg_free (*((struct nl_msg **) ptr));
}
#define nm_auto_nlmsg nm_auto(_nm_auto_nl_msg_cleanup)
static const char *
_nl_nlmsghdr_to_str (const struct nlmsghdr *hdr, char *buf, gsize len)
{
@ -1059,30 +1051,6 @@ flags_done:
return b;
}
static int
_nl_nla_parse (struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
const struct nla_policy *policy)
{
return nla_parse (tb, maxtype, head, len, (struct nla_policy *) policy);
}
#define nla_parse(...) _nl_nla_parse(__VA_ARGS__)
static int
_nl_nlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
int maxtype, const struct nla_policy *policy)
{
return nlmsg_parse (nlh, hdrlen, tb, maxtype, (struct nla_policy *) policy);
}
#define nlmsg_parse(...) _nl_nlmsg_parse(__VA_ARGS__)
static int
_nl_nla_parse_nested (struct nlattr *tb[], int maxtype, struct nlattr *nla,
const struct nla_policy *policy)
{
return nla_parse_nested (tb, maxtype, nla, (struct nla_policy *) policy);
}
#define nla_parse_nested(...) _nl_nla_parse_nested(__VA_ARGS__)
/******************************************************************
* NMPObject/netlink functions
******************************************************************/
@ -6421,7 +6389,7 @@ ip_route_get (NMPlatform *platform,
int try_count = 0;
WaitForNlResponseResult seq_result;
int nle;
nm_auto_nlmsg NMPObject *route = NULL;
nm_auto_nmpobj NMPObject *route = NULL;
nm_assert (NM_IS_LINUX_PLATFORM (platform));
nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
@ -7053,7 +7021,7 @@ nm_linux_platform_init (NMLinuxPlatform *self)
priv->delayed_action.list_master_connected = g_ptr_array_new ();
priv->delayed_action.list_refresh_link = g_ptr_array_new ();
priv->delayed_action.list_wait_for_nl_response = g_array_new (FALSE, TRUE, sizeof (DelayedActionWaitForNlResponseData));
priv->wifi_data = g_hash_table_new_full (nm_direct_hash, NULL, NULL, (GDestroyNotify) wifi_utils_deinit);
priv->wifi_data = g_hash_table_new_full (nm_direct_hash, NULL, NULL, (GDestroyNotify) wifi_utils_unref);
}
static void

122
src/platform/nm-netlink.c Normal file
View file

@ -0,0 +1,122 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* nm-platform.c - Handle runtime kernel networking configuration
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2018 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-netlink.h"
/*****************************************************************************
* Reimplementations/copied from libnl3/genl
*****************************************************************************/
void *
genlmsg_put (struct nl_msg *msg, uint32_t port, uint32_t seq, int family,
int hdrlen, int flags, uint8_t cmd, uint8_t version)
{
struct nlmsghdr *nlh;
struct genlmsghdr hdr = {
.cmd = cmd,
.version = version,
};
nlh = nlmsg_put (msg, port, seq, family, GENL_HDRLEN + hdrlen, flags);
if (nlh == NULL)
return NULL;
memcpy (nlmsg_data (nlh), &hdr, sizeof (hdr));
return (char *) nlmsg_data (nlh) + GENL_HDRLEN;
}
void *
genlmsg_data (const struct genlmsghdr *gnlh)
{
return ((unsigned char *) gnlh + GENL_HDRLEN);
}
void *
genlmsg_user_hdr (const struct genlmsghdr *gnlh)
{
return genlmsg_data (gnlh);
}
struct genlmsghdr *
genlmsg_hdr (struct nlmsghdr *nlh)
{
return nlmsg_data (nlh);
}
void *
genlmsg_user_data (const struct genlmsghdr *gnlh, const int hdrlen)
{
return (char *) genlmsg_user_hdr (gnlh) + NLMSG_ALIGN (hdrlen);
}
struct nlattr *
genlmsg_attrdata (const struct genlmsghdr *gnlh, int hdrlen)
{
return genlmsg_user_data (gnlh, hdrlen);
}
int
genlmsg_len (const struct genlmsghdr *gnlh)
{
const struct nlmsghdr *nlh;
nlh = (const struct nlmsghdr *) ((const unsigned char *) gnlh - NLMSG_HDRLEN);
return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
}
int
genlmsg_attrlen (const struct genlmsghdr *gnlh, int hdrlen)
{
return genlmsg_len (gnlh) - NLMSG_ALIGN (hdrlen);
}
int
genlmsg_valid_hdr (struct nlmsghdr *nlh, int hdrlen)
{
struct genlmsghdr *ghdr;
if (!nlmsg_valid_hdr (nlh, GENL_HDRLEN))
return 0;
ghdr = nlmsg_data (nlh);
if (genlmsg_len (ghdr) < NLMSG_ALIGN (hdrlen))
return 0;
return 1;
}
int
genlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
int maxtype, const struct nla_policy *policy)
{
struct genlmsghdr *ghdr;
if (!genlmsg_valid_hdr (nlh, hdrlen))
return -NLE_MSG_TOOSHORT;
ghdr = nlmsg_data (nlh);
return nla_parse (tb, maxtype, genlmsg_attrdata (ghdr, hdrlen),
genlmsg_attrlen (ghdr, hdrlen), policy);
}
/*****************************************************************************/

85
src/platform/nm-netlink.h Normal file
View file

@ -0,0 +1,85 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* nm-platform.c - Handle runtime kernel networking configuration
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2018 Red Hat, Inc.
*/
#ifndef __NM_NETLINK_H__
#define __NM_NETLINK_H__
#include <netlink/msg.h>
#include <netlink/attr.h>
/*****************************************************************************
* libnl3 compat code
*****************************************************************************/
static inline int
_nl_nla_parse (struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
const struct nla_policy *policy)
{
return nla_parse (tb, maxtype, head, len, (struct nla_policy *) policy);
}
#define nla_parse(...) _nl_nla_parse(__VA_ARGS__)
static inline int
_nl_nlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
int maxtype, const struct nla_policy *policy)
{
return nlmsg_parse (nlh, hdrlen, tb, maxtype, (struct nla_policy *) policy);
}
#define nlmsg_parse(...) _nl_nlmsg_parse(__VA_ARGS__)
static inline int
_nl_nla_parse_nested (struct nlattr *tb[], int maxtype, struct nlattr *nla,
const struct nla_policy *policy)
{
return nla_parse_nested (tb, maxtype, nla, (struct nla_policy *) policy);
}
#define nla_parse_nested(...) _nl_nla_parse_nested(__VA_ARGS__)
/*****************************************************************************
* Reimplementations/copied from libnl3/genl
*****************************************************************************/
void *genlmsg_put (struct nl_msg *msg, uint32_t port, uint32_t seq, int family,
int hdrlen, int flags, uint8_t cmd, uint8_t version);
void *genlmsg_data (const struct genlmsghdr *gnlh);
void *genlmsg_user_hdr (const struct genlmsghdr *gnlh);
struct genlmsghdr *genlmsg_hdr (struct nlmsghdr *nlh);
void *genlmsg_user_data (const struct genlmsghdr *gnlh, const int hdrlen);
struct nlattr *genlmsg_attrdata (const struct genlmsghdr *gnlh, int hdrlen);
int genlmsg_len (const struct genlmsghdr *gnlh);
int genlmsg_attrlen (const struct genlmsghdr *gnlh, int hdrlen);
int genlmsg_valid_hdr (struct nlmsghdr *nlh, int hdrlen);
int genlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
int maxtype, const struct nla_policy *policy);
/*****************************************************************************
* helpers
*****************************************************************************/
static inline void
_nm_auto_nl_msg_cleanup (struct nl_msg **ptr)
{
nlmsg_free (*ptr);
}
#define nm_auto_nlmsg nm_auto(_nm_auto_nl_msg_cleanup)
/*****************************************************************************/
#endif /* __NM_NETLINK_H__ */

View file

@ -22,17 +22,17 @@
#include "nm-default.h"
#include "wifi-utils-nl80211.h"
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/ethernet.h>
#include <unistd.h>
#include <netlink/netlink.h>
#include <netlink/msg.h>
#include <linux/nl80211.h>
#include "platform/nm-netlink.h"
#include "wifi-utils-private.h"
#include "wifi-utils-nl80211.h"
#include "platform/nm-platform.h"
#include "platform/nm-platform-utils.h"
#include "nm-utils.h"
@ -46,121 +46,6 @@
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
} G_STMT_END
/*****************************************************************************/
static int
_nl_nla_parse (struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
const struct nla_policy *policy)
{
return nla_parse (tb, maxtype, head, len, (struct nla_policy *) policy);
}
#define nla_parse(...) _nl_nla_parse(__VA_ARGS__)
static int
_nl_nla_parse_nested (struct nlattr *tb[], int maxtype, struct nlattr *nla,
const struct nla_policy *policy)
{
return nla_parse_nested (tb, maxtype, nla, (struct nla_policy *) policy);
}
#define nla_parse_nested(...) _nl_nla_parse_nested(__VA_ARGS__)
/*****************************************************************************
* Copied from libnl3/genl:
*****************************************************************************/
static void *
genlmsg_put (struct nl_msg *msg, uint32_t port, uint32_t seq, int family,
int hdrlen, int flags, uint8_t cmd, uint8_t version)
{
struct nlmsghdr *nlh;
struct genlmsghdr hdr = {
.cmd = cmd,
.version = version,
};
nlh = nlmsg_put (msg, port, seq, family, GENL_HDRLEN + hdrlen, flags);
if (nlh == NULL)
return NULL;
memcpy (nlmsg_data (nlh), &hdr, sizeof (hdr));
return (char *) nlmsg_data (nlh) + GENL_HDRLEN;
}
static void *
genlmsg_data (const struct genlmsghdr *gnlh)
{
return ((unsigned char *) gnlh + GENL_HDRLEN);
}
static void *
genlmsg_user_hdr (const struct genlmsghdr *gnlh)
{
return genlmsg_data (gnlh);
}
static struct genlmsghdr *
genlmsg_hdr (struct nlmsghdr *nlh)
{
return nlmsg_data (nlh);
}
static void *
genlmsg_user_data (const struct genlmsghdr *gnlh, const int hdrlen)
{
return (char *) genlmsg_user_hdr (gnlh) + NLMSG_ALIGN (hdrlen);
}
static struct nlattr *
genlmsg_attrdata (const struct genlmsghdr *gnlh, int hdrlen)
{
return genlmsg_user_data (gnlh, hdrlen);
}
static int
genlmsg_len (const struct genlmsghdr *gnlh)
{
const struct nlmsghdr *nlh;
nlh = (const struct nlmsghdr *) ((const unsigned char *) gnlh - NLMSG_HDRLEN);
return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
}
static int
genlmsg_attrlen (const struct genlmsghdr *gnlh, int hdrlen)
{
return genlmsg_len (gnlh) - NLMSG_ALIGN (hdrlen);
}
static int
genlmsg_valid_hdr (struct nlmsghdr *nlh, int hdrlen)
{
struct genlmsghdr *ghdr;
if (!nlmsg_valid_hdr (nlh, GENL_HDRLEN))
return 0;
ghdr = nlmsg_data (nlh);
if (genlmsg_len (ghdr) < NLMSG_ALIGN (hdrlen))
return 0;
return 1;
}
static int
genlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
int maxtype, const struct nla_policy *policy)
{
struct genlmsghdr *ghdr;
if (!genlmsg_valid_hdr (nlh, hdrlen))
return -NLE_MSG_TOOSHORT;
ghdr = nlmsg_data (nlh);
return nla_parse (tb, maxtype, genlmsg_attrdata (ghdr, hdrlen),
genlmsg_attrlen (ghdr, hdrlen), policy);
}
/*****************************************************************************
* Reimplementation of libnl3/genl functions:
*****************************************************************************/
@ -258,11 +143,12 @@ out:
typedef struct {
WifiData parent;
struct nl_sock *nl_sock;
int id;
struct nl_cb *nl_cb;
guint32 *freqs;
int id;
int num_freqs;
int phy;
bool can_wowlan:1;
} WifiDataNl80211;
static int
@ -790,7 +676,6 @@ 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)
{
@ -799,16 +684,21 @@ wifi_nl80211_indicate_addressing_running (WifiData *data, gboolean running)
int err;
msg = nl80211_alloc_msg (nl80211,
running ? NL80211_CMD_CRIT_PROTOCOL_START :
NL80211_CMD_CRIT_PROTOCOL_STOP,
running
? 98 /* NL80211_CMD_CRIT_PROTOCOL_START */
: 99 /* 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);
NLA_PUT_U16 (msg,
179 /* NL80211_ATTR_CRIT_PROT_ID */,
1 /* NL80211_CRIT_PROTO_DHCP */);
if (running) {
/* Give DHCP 5 seconds to complete */
NLA_PUT_U16 (msg, NL80211_ATTR_MAX_CRIT_PROT_DURATION, 5000);
NLA_PUT_U16 (msg,
180 /* NL80211_ATTR_MAX_CRIT_PROT_DURATION */,
5000);
}
err = nl80211_send_and_recv (nl80211, msg, NULL, NULL);
@ -818,7 +708,6 @@ nla_put_failure:
nlmsg_free (msg);
return FALSE;
}
#endif
struct nl80211_wowlan_info {
gboolean enabled;
@ -850,9 +739,11 @@ wifi_nl80211_get_wowlan (WifiData *data)
struct nl_msg *msg;
struct nl80211_wowlan_info info;
if (!nl80211->can_wowlan)
return FALSE;
msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0);
nl80211_send_and_recv (nl80211, msg, nl80211_wowlan_handler, &info);
return info.enabled;
}
@ -1062,6 +953,20 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
WifiData *
wifi_nl80211_init (int ifindex)
{
static const WifiDataClass klass = {
.struct_size = sizeof (WifiDataNl80211),
.get_mode = wifi_nl80211_get_mode,
.set_mode = wifi_nl80211_set_mode,
.set_powersave = wifi_nl80211_set_powersave,
.get_freq = wifi_nl80211_get_freq,
.find_freq = wifi_nl80211_find_freq,
.get_bssid = wifi_nl80211_get_bssid,
.get_rate = wifi_nl80211_get_rate,
.get_qual = wifi_nl80211_get_qual,
.get_wowlan = wifi_nl80211_get_wowlan,
.indicate_addressing_running = wifi_nl80211_indicate_addressing_running,
.deinit = wifi_nl80211_deinit,
};
WifiDataNl80211 *nl80211;
struct nl_msg *msg;
struct nl80211_device_info device_info = {};
@ -1073,19 +978,7 @@ wifi_nl80211_init (int ifindex)
nm_sprintf_buf (ifname, "if %d", ifindex);
}
nl80211 = wifi_data_new (ifindex, sizeof (*nl80211));
nl80211->parent.get_mode = wifi_nl80211_get_mode;
nl80211->parent.set_mode = wifi_nl80211_set_mode;
nl80211->parent.set_powersave = wifi_nl80211_set_powersave;
nl80211->parent.get_freq = wifi_nl80211_get_freq;
nl80211->parent.find_freq = wifi_nl80211_find_freq;
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 = wifi_data_new (&klass, ifindex);
nl80211->nl_sock = nl_socket_alloc ();
if (nl80211->nl_sock == NULL)
@ -1153,18 +1046,15 @@ wifi_nl80211_init (int ifindex)
nl80211->freqs = device_info.freqs;
nl80211->num_freqs = device_info.num_freqs;
nl80211->parent.caps = device_info.caps;
if (device_info.can_wowlan)
nl80211->parent.get_wowlan = wifi_nl80211_get_wowlan;
nl80211->can_wowlan = device_info.can_wowlan;
_LOGI (LOGD_PLATFORM | LOGD_WIFI,
"(%s): using nl80211 for WiFi device control",
ifname);
return (WifiData *) nl80211;
error:
wifi_utils_deinit ((WifiData *) nl80211);
wifi_utils_unref ((WifiData *) nl80211);
return NULL;
}

View file

@ -24,9 +24,8 @@
#include "nm-dbus-interface.h"
#include "wifi-utils.h"
struct WifiData {
int ifindex;
NMDeviceWifiCapabilities caps;
typedef struct {
gsize struct_size;
NM80211Mode (*get_mode) (WifiData *data);
@ -66,9 +65,14 @@ struct WifiData {
gboolean (*set_mesh_ssid) (WifiData *data, const guint8 *ssid, gsize len);
gboolean (*indicate_addressing_running) (WifiData *data, gboolean running);
} WifiDataClass;
struct WifiData {
const WifiDataClass *klass;
int ifindex;
NMDeviceWifiCapabilities caps;
};
gpointer wifi_data_new (int ifindex, gsize len);
void wifi_data_free (WifiData *data);
gpointer wifi_data_new (const WifiDataClass *klass, int ifindex);
#endif /* __WIFI_UTILS_PRIVATE_H__ */

View file

@ -21,17 +21,14 @@
#include "nm-default.h"
#include "wifi-utils-wext.h"
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/ethernet.h>
#include <unistd.h>
#include "wifi-utils-private.h"
#include "wifi-utils-wext.h"
#include "nm-utils.h"
#include "platform/nm-platform-utils.h"
/* Hacks necessary to #include wireless.h; yay for WEXT */
#ifndef __user
#define __user
@ -41,6 +38,10 @@
#include <sys/socket.h>
#include <linux/wireless.h>
#include "wifi-utils-private.h"
#include "nm-utils.h"
#include "platform/nm-platform-utils.h"
typedef struct {
WifiData parent;
int fd;
@ -628,6 +629,21 @@ wext_get_caps (WifiDataWext *wext, const char *ifname, struct iw_range *range)
WifiData *
wifi_wext_init (int ifindex, gboolean check_scan)
{
static const WifiDataClass klass = {
.struct_size = sizeof (WifiDataWext),
.get_mode = wifi_wext_get_mode,
.set_mode = wifi_wext_set_mode,
.set_powersave = wifi_wext_set_powersave,
.get_freq = wifi_wext_get_freq,
.find_freq = wifi_wext_find_freq,
.get_bssid = wifi_wext_get_bssid,
.get_rate = wifi_wext_get_rate,
.get_qual = wifi_wext_get_qual,
.deinit = wifi_wext_deinit,
.get_mesh_channel = wifi_wext_get_mesh_channel,
.set_mesh_channel = wifi_wext_set_mesh_channel,
.set_mesh_ssid = wifi_wext_set_mesh_ssid,
};
WifiDataWext *wext;
struct iw_range range;
guint32 response_len = 0;
@ -642,19 +658,7 @@ wifi_wext_init (int ifindex, gboolean check_scan)
return NULL;
}
wext = wifi_data_new (ifindex, sizeof (*wext));
wext->parent.get_mode = wifi_wext_get_mode;
wext->parent.set_mode = wifi_wext_set_mode;
wext->parent.set_powersave = wifi_wext_set_powersave;
wext->parent.get_freq = wifi_wext_get_freq;
wext->parent.find_freq = wifi_wext_find_freq;
wext->parent.get_bssid = wifi_wext_get_bssid;
wext->parent.get_rate = wifi_wext_get_rate;
wext->parent.get_qual = wifi_wext_get_qual;
wext->parent.deinit = wifi_wext_deinit;
wext->parent.get_mesh_channel = wifi_wext_get_mesh_channel;
wext->parent.set_mesh_channel = wifi_wext_set_mesh_channel;
wext->parent.set_mesh_ssid = wifi_wext_set_mesh_ssid;
wext = wifi_data_new (&klass, ifindex);
wext->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (wext->fd < 0)
@ -730,7 +734,7 @@ wifi_wext_init (int ifindex, gboolean check_scan)
return (WifiData *) wext;
error:
wifi_utils_deinit ((WifiData *) wext);
wifi_utils_unref ((WifiData *) wext);
return NULL;
}

View file

@ -38,22 +38,19 @@
#include "platform/nm-platform-utils.h"
gpointer
wifi_data_new (int ifindex, gsize len)
wifi_data_new (const WifiDataClass *klass, int ifindex)
{
WifiData *data;
data = g_malloc0 (len);
nm_assert (klass);
nm_assert (klass->struct_size > sizeof (WifiData));
data = g_malloc0 (klass->struct_size);
data->klass = klass;
data->ifindex = ifindex;
return data;
}
void
wifi_data_free (WifiData *data)
{
memset (data, 0, sizeof (*data));
g_free (data);
}
/*****************************************************************************/
WifiData *
@ -85,14 +82,14 @@ wifi_utils_get_caps (WifiData *data)
{
g_return_val_if_fail (data != NULL, NM_WIFI_DEVICE_CAP_NONE);
return data->caps;
return data->caps;
}
NM80211Mode
wifi_utils_get_mode (WifiData *data)
{
g_return_val_if_fail (data != NULL, NM_802_11_MODE_UNKNOWN);
return data->get_mode (data);
return data->klass->get_mode (data);
}
gboolean
@ -104,7 +101,7 @@ wifi_utils_set_mode (WifiData *data, const NM80211Mode mode)
|| (mode == NM_802_11_MODE_ADHOC), FALSE);
/* nl80211 probably doesn't need this */
return data->set_mode ? data->set_mode (data, mode) : TRUE;
return data->klass->set_mode ? data->klass->set_mode (data, mode) : TRUE;
}
gboolean
@ -112,14 +109,14 @@ wifi_utils_set_powersave (WifiData *data, guint32 powersave)
{
g_return_val_if_fail (data != NULL, FALSE);
return data->set_powersave ? data->set_powersave (data, powersave) : TRUE;
return data->klass->set_powersave ? data->klass->set_powersave (data, powersave) : TRUE;
}
guint32
wifi_utils_get_freq (WifiData *data)
{
g_return_val_if_fail (data != NULL, 0);
return data->get_freq (data);
return data->klass->get_freq (data);
}
guint32
@ -127,7 +124,7 @@ wifi_utils_find_freq (WifiData *data, const guint32 *freqs)
{
g_return_val_if_fail (data != NULL, 0);
g_return_val_if_fail (freqs != NULL, 0);
return data->find_freq (data, freqs);
return data->klass->find_freq (data, freqs);
}
gboolean
@ -137,38 +134,40 @@ wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid)
g_return_val_if_fail (out_bssid != NULL, FALSE);
memset (out_bssid, 0, ETH_ALEN);
return data->get_bssid (data, out_bssid);
return data->klass->get_bssid (data, out_bssid);
}
guint32
wifi_utils_get_rate (WifiData *data)
{
g_return_val_if_fail (data != NULL, 0);
return data->get_rate (data);
return data->klass->get_rate (data);
}
int
wifi_utils_get_qual (WifiData *data)
{
g_return_val_if_fail (data != NULL, 0);
return data->get_qual (data);
return data->klass->get_qual (data);
}
gboolean
wifi_utils_get_wowlan (WifiData *data)
{
g_return_val_if_fail (data != NULL, 0);
if (!data->get_wowlan)
if (!data->klass->get_wowlan)
return FALSE;
return data->get_wowlan (data);
return data->klass->get_wowlan (data);
}
void
wifi_utils_deinit (WifiData *data)
wifi_utils_unref (WifiData *data)
{
g_return_if_fail (data != NULL);
data->deinit (data);
wifi_data_free (data);
data->klass->deinit (data);
g_free (data);
}
gboolean
@ -191,8 +190,8 @@ guint32
wifi_utils_get_mesh_channel (WifiData *data)
{
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (data->get_mesh_channel != NULL, FALSE);
return data->get_mesh_channel (data);
g_return_val_if_fail (data->klass->get_mesh_channel != NULL, FALSE);
return data->klass->get_mesh_channel (data);
}
gboolean
@ -200,24 +199,24 @@ wifi_utils_set_mesh_channel (WifiData *data, guint32 channel)
{
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (channel <= 13, FALSE);
g_return_val_if_fail (data->set_mesh_channel != NULL, FALSE);
return data->set_mesh_channel (data, channel);
g_return_val_if_fail (data->klass->set_mesh_channel != NULL, FALSE);
return data->klass->set_mesh_channel (data, channel);
}
gboolean
wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len)
{
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (data->set_mesh_ssid != NULL, FALSE);
return data->set_mesh_ssid (data, ssid, len);
g_return_val_if_fail (data->klass->set_mesh_ssid != NULL, FALSE);
return data->klass->set_mesh_ssid (data, ssid, len);
}
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);
if (data->klass->indicate_addressing_running)
return data->klass->indicate_addressing_running (data, running);
return FALSE;
}

View file

@ -34,7 +34,7 @@ WifiData *wifi_utils_init (int ifindex, gboolean check_scan);
int wifi_utils_get_ifindex (WifiData *data);
void wifi_utils_deinit (WifiData *data);
void wifi_utils_unref (WifiData *data);
NMDeviceWifiCapabilities wifi_utils_get_caps (WifiData *data);