summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-01-15 20:29:36 +0100
committerThomas Haller <thaller@redhat.com>2018-01-15 20:29:36 +0100
commit07d8431ae546dc51a87463be8f1f72bac7dc526a (patch)
tree87820415b7551298ceb8d020837478ffd8f87e82
parent345d34b36995103ca173f1a3ff07d02400c5d5f6 (diff)
parenta21a5558b1e50c05e0094dda2b76c8e128873366 (diff)
downloadNetworkManager-07d8431ae546dc51a87463be8f1f72bac7dc526a.tar.gz
platform: merge branch 'th/wifi-cleanup'
https://github.com/NetworkManager/NetworkManager/pull/58
-rw-r--r--Makefile.am3
-rw-r--r--config.h.meson3
-rw-r--r--configure.ac61
-rw-r--r--meson.build51
-rw-r--r--src/meson.build1
-rw-r--r--src/platform/nm-fake-platform.c1
-rw-r--r--src/platform/nm-linux-platform.c38
-rw-r--r--src/platform/nm-netlink.c122
-rw-r--r--src/platform/nm-netlink.h85
-rw-r--r--src/platform/wifi/wifi-utils-nl80211.c178
-rw-r--r--src/platform/wifi/wifi-utils-private.h14
-rw-r--r--src/platform/wifi/wifi-utils-wext.c42
-rw-r--r--src/platform/wifi/wifi-utils.c61
-rw-r--r--src/platform/wifi/wifi-utils.h2
14 files changed, 311 insertions, 351 deletions
diff --git a/Makefile.am b/Makefile.am
index 6b3bc3ad9e..5fd761f8e6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 \
diff --git a/config.h.meson b/config.h.meson
index 704c0a48d2..e07e128a65 100644
--- a/config.h.meson
+++ b/config.h.meson
@@ -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
diff --git a/configure.ac b/configure.ac
index 8afebe4cc5..5c694ef84c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
diff --git a/meson.build b/meson.build
index 8418cb1050..e59be17f96 100644
--- a/meson.build
+++ b/meson.build
@@ -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
diff --git a/src/meson.build b/src/meson.build
index db17bf1555..981a4794e4 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -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',
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index be43015281..06dd7e1398 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -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
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 3b692aee10..0128362864 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -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
diff --git a/src/platform/nm-netlink.c b/src/platform/nm-netlink.c
new file mode 100644
index 0000000000..45bc1cf75b
--- /dev/null
+++ b/src/platform/nm-netlink.c
@@ -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);
+}
+
+/*****************************************************************************/
diff --git a/src/platform/nm-netlink.h b/src/platform/nm-netlink.h
new file mode 100644
index 0000000000..64fcbfa4ad
--- /dev/null
+++ b/src/platform/nm-netlink.h
@@ -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__ */
diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c
index a5f25b0269..a2082b05d7 100644
--- a/src/platform/wifi/wifi-utils-nl80211.c
+++ b/src/platform/wifi/wifi-utils-nl80211.c
@@ -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;
}
diff --git a/src/platform/wifi/wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h
index 11a0f060dc..59386514d7 100644
--- a/src/platform/wifi/wifi-utils-private.h
+++ b/src/platform/wifi/wifi-utils-private.h
@@ -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__ */
diff --git a/src/platform/wifi/wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c
index c4d3c99962..c8744f79b6 100644
--- a/src/platform/wifi/wifi-utils-wext.c
+++ b/src/platform/wifi/wifi-utils-wext.c
@@ -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;
}
diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c
index d005212125..8818dc9d94 100644
--- a/src/platform/wifi/wifi-utils.c
+++ b/src/platform/wifi/wifi-utils.c
@@ -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;
}
diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h
index 705717b078..2633e96592 100644
--- a/src/platform/wifi/wifi-utils.h
+++ b/src/platform/wifi/wifi-utils.h
@@ -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);