diff options
author | Thomas Haller <thaller@redhat.com> | 2017-10-10 18:20:05 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-10-12 10:38:19 +0200 |
commit | 5b0745e7bd77b5b4dcd2a2061820fe2e80615ba8 (patch) | |
tree | 72b451c32e473bbbacb5113385f80ff5420d842a | |
parent | 5b507d5787b74d58fdfc97c4c381cc48b150ccba (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.c | 15 | ||||
-rw-r--r-- | src/nm-iface-helper.c | 3 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 26 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 54 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 13 | ||||
-rw-r--r-- | src/platform/tests/test-link.c | 3 |
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); |