summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-10-10 18:20:05 +0200
committerThomas Haller <thaller@redhat.com>2017-10-12 10:38:19 +0200
commit5b0745e7bd77b5b4dcd2a2061820fe2e80615ba8 (patch)
tree72b451c32e473bbbacb5113385f80ff5420d842a
parent5b507d5787b74d58fdfc97c4c381cc48b150ccba (diff)
platform: refactor detecting kernel support
We are going to add another parameter to check. Instead of adding multiple virtual functions, add a NMPlatformKernelSupportFlags flags enum.
-rw-r--r--src/devices/nm-device.c15
-rw-r--r--src/nm-iface-helper.c3
-rw-r--r--src/platform/nm-linux-platform.c26
-rw-r--r--src/platform/nm-platform.c54
-rw-r--r--src/platform/nm-platform.h13
-rw-r--r--src/platform/tests/test-link.c3
6 files changed, 65 insertions, 49 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index fd6f840a75..0e9833bd3d 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1203,7 +1203,8 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface)
}
if (priv->ip_ifindex > 0) {
- if (nm_platform_check_support_user_ipv6ll (nm_device_get_platform (self)))
+ if (nm_platform_check_kernel_support (nm_device_get_platform (self),
+ NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL))
nm_platform_link_set_user_ipv6ll_enabled (nm_device_get_platform (self), priv->ip_ifindex, TRUE);
if (!nm_platform_link_is_up (nm_device_get_platform (self), priv->ip_ifindex))
@@ -3308,7 +3309,8 @@ realize_start_setup (NMDevice *self,
if (priv->firmware_version)
_notify (self, PROP_FIRMWARE_VERSION);
- if (nm_platform_check_support_user_ipv6ll (nm_device_get_platform (self)))
+ if (nm_platform_check_kernel_support (nm_device_get_platform (self),
+ NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL))
priv->nm_ipv6ll = nm_platform_link_get_user_ipv6ll_enabled (nm_device_get_platform (self), priv->ifindex);
if (nm_platform_link_supports_sriov (nm_device_get_platform (self), priv->ifindex))
@@ -7370,7 +7372,8 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
* addresses as /128. The reason for the /128 is to prevent the kernel
* from adding a prefix route for this address. */
ifa_flags = 0;
- if (nm_platform_check_support_kernel_extended_ifa_flags (nm_device_get_platform (self))) {
+ if (nm_platform_check_kernel_support (nm_device_get_platform (self),
+ NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS)) {
ifa_flags |= IFA_F_NOPREFIXROUTE;
if (NM_IN_SET (priv->ndisc_use_tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR))
@@ -7586,7 +7589,8 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
priv->ndisc_use_tempaddr = use_tempaddr;
if ( NM_IN_SET (use_tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)
- && !nm_platform_check_support_kernel_extended_ifa_flags (nm_device_get_platform (self))) {
+ && !nm_platform_check_kernel_support (nm_device_get_platform (self),
+ NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS)) {
_LOGW (LOGD_IP6, "The kernel does not support extended IFA_FLAGS needed by NM for "
"IPv6 private addresses. This feature is not available");
}
@@ -7686,7 +7690,8 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable)
int ifindex = nm_device_get_ip_ifindex (self);
char *value;
- if (!nm_platform_check_support_user_ipv6ll (nm_device_get_platform (self)))
+ if (!nm_platform_check_kernel_support (nm_device_get_platform (self),
+ NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL))
return;
priv->nm_ipv6ll = enable;
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index 4be92bfb44..8f6331e3c9 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -183,7 +183,8 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
* addresses as /128. The reason for the /128 is to prevent the kernel
* from adding a prefix route for this address. */
ifa_flags = 0;
- if (nm_platform_check_support_kernel_extended_ifa_flags (NM_PLATFORM_GET)) {
+ if (nm_platform_check_kernel_support (NM_PLATFORM_GET,
+ NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS)) {
ifa_flags |= IFA_F_NOPREFIXROUTE;
if (NM_IN_SET (global_opt.tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR))
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index ee52446071..f7ce9851aa 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -3074,20 +3074,25 @@ sysctl_get (NMPlatform *platform, const char *pathid, int dirfd, const char *pat
/*****************************************************************************/
-static gboolean
-check_support_kernel_extended_ifa_flags (NMPlatform *platform)
+static NMPlatformKernelSupportFlags
+check_kernel_support (NMPlatform *platform,
+ NMPlatformKernelSupportFlags request_flags)
{
+ NMPlatformKernelSupportFlags response = 0;
+
nm_assert (NM_IS_LINUX_PLATFORM (platform));
- return _support_kernel_extended_ifa_flags_get ();
-}
+ if (NM_FLAGS_HAS (request_flags, NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS)) {
+ if (_support_kernel_extended_ifa_flags_get ())
+ response |= NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS;
+ }
-static gboolean
-check_support_user_ipv6ll (NMPlatform *platform)
-{
- nm_assert (NM_IS_LINUX_PLATFORM (platform));
+ if (NM_FLAGS_HAS (request_flags, NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL)) {
+ if (_support_user_ipv6ll_get ())
+ response |= NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL;
+ }
- return _support_user_ipv6ll_get ();
+ return response;
}
static void
@@ -6864,8 +6869,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->ip_route_delete = ip_route_delete;
platform_class->ip_route_get = ip_route_get;
- platform_class->check_support_kernel_extended_ifa_flags = check_support_kernel_extended_ifa_flags;
- platform_class->check_support_user_ipv6ll = check_support_user_ipv6ll;
+ platform_class->check_kernel_support = check_kernel_support;
platform_class->process_events = process_events;
}
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 9b0929757e..222b68f8e0 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -92,8 +92,8 @@ typedef struct _NMPlatformPrivate {
bool use_udev:1;
bool log_with_ptr:1;
- gint8 check_support_kernel_extended_ifa_flags_cached;
- gint8 check_support_user_ipv6ll_cached;
+ NMPlatformKernelSupportFlags support_checked;
+ NMPlatformKernelSupportFlags support_present;
guint ip4_dev_route_blacklist_check_id;
guint ip4_dev_route_blacklist_gc_timeout_id;
@@ -301,8 +301,9 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_nmp_nlm_flag_to_string_lookup, NMPNlmFlags,
/*****************************************************************************/
-gboolean
-nm_platform_check_support_kernel_extended_ifa_flags (NMPlatform *self)
+NMPlatformKernelSupportFlags
+nm_platform_check_kernel_support (NMPlatform *self,
+ NMPlatformKernelSupportFlags request_flags)
{
NMPlatformPrivate *priv;
@@ -310,29 +311,28 @@ nm_platform_check_support_kernel_extended_ifa_flags (NMPlatform *self)
priv = NM_PLATFORM_GET_PRIVATE (self);
- if (G_UNLIKELY (priv->check_support_kernel_extended_ifa_flags_cached == 0)) {
- priv->check_support_kernel_extended_ifa_flags_cached = ( klass->check_support_kernel_extended_ifa_flags
- && klass->check_support_kernel_extended_ifa_flags (self))
- ? 1 : -1;
- }
- return priv->check_support_kernel_extended_ifa_flags_cached >= 0;
-}
-
-gboolean
-nm_platform_check_support_user_ipv6ll (NMPlatform *self)
-{
- NMPlatformPrivate *priv;
-
- _CHECK_SELF (self, klass, TRUE);
-
- priv = NM_PLATFORM_GET_PRIVATE (self);
+ /* we cache the response from subclasses and only request it once.
+ * This probably gives better performance, but more importantly,
+ * we are guaranteed that the answer for a certain request_flag
+ * is always the same. */
+ if (G_UNLIKELY (!NM_FLAGS_ALL (priv->support_checked, request_flags))) {
+ NMPlatformKernelSupportFlags checked, response;
+
+ checked = request_flags & ~priv->support_checked;
+ nm_assert (checked);
+
+ if (klass->check_kernel_support)
+ response = klass->check_kernel_support (self, checked);
+ else {
+ /* fake platform. Pretend no support for anything. */
+ response = 0;
+ }
- if (G_UNLIKELY (priv->check_support_user_ipv6ll_cached == 0)) {
- priv->check_support_user_ipv6ll_cached = ( klass->check_support_user_ipv6ll
- && klass->check_support_user_ipv6ll (self))
- ? 1 : -1;
+ priv->support_checked |= checked;
+ priv->support_present = (priv->support_present & ~checked) | (response & checked);
}
- return priv->check_support_user_ipv6ll_cached >= 0;
+
+ return priv->support_present & request_flags;
}
/**
@@ -3421,7 +3421,7 @@ delete_and_next:
if (!known_addresses)
return TRUE;
- ifa_flags = nm_platform_check_support_kernel_extended_ifa_flags (self)
+ ifa_flags = nm_platform_check_kernel_support (self, NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS)
? IFA_F_NOPREFIXROUTE
: 0;
@@ -3503,7 +3503,7 @@ nm_platform_ip6_address_sync (NMPlatform *self,
if (!known_addresses)
return TRUE;
- ifa_flags = nm_platform_check_support_kernel_extended_ifa_flags (self)
+ ifa_flags = nm_platform_check_kernel_support (self, NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS)
? IFA_F_NOPREFIXROUTE
: 0;
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 0f953f122d..3d6e5bf7f5 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -659,6 +659,11 @@ typedef enum {
NM_PLATFORM_LINK_DUPLEX_FULL,
} NMPlatformLinkDuplexType;
+typedef enum {
+ NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS = (1LL << 0),
+ NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL = (1LL << 1),
+} NMPlatformKernelSupportFlags;
+
/*****************************************************************************/
struct _NMPlatformPrivate;
@@ -824,8 +829,8 @@ typedef struct {
int oif_ifindex,
NMPObject **out_route);
- gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *);
- gboolean (*check_support_user_ipv6ll) (NMPlatform *);
+ NMPlatformKernelSupportFlags (*check_kernel_support) (NMPlatform * self,
+ NMPlatformKernelSupportFlags request_flags);
} NMPlatformClass;
/* NMPlatform signals
@@ -1315,8 +1320,8 @@ nm_platform_ip6_route_hash_full (const NMPlatformIP6Route *obj)
return nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL);
}
-gboolean nm_platform_check_support_kernel_extended_ifa_flags (NMPlatform *self);
-gboolean nm_platform_check_support_user_ipv6ll (NMPlatform *self);
+NMPlatformKernelSupportFlags nm_platform_check_kernel_support (NMPlatform *self,
+ NMPlatformKernelSupportFlags request_flags);
const char *nm_platform_link_flags2str (unsigned flags, char *buf, gsize len);
const char *nm_platform_link_inet6_addrgenmode2str (guint8 mode, char *buf, gsize len);
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index 0a974eb13a..ccbada32d7 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -512,7 +512,8 @@ test_bridge_addr (void)
plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex);
g_assert (plink);
- if (nm_platform_check_support_user_ipv6ll (NM_PLATFORM_GET)) {
+ if (nm_platform_check_kernel_support (NM_PLATFORM_GET,
+ NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL)) {
g_assert (!nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex));
g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64);