diff options
| author | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
| commit | aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch) | |
| tree | a2a9bb4d007339a0b1304540388230ccedac32bd /src/platform/nm-platform.c | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'src/platform/nm-platform.c')
| -rw-r--r-- | src/platform/nm-platform.c | 12330 |
1 files changed, 6544 insertions, 5786 deletions
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 4702ba97..d1ff6fbc 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2012 - 2018 Red Hat, Inc. */ @@ -36,220 +36,226 @@ /*****************************************************************************/ -G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPAddress, address_ptr) == G_STRUCT_OFFSET (NMPlatformIP4Address, address)); -G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPAddress, address_ptr) == G_STRUCT_OFFSET (NMPlatformIP6Address, address)); -G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPRoute, network_ptr) == G_STRUCT_OFFSET (NMPlatformIP4Route, network)); -G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPRoute, network_ptr) == G_STRUCT_OFFSET (NMPlatformIP6Route, network)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPAddress, address_ptr) + == G_STRUCT_OFFSET(NMPlatformIP4Address, address)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPAddress, address_ptr) + == G_STRUCT_OFFSET(NMPlatformIP6Address, address)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPRoute, network_ptr) + == G_STRUCT_OFFSET(NMPlatformIP4Route, network)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPRoute, network_ptr) + == G_STRUCT_OFFSET(NMPlatformIP6Route, network)); -G_STATIC_ASSERT (_nm_alignof (NMPlatformIPRoute) == _nm_alignof (NMPlatformIP4Route)); -G_STATIC_ASSERT (_nm_alignof (NMPlatformIPRoute) == _nm_alignof (NMPlatformIP6Route)); -G_STATIC_ASSERT (_nm_alignof (NMPlatformIPRoute) == _nm_alignof (NMPlatformIPXRoute)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPRoute) == _nm_alignof(NMPlatformIP4Route)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPRoute) == _nm_alignof(NMPlatformIP6Route)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPRoute) == _nm_alignof(NMPlatformIPXRoute)); -G_STATIC_ASSERT (_nm_alignof (NMPlatformIPAddress) == _nm_alignof (NMPlatformIP4Address)); -G_STATIC_ASSERT (_nm_alignof (NMPlatformIPAddress) == _nm_alignof (NMPlatformIP6Address)); -G_STATIC_ASSERT (_nm_alignof (NMPlatformIPAddress) == _nm_alignof (NMPlatformIPXAddress)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPAddress) == _nm_alignof(NMPlatformIP4Address)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPAddress) == _nm_alignof(NMPlatformIP6Address)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPAddress) == _nm_alignof(NMPlatformIPXAddress)); /*****************************************************************************/ -G_STATIC_ASSERT (sizeof ( ((NMPLinkAddress *) NULL)->data ) == NM_UTILS_HWADDR_LEN_MAX); -G_STATIC_ASSERT (sizeof ( ((NMPlatformLink *) NULL)->l_address.data ) == NM_UTILS_HWADDR_LEN_MAX); -G_STATIC_ASSERT (sizeof ( ((NMPlatformLink *) NULL)->l_broadcast.data ) == NM_UTILS_HWADDR_LEN_MAX); +G_STATIC_ASSERT(sizeof(((NMPLinkAddress *) NULL)->data) == NM_UTILS_HWADDR_LEN_MAX); +G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_address.data) == NM_UTILS_HWADDR_LEN_MAX); +G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_broadcast.data) == NM_UTILS_HWADDR_LEN_MAX); static const char * -_nmp_link_address_to_string (const NMPLinkAddress *addr, - char buf[static (NM_UTILS_HWADDR_LEN_MAX * 3)]) +_nmp_link_address_to_string(const NMPLinkAddress *addr, + char buf[static(NM_UTILS_HWADDR_LEN_MAX * 3)]) { - nm_assert (addr); + nm_assert(addr); - if (addr->len > 0) { - if (!nm_utils_hwaddr_ntoa_buf (addr->data, - addr->len, - TRUE, - buf, - NM_UTILS_HWADDR_LEN_MAX * 3)) { - buf[0] = '\0'; - g_return_val_if_reached (buf); - } - } else - buf[0] = '\0'; + if (addr->len > 0) { + if (!_nm_utils_hwaddr_ntoa(addr->data, addr->len, TRUE, buf, NM_UTILS_HWADDR_LEN_MAX * 3)) { + buf[0] = '\0'; + g_return_val_if_reached(buf); + } + } else + buf[0] = '\0'; - return buf; + return buf; } gconstpointer -nmp_link_address_get (const NMPLinkAddress *addr, size_t *length) +nmp_link_address_get(const NMPLinkAddress *addr, size_t *length) { - if ( !addr - || addr->len <= 0) { - NM_SET_OUT (length, 0); - return NULL; - } + if (!addr || addr->len <= 0) { + NM_SET_OUT(length, 0); + return NULL; + } - if (addr->len > NM_UTILS_HWADDR_LEN_MAX) { - NM_SET_OUT (length, 0); - g_return_val_if_reached (NULL); - } + if (addr->len > NM_UTILS_HWADDR_LEN_MAX) { + NM_SET_OUT(length, 0); + g_return_val_if_reached(NULL); + } - NM_SET_OUT (length, addr->len); - return addr->data; + NM_SET_OUT(length, addr->len); + return addr->data; } GBytes * -nmp_link_address_get_as_bytes (const NMPLinkAddress *addr) +nmp_link_address_get_as_bytes(const NMPLinkAddress *addr) { - gconstpointer data; - size_t length; + gconstpointer data; + size_t length; - data = nmp_link_address_get (addr, &length); + data = nmp_link_address_get(addr, &length); - return length > 0 - ? g_bytes_new (data, length) - : NULL; + return length > 0 ? g_bytes_new(data, length) : NULL; } /*****************************************************************************/ -#define _NMLOG_DOMAIN LOGD_PLATFORM -#define _NMLOG_PREFIX_NAME "platform" - - -#define NMLOG_COMMON(level, name, ...) \ - char __prefix[32]; \ - const char *__p_prefix = _NMLOG_PREFIX_NAME; \ - const NMPlatform *const __self = (self); \ - const char *__name = name; \ - \ - if (__self && NM_PLATFORM_GET_PRIVATE (__self)->log_with_ptr) { \ - g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ - __p_prefix = __prefix; \ - } \ - _nm_log (__level, _NMLOG_DOMAIN, 0, __name, NULL, \ - "%s: %s%s%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - __p_prefix, \ - NM_PRINT_FMT_QUOTED (__name, "(", __name, ") ", "") \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)); - -#define _NMLOG(level, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - \ - if (nm_logging_enabled (__level, _NMLOG_DOMAIN)) { \ - NMLOG_COMMON(level, NULL, __VA_ARGS__); \ - } \ - } G_STMT_END - -#define _NMLOG2(level, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - \ - if (nm_logging_enabled (__level, _NMLOG_DOMAIN)) { \ - NMLOG_COMMON(level, name, __VA_ARGS__); \ - } \ - } G_STMT_END - -#define _NMLOG3(level, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - \ - if (nm_logging_enabled (__level, _NMLOG_DOMAIN)) { \ - NMLOG_COMMON(level, ifindex > 0 ? nm_platform_link_get_name (self, ifindex) : NULL, __VA_ARGS__); \ - } \ - } G_STMT_END +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG_PREFIX_NAME "platform" + +#define NMLOG_COMMON(level, name, ...) \ + char __prefix[32]; \ + const char * __p_prefix = _NMLOG_PREFIX_NAME; \ + const NMPlatform *const __self = (self); \ + const char * __name = name; \ + \ + if (__self && NM_PLATFORM_GET_PRIVATE(__self)->log_with_ptr) { \ + g_snprintf(__prefix, sizeof(__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ + __p_prefix = __prefix; \ + } \ + _nm_log(__level, \ + _NMLOG_DOMAIN, \ + 0, \ + __name, \ + NULL, \ + "%s: %s%s%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __p_prefix, \ + NM_PRINT_FMT_QUOTED(__name, "(", __name, ") ", "") _NM_UTILS_MACRO_REST(__VA_ARGS__)); + +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + NMLOG_COMMON(level, NULL, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + +#define _NMLOG2(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + NMLOG_COMMON(level, name, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + +#define _NMLOG3(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + NMLOG_COMMON(level, \ + ifindex > 0 ? nm_platform_link_get_name(self, ifindex) : NULL, \ + __VA_ARGS__); \ + } \ + } \ + G_STMT_END /*****************************************************************************/ -static guint signals[_NM_PLATFORM_SIGNAL_ID_LAST] = { 0 }; +static guint signals[_NM_PLATFORM_SIGNAL_ID_LAST] = {0}; enum { - PROP_0, - PROP_NETNS_SUPPORT, - PROP_USE_UDEV, - PROP_LOG_WITH_PTR, - LAST_PROP, + PROP_0, + PROP_NETNS_SUPPORT, + PROP_USE_UDEV, + PROP_LOG_WITH_PTR, + LAST_PROP, }; typedef struct _NMPlatformPrivate { - bool use_udev:1; - bool log_with_ptr:1; - - guint ip4_dev_route_blacklist_check_id; - guint ip4_dev_route_blacklist_gc_timeout_id; - GHashTable *ip4_dev_route_blacklist_hash; - NMDedupMultiIndex *multi_idx; - NMPCache *cache; + bool use_udev : 1; + bool log_with_ptr : 1; + + guint ip4_dev_route_blacklist_check_id; + guint ip4_dev_route_blacklist_gc_timeout_id; + GHashTable * ip4_dev_route_blacklist_hash; + NMDedupMultiIndex *multi_idx; + NMPCache * cache; } NMPlatformPrivate; -G_DEFINE_TYPE (NMPlatform, nm_platform, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMPlatform, nm_platform, G_TYPE_OBJECT) -#define NM_PLATFORM_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR (self, NMPlatform, NM_IS_PLATFORM) +#define NM_PLATFORM_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMPlatform, NM_IS_PLATFORM) /*****************************************************************************/ -static void _ip4_dev_route_blacklist_schedule (NMPlatform *self); +static void _ip4_dev_route_blacklist_schedule(NMPlatform *self); /*****************************************************************************/ gboolean -nm_platform_get_use_udev (NMPlatform *self) +nm_platform_get_use_udev(NMPlatform *self) { - return NM_PLATFORM_GET_PRIVATE (self)->use_udev; + return NM_PLATFORM_GET_PRIVATE(self)->use_udev; } gboolean -nm_platform_get_log_with_ptr (NMPlatform *self) +nm_platform_get_log_with_ptr(NMPlatform *self) { - return NM_PLATFORM_GET_PRIVATE (self)->log_with_ptr; + return NM_PLATFORM_GET_PRIVATE(self)->log_with_ptr; } /*****************************************************************************/ guint -_nm_platform_signal_id_get (NMPlatformSignalIdType signal_type) +_nm_platform_signal_id_get(NMPlatformSignalIdType signal_type) { - nm_assert ( signal_type > 0 - && signal_type != NM_PLATFORM_SIGNAL_ID_NONE - && signal_type < _NM_PLATFORM_SIGNAL_ID_LAST); + nm_assert(signal_type > 0 && signal_type != NM_PLATFORM_SIGNAL_ID_NONE + && signal_type < _NM_PLATFORM_SIGNAL_ID_LAST); - return signals[signal_type]; + return signals[signal_type]; } /*****************************************************************************/ /* Singleton NMPlatform subclass instance and cached class object */ -NM_DEFINE_SINGLETON_INSTANCE (NMPlatform); +NM_DEFINE_SINGLETON_INSTANCE(NMPlatform); -NM_DEFINE_SINGLETON_REGISTER (NMPlatform); +NM_DEFINE_SINGLETON_REGISTER(NMPlatform); /* Just always initialize a @klass instance. NM_PLATFORM_GET_CLASS() * is only a plain read on the self instance, which the compiler * like can optimize out. */ -#define _CHECK_SELF_VOID(self, klass) \ - NMPlatformClass *klass; \ - do { \ - g_return_if_fail (NM_IS_PLATFORM (self)); \ - klass = NM_PLATFORM_GET_CLASS (self); \ - (void) klass; \ - } while (0) - -#define _CHECK_SELF(self, klass, err_val) \ - NMPlatformClass *klass; \ - do { \ - g_return_val_if_fail (NM_IS_PLATFORM (self), err_val); \ - klass = NM_PLATFORM_GET_CLASS (self); \ - (void) klass; \ - } while (0) - -#define _CHECK_SELF_NETNS(self, klass, netns, err_val) \ - nm_auto_pop_netns NMPNetns *netns = NULL; \ - NMPlatformClass *klass; \ - do { \ - g_return_val_if_fail (NM_IS_PLATFORM (self), err_val); \ - klass = NM_PLATFORM_GET_CLASS (self); \ - (void) klass; \ - if (!nm_platform_netns_push (self, &netns)) \ - return (err_val); \ - } while (0) +#define _CHECK_SELF_VOID(self, klass) \ + NMPlatformClass *klass; \ + do { \ + g_return_if_fail(NM_IS_PLATFORM(self)); \ + klass = NM_PLATFORM_GET_CLASS(self); \ + (void) klass; \ + } while (0) + +#define _CHECK_SELF(self, klass, err_val) \ + NMPlatformClass *klass; \ + do { \ + g_return_val_if_fail(NM_IS_PLATFORM(self), err_val); \ + klass = NM_PLATFORM_GET_CLASS(self); \ + (void) klass; \ + } while (0) + +#define _CHECK_SELF_NETNS(self, klass, netns, err_val) \ + nm_auto_pop_netns NMPNetns *netns = NULL; \ + NMPlatformClass * klass; \ + do { \ + g_return_val_if_fail(NM_IS_PLATFORM(self), err_val); \ + klass = NM_PLATFORM_GET_CLASS(self); \ + (void) klass; \ + if (!nm_platform_netns_push(self, &netns)) \ + return (err_val); \ + } while (0) /** * nm_platform_setup: @@ -264,17 +270,19 @@ NM_DEFINE_SINGLETON_REGISTER (NMPlatform); * though. */ void -nm_platform_setup (NMPlatform *instance) +nm_platform_setup(NMPlatform *instance) { - g_return_if_fail (NM_IS_PLATFORM (instance)); - g_return_if_fail (!singleton_instance); + g_return_if_fail(NM_IS_PLATFORM(instance)); + g_return_if_fail(!singleton_instance); - singleton_instance = instance; + singleton_instance = instance; - nm_singleton_instance_register (); + nm_singleton_instance_register(); - nm_log_dbg (LOGD_CORE, "setup %s singleton ("NM_HASH_OBFUSCATE_PTR_FMT")", - "NMPlatform", NM_HASH_OBFUSCATE_PTR (instance)); + nm_log_dbg(LOGD_CORE, + "setup %s singleton (" NM_HASH_OBFUSCATE_PTR_FMT ")", + "NMPlatform", + NM_HASH_OBFUSCATE_PTR(instance)); } /** @@ -287,138 +295,152 @@ nm_platform_setup (NMPlatform *instance) * Returns: (transfer none): The #NMPlatform singleton reference. */ NMPlatform * -nm_platform_get () +nm_platform_get() { - g_assert (singleton_instance); + g_assert(singleton_instance); - return singleton_instance; + return singleton_instance; } /*****************************************************************************/ NMDedupMultiIndex * -nm_platform_get_multi_idx (NMPlatform *self) +nm_platform_get_multi_idx(NMPlatform *self) { - g_return_val_if_fail (NM_IS_PLATFORM (self), NULL); + g_return_val_if_fail(NM_IS_PLATFORM(self), NULL); - return NM_PLATFORM_GET_PRIVATE (self)->multi_idx; + return NM_PLATFORM_GET_PRIVATE(self)->multi_idx; } /*****************************************************************************/ -static -NM_UTILS_LOOKUP_STR_DEFINE (_nmp_nlm_flag_to_string_lookup, NMPNlmFlags, - NM_UTILS_LOOKUP_DEFAULT (NULL), - NM_UTILS_LOOKUP_ITEM (NMP_NLM_FLAG_ADD, "add"), - NM_UTILS_LOOKUP_ITEM (NMP_NLM_FLAG_CHANGE, "change"), - NM_UTILS_LOOKUP_ITEM (NMP_NLM_FLAG_REPLACE, "replace"), - NM_UTILS_LOOKUP_ITEM (NMP_NLM_FLAG_PREPEND, "prepend"), - NM_UTILS_LOOKUP_ITEM (NMP_NLM_FLAG_APPEND, "append"), - NM_UTILS_LOOKUP_ITEM (NMP_NLM_FLAG_TEST, "test"), - NM_UTILS_LOOKUP_ITEM_IGNORE (NMP_NLM_FLAG_F_APPEND), - NM_UTILS_LOOKUP_ITEM_IGNORE (NMP_NLM_FLAG_FMASK), - NM_UTILS_LOOKUP_ITEM_IGNORE (NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE), - NM_UTILS_LOOKUP_ITEM_IGNORE (NMP_NLM_FLAG_F_ECHO), -); - -#define _nmp_nlm_flag_to_string(flags) \ - ({ \ - NMPNlmFlags _flags = (flags); \ - \ - _nmp_nlm_flag_to_string_lookup (flags) ?: nm_sprintf_bufa (100, "new[0x%x]", (unsigned) _flags); \ - }) +static NM_UTILS_LOOKUP_STR_DEFINE( + _nmp_nlm_flag_to_string_lookup, + NMPNlmFlags, + NM_UTILS_LOOKUP_DEFAULT(NULL), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_ADD, "add"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_CHANGE, "change"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_REPLACE, "replace"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_PREPEND, "prepend"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_APPEND, "append"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_TEST, "test"), + NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_F_APPEND), + NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_FMASK), + NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE), + NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_F_ECHO), ); + +#define _nmp_nlm_flag_to_string(flags) \ + ({ \ + NMPNlmFlags _flags = (flags); \ + \ + _nmp_nlm_flag_to_string_lookup(flags) \ + ?: nm_sprintf_bufa(100, "new[0x%x]", (unsigned) _flags); \ + }) /*****************************************************************************/ -volatile int _nm_platform_kernel_support_state[_NM_PLATFORM_KERNEL_SUPPORT_NUM] = { }; +volatile int _nm_platform_kernel_support_state[_NM_PLATFORM_KERNEL_SUPPORT_NUM] = {}; static const struct { - bool compile_time_default; - const char *name; - const char *desc; + bool compile_time_default; + const char *name; + const char *desc; } _nm_platform_kernel_support_info[_NM_PLATFORM_KERNEL_SUPPORT_NUM] = { - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS] = { - .compile_time_default = TRUE, - .name = "EXTENDED_IFA_FLAGS", - .desc = "IPv6 temporary addresses support", - }, - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL] = { - .compile_time_default = TRUE, - .name = "USER_IPV6LL", - .desc = "IFLA_INET6_ADDR_GEN_MODE support", - }, - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF] = { - .compile_time_default = (RTA_MAX >= 20 /* RTA_PREF */), - .name = "RTA_PREF", - .desc = "ability to set router preference for IPv6 routes", - }, - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV] = { - .compile_time_default = (FRA_MAX >= 19 /* FRA_L3MDEV */), - .name = "FRA_L3MDEV", - .desc = "FRA_L3MDEV attribute for policy routing rules", - }, - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE] = { - .compile_time_default = (FRA_MAX >= 20 /* FRA_UID_RANGE */), - .name = "FRA_UID_RANGE", - .desc = "FRA_UID_RANGE attribute for policy routing rules", - }, - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL] = { - .compile_time_default = (FRA_MAX >= 21 /* FRA_PROTOCOL */), - .name = "FRA_PROTOCOL", - .desc = "FRA_PROTOCOL attribute for policy routing rules", - }, - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO] = { - .compile_time_default = (FRA_MAX >= 22 /* FRA_IP_PROTO */), - .name = "FRA_IP_PROTO", - .desc = "FRA_IP_PROTO, FRA_SPORT_RANGE, FRA_DPORT_RANGE attributes for policy routing rules", - }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS] = + { + .compile_time_default = TRUE, + .name = "EXTENDED_IFA_FLAGS", + .desc = "IPv6 temporary addresses support", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL] = + { + .compile_time_default = TRUE, + .name = "USER_IPV6LL", + .desc = "IFLA_INET6_ADDR_GEN_MODE support", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF] = + { + .compile_time_default = (RTA_MAX >= 20 /* RTA_PREF */), + .name = "RTA_PREF", + .desc = "ability to set router preference for IPv6 routes", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV] = + { + .compile_time_default = (FRA_MAX >= 19 /* FRA_L3MDEV */), + .name = "FRA_L3MDEV", + .desc = "FRA_L3MDEV attribute for policy routing rules", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE] = + { + .compile_time_default = (FRA_MAX >= 20 /* FRA_UID_RANGE */), + .name = "FRA_UID_RANGE", + .desc = "FRA_UID_RANGE attribute for policy routing rules", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL] = + { + .compile_time_default = (FRA_MAX >= 21 /* FRA_PROTOCOL */), + .name = "FRA_PROTOCOL", + .desc = "FRA_PROTOCOL attribute for policy routing rules", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO] = + { + .compile_time_default = (FRA_MAX >= 22 /* FRA_IP_PROTO */), + .name = "FRA_IP_PROTO", + .desc = "FRA_IP_PROTO, FRA_SPORT_RANGE, FRA_DPORT_RANGE attributes for policy routing " + "rules", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED] = + { + .compile_time_default = (IFLA_BR_MAX >= 41 /* IFLA_BR_VLAN_STATS_ENABLED */), + .name = "IFLA_BR_VLAN_STATS_ENABLE", + .desc = "IFLA_BR_VLAN_STATS_ENABLE bridge link attribute", + }, }; int -_nm_platform_kernel_support_init (NMPlatformKernelSupportType type, - int value) +_nm_platform_kernel_support_init(NMPlatformKernelSupportType type, int value) { - volatile int *p_state; - gboolean set_default = FALSE; + volatile int *p_state; + gboolean set_default = FALSE; - nm_assert (_NM_INT_NOT_NEGATIVE (type) && type < G_N_ELEMENTS (_nm_platform_kernel_support_state)); + nm_assert(_NM_INT_NOT_NEGATIVE(type) && type < G_N_ELEMENTS(_nm_platform_kernel_support_state)); - p_state = &_nm_platform_kernel_support_state[type]; + p_state = &_nm_platform_kernel_support_state[type]; - if (value == 0) { - set_default = TRUE; - value = _nm_platform_kernel_support_info[type].compile_time_default - ? 1 - : -1; - } + if (value == 0) { + set_default = TRUE; + value = _nm_platform_kernel_support_info[type].compile_time_default ? 1 : -1; + } - nm_assert (NM_IN_SET (value, -1, 1)); + nm_assert(NM_IN_SET(value, -1, 1)); - if (!g_atomic_int_compare_and_exchange (p_state, 0, value)) { - value = g_atomic_int_get (p_state); - nm_assert (NM_IN_SET (value, -1, 1)); - return value; - } + if (!g_atomic_int_compare_and_exchange(p_state, 0, value)) { + value = g_atomic_int_get(p_state); + nm_assert(NM_IN_SET(value, -1, 1)); + return value; + } #undef NM_THREAD_SAFE_ON_MAIN_THREAD #define NM_THREAD_SAFE_ON_MAIN_THREAD 0 - if (set_default) { - nm_log_dbg (LOGD_PLATFORM, "platform: kernel-support for %s (%s) not detected: assume %ssupported", - _nm_platform_kernel_support_info[type].name, - _nm_platform_kernel_support_info[type].desc, - value >= 0 ? "" : "not "); - } else { - nm_log_dbg (LOGD_PLATFORM, "platform: kernel-support for %s (%s) detected: %ssupported", - _nm_platform_kernel_support_info[type].name, - _nm_platform_kernel_support_info[type].desc, - value >= 0 ? "" : "not "); - } + if (set_default) { + nm_log_dbg(LOGD_PLATFORM, + "platform: kernel-support for %s (%s) not detected: assume %ssupported", + _nm_platform_kernel_support_info[type].name, + _nm_platform_kernel_support_info[type].desc, + value >= 0 ? "" : "not "); + } else { + nm_log_dbg(LOGD_PLATFORM, + "platform: kernel-support for %s (%s) detected: %ssupported", + _nm_platform_kernel_support_info[type].name, + _nm_platform_kernel_support_info[type].desc, + value >= 0 ? "" : "not "); + } #undef NM_THREAD_SAFE_ON_MAIN_THREAD #define NM_THREAD_SAFE_ON_MAIN_THREAD 1 - return value; + return value; } /*****************************************************************************/ @@ -432,51 +454,51 @@ _nm_platform_kernel_support_init (NMPlatformKernelSupportType type, * new netlink messages. Possibly it will raise change signals. */ void -nm_platform_process_events (NMPlatform *self) +nm_platform_process_events(NMPlatform *self) { - _CHECK_SELF_VOID (self, klass); + _CHECK_SELF_VOID(self, klass); - if (klass->process_events) - klass->process_events (self); + if (klass->process_events) + klass->process_events(self); } const NMPlatformLink * -nm_platform_process_events_ensure_link (NMPlatform *self, - int ifindex, - const char *ifname) -{ - const NMPObject *obj; - gboolean refreshed = FALSE; - - g_return_val_if_fail (NM_IS_PLATFORM (self), NULL); - - if (ifindex <= 0 && !ifname) - return NULL; - - /* we look into the cache, whether a link for given ifindex/ifname - * exits. If not, we poll the netlink socket, maybe the event - * with the link is waiting. - * - * Then we try again to find the object. - * - * If the link is already cached the first time, we avoid polling - * the netlink socket. */ +nm_platform_process_events_ensure_link(NMPlatform *self, int ifindex, const char *ifname) +{ + const NMPObject *obj; + gboolean refreshed = FALSE; + + g_return_val_if_fail(NM_IS_PLATFORM(self), NULL); + + if (ifindex <= 0 && !ifname) + return NULL; + + /* we look into the cache, whether a link for given ifindex/ifname + * exits. If not, we poll the netlink socket, maybe the event + * with the link is waiting. + * + * Then we try again to find the object. + * + * If the link is already cached the first time, we avoid polling + * the netlink socket. */ again: - obj = nmp_cache_lookup_link_full (nm_platform_get_cache (self), - ifindex, - ifname, - FALSE, /* also invisible. We don't care here whether udev is ready */ - NM_LINK_TYPE_NONE, - NULL, NULL); - if (obj) - return NMP_OBJECT_CAST_LINK (obj); - if (!refreshed) { - refreshed = TRUE; - nm_platform_process_events (self); - goto again; - } - - return NULL; + obj = nmp_cache_lookup_link_full( + nm_platform_get_cache(self), + ifindex, + ifname, + FALSE, /* also invisible. We don't care here whether udev is ready */ + NM_LINK_TYPE_NONE, + NULL, + NULL); + if (obj) + return NMP_OBJECT_CAST_LINK(obj); + if (!refreshed) { + refreshed = TRUE; + nm_platform_process_events(self); + goto again; + } + + return NULL; } /*****************************************************************************/ @@ -494,19 +516,19 @@ again: * directory. */ int -nm_platform_sysctl_open_netdir (NMPlatform *self, int ifindex, char *out_ifname) +nm_platform_sysctl_open_netdir(NMPlatform *self, int ifindex, char *out_ifname) { - const char*ifname_guess; - _CHECK_SELF_NETNS (self, klass, netns, -1); + const char *ifname_guess; + _CHECK_SELF_NETNS(self, klass, netns, -1); - g_return_val_if_fail (ifindex > 0, -1); + g_return_val_if_fail(ifindex > 0, -1); - /* we don't have an @ifname_guess argument to make the API nicer. - * But still do a cache-lookup first. Chances are good that we have - * the right ifname cached and save if_indextoname() */ - ifname_guess = nm_platform_link_get_name (self, ifindex); + /* we don't have an @ifname_guess argument to make the API nicer. + * But still do a cache-lookup first. Chances are good that we have + * the right ifname cached and save if_indextoname() */ + ifname_guess = nm_platform_link_get_name(self, ifindex); - return nmp_utils_sysctl_open_netdir (ifindex, ifname_guess, out_ifname); + return nmp_utils_sysctl_open_netdir(ifindex, ifname_guess, out_ifname); } /** @@ -525,14 +547,18 @@ nm_platform_sysctl_open_netdir (NMPlatform *self, int ifindex, char *out_ifname) * Returns: %TRUE on success. */ gboolean -nm_platform_sysctl_set (NMPlatform *self, const char *pathid, int dirfd, const char *path, const char *value) +nm_platform_sysctl_set(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + const char *value) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (path, FALSE); - g_return_val_if_fail (value, FALSE); + g_return_val_if_fail(path, FALSE); + g_return_val_if_fail(value, FALSE); - return klass->sysctl_set (self, pathid, dirfd, path, value); + return klass->sysctl_set(self, pathid, dirfd, path, value); } /** @@ -554,104 +580,107 @@ nm_platform_sysctl_set (NMPlatform *self, const char *pathid, int dirfd, const c * that the function can be used safely on all /proc and /sys files, * independently of how /proc/sys/kernel/sysctl_writes_strict is configured. */ -void nm_platform_sysctl_set_async (NMPlatform *self, - const char *pathid, - int dirfd, - const char *path, - const char *const *values, - NMPlatformAsyncCallback callback, - gpointer data, - GCancellable *cancellable) +void +nm_platform_sysctl_set_async(NMPlatform * self, + const char * pathid, + int dirfd, + const char * path, + const char *const * values, + NMPlatformAsyncCallback callback, + gpointer data, + GCancellable * cancellable) { - _CHECK_SELF_VOID (self, klass); + _CHECK_SELF_VOID(self, klass); - klass->sysctl_set_async (self, pathid, dirfd, path, values, callback, data, cancellable); + klass->sysctl_set_async(self, pathid, dirfd, path, values, callback, data, cancellable); } - gboolean -nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (NMPlatform *self, - const char *iface, - int value) +nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe(NMPlatform *self, const char *iface, int value) { - const char *path; - gint64 cur; - char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + const char *path; + gint64 cur; + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - /* the hop-limit provided via RA is uint8. */ - if (value > 0xFF) - return FALSE; + /* the hop-limit provided via RA is uint8. */ + if (value > 0xFF) + return FALSE; - /* don't allow unreasonable small values */ - if (value < 10) - return FALSE; + /* don't allow unreasonable small values */ + if (value < 10) + return FALSE; - path = nm_utils_sysctl_ip_conf_path (AF_INET6, buf, iface, "hop_limit"); - cur = nm_platform_sysctl_get_int_checked (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), 10, 1, G_MAXINT32, -1); + path = nm_utils_sysctl_ip_conf_path(AF_INET6, buf, iface, "hop_limit"); + cur = nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_ABSOLUTE(path), + 10, + 1, + G_MAXINT32, + -1); - /* only allow increasing the hop-limit to avoid DOS by an attacker - * setting a low hop-limit (CVE-2015-2924, rh#1209902) */ + /* only allow increasing the hop-limit to avoid DOS by an attacker + * setting a low hop-limit (CVE-2015-2924, rh#1209902) */ - if (value < cur) - return FALSE; - if (value != cur) { - char svalue[20]; + if (value < cur) + return FALSE; + if (value != cur) { + char svalue[20]; - sprintf (svalue, "%d", value); - nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), svalue); - } + sprintf(svalue, "%d", value); + nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), svalue); + } - return TRUE; + return TRUE; } gboolean -nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time (NMPlatform *self, - const char *iface, - guint value_ms) +nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time(NMPlatform *self, + const char *iface, + guint value_ms) { - char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; - char str[128]; - guint clamped; + char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + char str[128]; + guint clamped; - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - if (!value_ms) - return TRUE; + if (!value_ms) + return TRUE; - /* RFC 4861 says the value can't be greater than one hour. - * Also use a reasonable lower threshold. */ - clamped = NM_CLAMP (value_ms, 100, 3600000); - nm_sprintf_buf (path, "/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", iface); - nm_sprintf_buf (str, "%u", clamped); - if (!nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), str)) - return FALSE; + /* RFC 4861 says the value can't be greater than one hour. + * Also use a reasonable lower threshold. */ + clamped = NM_CLAMP(value_ms, 100, 3600000); + nm_sprintf_buf(path, "/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", iface); + nm_sprintf_buf(str, "%u", clamped); + if (!nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), str)) + return FALSE; - /* Set stale time in the same way as kernel */ - nm_sprintf_buf (path, "/proc/sys/net/ipv6/neigh/%s/gc_stale_time", iface); - nm_sprintf_buf (str, "%u", clamped * 3 / 1000); + /* Set stale time in the same way as kernel */ + nm_sprintf_buf(path, "/proc/sys/net/ipv6/neigh/%s/gc_stale_time", iface); + nm_sprintf_buf(str, "%u", clamped * 3 / 1000); - return nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), str); + return nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), str); } gboolean -nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time (NMPlatform *self, - const char *iface, - guint value_ms) +nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time(NMPlatform *self, + const char *iface, + guint value_ms) { - char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; - char str[128]; + char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + char str[128]; - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - if (!value_ms) - return TRUE; + if (!value_ms) + return TRUE; - nm_sprintf_buf (path, "/proc/sys/net/ipv6/neigh/%s/retrans_time_ms", iface); - nm_sprintf_buf (str, "%u", NM_CLAMP (value_ms, 10, 3600000)); + nm_sprintf_buf(path, "/proc/sys/net/ipv6/neigh/%s/retrans_time_ms", iface); + nm_sprintf_buf(str, "%u", NM_CLAMP(value_ms, 10, 3600000)); - return nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), str); + return nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), str); } /** @@ -667,13 +696,13 @@ nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time (NMPlatform *self, * If the path does not exist, %NULL is returned and %errno set to %ENOENT. */ char * -nm_platform_sysctl_get (NMPlatform *self, const char *pathid, int dirfd, const char *path) +nm_platform_sysctl_get(NMPlatform *self, const char *pathid, int dirfd, const char *path) { - _CHECK_SELF (self, klass, NULL); + _CHECK_SELF(self, klass, NULL); - g_return_val_if_fail (path, NULL); + g_return_val_if_fail(path, NULL); - return klass->sysctl_get (self, pathid, dirfd, path); + return klass->sysctl_get(self, pathid, dirfd, path); } /** @@ -691,9 +720,20 @@ nm_platform_sysctl_get (NMPlatform *self, const char *pathid, int dirfd, const c * value, on success %errno will be set to zero. */ gint32 -nm_platform_sysctl_get_int32 (NMPlatform *self, const char *pathid, int dirfd, const char *path, gint32 fallback) -{ - return nm_platform_sysctl_get_int_checked (self, pathid, dirfd, path, 10, G_MININT32, G_MAXINT32, fallback); +nm_platform_sysctl_get_int32(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + gint32 fallback) +{ + return nm_platform_sysctl_get_int_checked(self, + pathid, + dirfd, + path, + 10, + G_MININT32, + G_MAXINT32, + fallback); } /** @@ -718,186 +758,184 @@ nm_platform_sysctl_get_int32 (NMPlatform *self, const char *pathid, int dirfd, c * is set to ENOENT. */ gint64 -nm_platform_sysctl_get_int_checked (NMPlatform *self, - const char *pathid, - int dirfd, - const char *path, - guint base, - gint64 min, - gint64 max, - gint64 fallback) -{ - char *value = NULL; - gint32 ret; - int errsv; - - _CHECK_SELF (self, klass, fallback); - - g_return_val_if_fail (path, fallback); - - if (!path) { - errno = EINVAL; - return fallback; - } - - value = nm_platform_sysctl_get (self, pathid, dirfd, path); - if (!value) { - /* nm_platform_sysctl_get() set errno to ENOENT if the file does not exist. - * Propagate/preserve that. */ - if (errno != ENOENT) - errno = EINVAL; - return fallback; - } - - ret = _nm_utils_ascii_str_to_int64 (value, base, min, max, fallback); - errsv = errno; - g_free (value); - errno = errsv; - return ret; +nm_platform_sysctl_get_int_checked(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + guint base, + gint64 min, + gint64 max, + gint64 fallback) +{ + char * value = NULL; + gint32 ret; + int errsv; + + _CHECK_SELF(self, klass, fallback); + + g_return_val_if_fail(path, fallback); + + if (!path) { + errno = EINVAL; + return fallback; + } + + value = nm_platform_sysctl_get(self, pathid, dirfd, path); + if (!value) { + /* nm_platform_sysctl_get() set errno to ENOENT if the file does not exist. + * Propagate/preserve that. */ + if (errno != ENOENT) + errno = EINVAL; + return fallback; + } + + ret = _nm_utils_ascii_str_to_int64(value, base, min, max, fallback); + errsv = errno; + g_free(value); + errno = errsv; + return ret; } /*****************************************************************************/ char * -nm_platform_sysctl_ip_conf_get (NMPlatform *self, - int addr_family, - const char *ifname, - const char *property) +nm_platform_sysctl_ip_conf_get(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property) { - char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; - return nm_platform_sysctl_get (self, - NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family, - buf, - ifname, - property))); + return nm_platform_sysctl_get( + self, + NMP_SYSCTL_PATHID_ABSOLUTE( + nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property))); } gint64 -nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *self, - int addr_family, - const char *ifname, - const char *property, - guint base, - gint64 min, - gint64 max, - gint64 fallback) -{ - char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; - - return nm_platform_sysctl_get_int_checked (self, - NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family, - buf, - ifname, - property)), - base, - min, - max, - fallback); +nm_platform_sysctl_ip_conf_get_int_checked(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property, + guint base, + gint64 min, + gint64 max, + gint64 fallback) +{ + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + + return nm_platform_sysctl_get_int_checked( + self, + NMP_SYSCTL_PATHID_ABSOLUTE( + nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)), + base, + min, + max, + fallback); } gboolean -nm_platform_sysctl_ip_conf_set (NMPlatform *self, - int addr_family, - const char *ifname, - const char *property, - const char *value) +nm_platform_sysctl_ip_conf_set(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property, + const char *value) { - char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; - return nm_platform_sysctl_set (self, - NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family, - buf, - ifname, - property)), - value); + return nm_platform_sysctl_set( + self, + NMP_SYSCTL_PATHID_ABSOLUTE( + nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)), + value); } gboolean -nm_platform_sysctl_ip_conf_set_int64 (NMPlatform *self, - int addr_family, - const char *ifname, - const char *property, - gint64 value) +nm_platform_sysctl_ip_conf_set_int64(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property, + gint64 value) { - char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; - char s[64]; + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + char s[64]; - return nm_platform_sysctl_set (self, - NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family, - buf, - ifname, - property)), - nm_sprintf_buf (s, "%"G_GINT64_FORMAT, value)); + return nm_platform_sysctl_set( + self, + NMP_SYSCTL_PATHID_ABSOLUTE( + nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)), + nm_sprintf_buf(s, "%" G_GINT64_FORMAT, value)); } int -nm_platform_sysctl_ip_conf_get_rp_filter_ipv4 (NMPlatform *self, - const char *ifname, - gboolean consider_all, - gboolean *out_due_to_all) -{ - int val, val_all; - - NM_SET_OUT (out_due_to_all, FALSE); - - if (!ifname) - return -1; - - val = nm_platform_sysctl_ip_conf_get_int_checked (self, - AF_INET, - ifname, - "rp_filter", - 10, 0, 2, -1); - if (val == -1) - return -1; - - /* the effectively used value is the rp_filter sysctl value of MAX(all,ifname). - * Note that this is the numerical MAX(), despite rp_filter "1" being more strict - * than "2". */ - if ( val < 2 - && consider_all - && !nm_streq (ifname, "all")) { - val_all = nm_platform_sysctl_ip_conf_get_int_checked (self, - AF_INET, - "all", - "rp_filter", - 10, 0, 2, val); - if (val_all > val) { - val = val_all; - NM_SET_OUT (out_due_to_all, TRUE); - } - } - - return val; +nm_platform_sysctl_ip_conf_get_rp_filter_ipv4(NMPlatform *self, + const char *ifname, + gboolean consider_all, + gboolean * out_due_to_all) +{ + int val, val_all; + + NM_SET_OUT(out_due_to_all, FALSE); + + if (!ifname) + return -1; + + val = nm_platform_sysctl_ip_conf_get_int_checked(self, + AF_INET, + ifname, + "rp_filter", + 10, + 0, + 2, + -1); + if (val == -1) + return -1; + + /* the effectively used value is the rp_filter sysctl value of MAX(all,ifname). + * Note that this is the numerical MAX(), despite rp_filter "1" being more strict + * than "2". */ + if (val < 2 && consider_all && !nm_streq(ifname, "all")) { + val_all = nm_platform_sysctl_ip_conf_get_int_checked(self, + AF_INET, + "all", + "rp_filter", + 10, + 0, + 2, + val); + if (val_all > val) { + val = val_all; + NM_SET_OUT(out_due_to_all, TRUE); + } + } + + return val; } /*****************************************************************************/ static int -_link_get_all_presort (gconstpointer p_a, - gconstpointer p_b, - gpointer sort_by_name) +_link_get_all_presort(gconstpointer p_a, gconstpointer p_b, gpointer sort_by_name) { - const NMPlatformLink *a = NMP_OBJECT_CAST_LINK (*((const NMPObject **) p_a)); - const NMPlatformLink *b = NMP_OBJECT_CAST_LINK (*((const NMPObject **) p_b)); + const NMPlatformLink *a = NMP_OBJECT_CAST_LINK(*((const NMPObject **) p_a)); + const NMPlatformLink *b = NMP_OBJECT_CAST_LINK(*((const NMPObject **) p_b)); - /* Loopback always first */ - if (a->ifindex == 1) - return -1; - if (b->ifindex == 1) - return 1; + /* Loopback always first */ + if (a->ifindex == 1) + return -1; + if (b->ifindex == 1) + return 1; - if (GPOINTER_TO_INT (sort_by_name)) { - /* Initialized links first */ - if (a->initialized > b->initialized) - return -1; - if (a->initialized < b->initialized) - return 1; + if (GPOINTER_TO_INT(sort_by_name)) { + /* Initialized links first */ + if (a->initialized > b->initialized) + return -1; + if (a->initialized < b->initialized) + return 1; - return strcmp (a->name, b->name); - } else - return a->ifindex - b->ifindex; + return strcmp(a->name, b->name); + } else + return a->ifindex - b->ifindex; } /** @@ -909,136 +947,131 @@ _link_get_all_presort (gconstpointer p_a, * owned by the caller and should be freed with g_ptr_array_unref(). */ GPtrArray * -nm_platform_link_get_all (NMPlatform *self, gboolean sort_by_name) -{ - gs_unref_ptrarray GPtrArray *links = NULL; - GPtrArray *result; - guint i, nresult; - gs_unref_hashtable GHashTable *unseen = NULL; - const NMPlatformLink *item; - NMPLookup lookup; - - _CHECK_SELF (self, klass, NULL); - - nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_LINK); - links = nm_dedup_multi_objs_to_ptr_array_head (nm_platform_lookup (self, &lookup), - NULL, NULL); - if (!links) - return NULL; - - for (i = 0; i < links->len; ) { - if (!nmp_object_is_visible (links->pdata[i])) - g_ptr_array_remove_index_fast (links, i); - else - i++; - } - - if (links->len == 0) - return NULL; - - /* first sort the links by their ifindex or name. Below we will sort - * further by moving children/slaves to the end. */ - g_ptr_array_sort_with_data (links, _link_get_all_presort, GINT_TO_POINTER (sort_by_name)); - - unseen = g_hash_table_new (nm_direct_hash, NULL); - for (i = 0; i < links->len; i++) { - item = NMP_OBJECT_CAST_LINK (links->pdata[i]); - nm_assert (item->ifindex > 0); - if (!g_hash_table_insert (unseen, GINT_TO_POINTER (item->ifindex), NULL)) - nm_assert_not_reached (); - } +nm_platform_link_get_all(NMPlatform *self, gboolean sort_by_name) +{ + gs_unref_ptrarray GPtrArray *links = NULL; + GPtrArray * result; + guint i, nresult; + gs_unref_hashtable GHashTable *unseen = NULL; + const NMPlatformLink * item; + NMPLookup lookup; + + _CHECK_SELF(self, klass, NULL); + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK); + links = nm_dedup_multi_objs_to_ptr_array_head(nm_platform_lookup(self, &lookup), NULL, NULL); + if (!links) + return NULL; + + for (i = 0; i < links->len;) { + if (!nmp_object_is_visible(links->pdata[i])) + g_ptr_array_remove_index_fast(links, i); + else + i++; + } + + if (links->len == 0) + return NULL; + + /* first sort the links by their ifindex or name. Below we will sort + * further by moving children/slaves to the end. */ + g_ptr_array_sort_with_data(links, _link_get_all_presort, GINT_TO_POINTER(sort_by_name)); + + unseen = g_hash_table_new(nm_direct_hash, NULL); + for (i = 0; i < links->len; i++) { + item = NMP_OBJECT_CAST_LINK(links->pdata[i]); + nm_assert(item->ifindex > 0); + if (!g_hash_table_insert(unseen, GINT_TO_POINTER(item->ifindex), NULL)) + nm_assert_not_reached(); + } #if NM_MORE_ASSERTS - /* Ensure that link_get_all returns a consistent and valid result. */ - for (i = 0; i < links->len; i++) { - item = NMP_OBJECT_CAST_LINK (links->pdata[i]); - - if (!item->ifindex) - continue; - if (item->master != 0) { - g_warn_if_fail (item->master > 0); - g_warn_if_fail (item->master != item->ifindex); - g_warn_if_fail (g_hash_table_contains (unseen, GINT_TO_POINTER (item->master))); - } - if (item->parent != 0) { - if (item->parent != NM_PLATFORM_LINK_OTHER_NETNS) { - g_warn_if_fail (item->parent > 0); - g_warn_if_fail (item->parent != item->ifindex); - g_warn_if_fail (g_hash_table_contains (unseen, GINT_TO_POINTER (item->parent))); - } - } - } + /* Ensure that link_get_all returns a consistent and valid result. */ + for (i = 0; i < links->len; i++) { + item = NMP_OBJECT_CAST_LINK(links->pdata[i]); + + if (!item->ifindex) + continue; + if (item->master != 0) { + g_warn_if_fail(item->master > 0); + g_warn_if_fail(item->master != item->ifindex); + g_warn_if_fail(g_hash_table_contains(unseen, GINT_TO_POINTER(item->master))); + } + if (item->parent != 0) { + if (item->parent != NM_PLATFORM_LINK_OTHER_NETNS) { + g_warn_if_fail(item->parent > 0); + g_warn_if_fail(item->parent != item->ifindex); + g_warn_if_fail(g_hash_table_contains(unseen, GINT_TO_POINTER(item->parent))); + } + } + } #endif - /* Re-order the links list such that children/slaves come after all ancestors */ - nm_assert (g_hash_table_size (unseen) == links->len); - nresult = links->len; - result = g_ptr_array_new_full (nresult, (GDestroyNotify) nmp_object_unref); + /* Re-order the links list such that children/slaves come after all ancestors */ + nm_assert(g_hash_table_size(unseen) == links->len); + nresult = links->len; + result = g_ptr_array_new_full(nresult, (GDestroyNotify) nmp_object_unref); - while (TRUE) { - gboolean found_something = FALSE; - guint first_idx = G_MAXUINT; + while (TRUE) { + gboolean found_something = FALSE; + guint first_idx = G_MAXUINT; - for (i = 0; i < links->len; i++) { - item = NMP_OBJECT_CAST_LINK (links->pdata[i]); + for (i = 0; i < links->len; i++) { + item = NMP_OBJECT_CAST_LINK(links->pdata[i]); - if (!item) - continue; + if (!item) + continue; - g_assert (g_hash_table_contains (unseen, GINT_TO_POINTER (item->ifindex))); + g_assert(g_hash_table_contains(unseen, GINT_TO_POINTER(item->ifindex))); - if (item->master > 0 && g_hash_table_contains (unseen, GINT_TO_POINTER (item->master))) - goto skip; - if (item->parent > 0 && g_hash_table_contains (unseen, GINT_TO_POINTER (item->parent))) - goto skip; + if (item->master > 0 && g_hash_table_contains(unseen, GINT_TO_POINTER(item->master))) + goto skip; + if (item->parent > 0 && g_hash_table_contains(unseen, GINT_TO_POINTER(item->parent))) + goto skip; - g_hash_table_remove (unseen, GINT_TO_POINTER (item->ifindex)); - g_ptr_array_add (result, links->pdata[i]); - links->pdata[i] = NULL; - found_something = TRUE; - continue; + g_hash_table_remove(unseen, GINT_TO_POINTER(item->ifindex)); + g_ptr_array_add(result, links->pdata[i]); + links->pdata[i] = NULL; + found_something = TRUE; + continue; skip: - if (first_idx == G_MAXUINT) - first_idx = i; - } - - if (found_something) { - if (first_idx == G_MAXUINT) - break; - } else { - nm_assert (first_idx != G_MAXUINT); - /* There is a loop, pop the first (remaining) element from the list. - * This can happen for veth pairs where each peer is parent of the other end. */ - item = NMP_OBJECT_CAST_LINK (links->pdata[first_idx]); - nm_assert (item); - g_hash_table_remove (unseen, GINT_TO_POINTER (item->ifindex)); - g_ptr_array_add (result, links->pdata[first_idx]); - links->pdata[first_idx] = NULL; - } - nm_assert (result->len < nresult); - } - nm_assert (result->len == nresult); - - return result; + if (first_idx == G_MAXUINT) + first_idx = i; + } + + if (found_something) { + if (first_idx == G_MAXUINT) + break; + } else { + nm_assert(first_idx != G_MAXUINT); + /* There is a loop, pop the first (remaining) element from the list. + * This can happen for veth pairs where each peer is parent of the other end. */ + item = NMP_OBJECT_CAST_LINK(links->pdata[first_idx]); + nm_assert(item); + g_hash_table_remove(unseen, GINT_TO_POINTER(item->ifindex)); + g_ptr_array_add(result, links->pdata[first_idx]); + links->pdata[first_idx] = NULL; + } + nm_assert(result->len < nresult); + } + nm_assert(result->len == nresult); + + return result; } /*****************************************************************************/ const NMPObject * -nm_platform_link_get_obj (NMPlatform *self, - int ifindex, - gboolean visible_only) +nm_platform_link_get_obj(NMPlatform *self, int ifindex, gboolean visible_only) { - const NMPObject *obj_cache; + const NMPObject *obj_cache; - _CHECK_SELF (self, klass, NULL); + _CHECK_SELF(self, klass, NULL); - obj_cache = nmp_cache_lookup_link (nm_platform_get_cache (self), ifindex); - if ( !obj_cache - || ( visible_only - && !nmp_object_is_visible (obj_cache))) - return NULL; - return obj_cache; + obj_cache = nmp_cache_lookup_link(nm_platform_get_cache(self), ifindex); + if (!obj_cache || (visible_only && !nmp_object_is_visible(obj_cache))) + return NULL; + return obj_cache; } /*****************************************************************************/ @@ -1056,9 +1089,9 @@ nm_platform_link_get_obj (NMPlatform *self, * invalidate/modify the returned instance. **/ const NMPlatformLink * -nm_platform_link_get (NMPlatform *self, int ifindex) +nm_platform_link_get(NMPlatform *self, int ifindex) { - return NMP_OBJECT_CAST_LINK (nm_platform_link_get_obj (self, ifindex, TRUE)); + return NMP_OBJECT_CAST_LINK(nm_platform_link_get_obj(self, ifindex, TRUE)); } /** @@ -1069,30 +1102,35 @@ nm_platform_link_get (NMPlatform *self, int ifindex) * Returns: the first #NMPlatformLink instance with the given name. **/ const NMPlatformLink * -nm_platform_link_get_by_ifname (NMPlatform *self, const char *ifname) +nm_platform_link_get_by_ifname(NMPlatform *self, const char *ifname) { - const NMPObject *obj; + const NMPObject *obj; - _CHECK_SELF (self, klass, NULL); + _CHECK_SELF(self, klass, NULL); - if (!ifname || !*ifname) - return NULL; + if (!ifname || !*ifname) + return NULL; - obj = nmp_cache_lookup_link_full (nm_platform_get_cache (self), - 0, ifname, TRUE, NM_LINK_TYPE_NONE, NULL, NULL); - return NMP_OBJECT_CAST_LINK (obj); + obj = nmp_cache_lookup_link_full(nm_platform_get_cache(self), + 0, + ifname, + TRUE, + NM_LINK_TYPE_NONE, + NULL, + NULL); + return NMP_OBJECT_CAST_LINK(obj); } struct _nm_platform_link_get_by_address_data { - gconstpointer data; - guint8 len; + gconstpointer data; + guint8 len; }; static gboolean -_nm_platform_link_get_by_address_match_link (const NMPObject *obj, struct _nm_platform_link_get_by_address_data *d) +_nm_platform_link_get_by_address_match_link(const NMPObject * obj, + struct _nm_platform_link_get_by_address_data *d) { - return obj->link.l_address.len == d->len - && !memcmp (obj->link.l_address.data, d->data, d->len); + return obj->link.l_address.len == d->len && !memcmp(obj->link.l_address.data, d->data, d->len); } /** @@ -1105,56 +1143,63 @@ _nm_platform_link_get_by_address_match_link (const NMPObject *obj, struct _nm_pl * address. **/ const NMPlatformLink * -nm_platform_link_get_by_address (NMPlatform *self, - NMLinkType link_type, - gconstpointer address, - size_t length) +nm_platform_link_get_by_address(NMPlatform * self, + NMLinkType link_type, + gconstpointer address, + size_t length) { - const NMPObject *obj; - struct _nm_platform_link_get_by_address_data d = { - .data = address, - .len = length, - }; + const NMPObject * obj; + struct _nm_platform_link_get_by_address_data d = { + .data = address, + .len = length, + }; - _CHECK_SELF (self, klass, NULL); + _CHECK_SELF(self, klass, NULL); - if (length == 0) - return NULL; + if (length == 0) + return NULL; - if (length > NM_UTILS_HWADDR_LEN_MAX) - g_return_val_if_reached (NULL); - if (!address) - g_return_val_if_reached (NULL); + if (length > NM_UTILS_HWADDR_LEN_MAX) + g_return_val_if_reached(NULL); + if (!address) + g_return_val_if_reached(NULL); - obj = nmp_cache_lookup_link_full (nm_platform_get_cache (self), - 0, NULL, TRUE, link_type, - (NMPObjectMatchFn) _nm_platform_link_get_by_address_match_link, &d); - return NMP_OBJECT_CAST_LINK (obj); + obj = nmp_cache_lookup_link_full(nm_platform_get_cache(self), + 0, + NULL, + TRUE, + link_type, + (NMPObjectMatchFn) _nm_platform_link_get_by_address_match_link, + &d); + return NMP_OBJECT_CAST_LINK(obj); } static int -_link_add_check_existing (NMPlatform *self, const char *name, NMLinkType type, const NMPlatformLink **out_link) -{ - const NMPlatformLink *pllink; - - pllink = nm_platform_link_get_by_ifname (self, name); - if (pllink) { - gboolean wrong_type; - - wrong_type = type != NM_LINK_TYPE_NONE && pllink->type != type; - _LOG2D ("link: skip adding link due to existing interface of type %s%s%s", - nm_link_type_to_string (pllink->type), - wrong_type ? ", expected " : "", - wrong_type ? nm_link_type_to_string (type) : ""); - if (out_link) - *out_link = pllink; - if (wrong_type) - return -NME_PL_WRONG_TYPE; - return -NME_PL_EXISTS; - } - if (out_link) - *out_link = NULL; - return 0; +_link_add_check_existing(NMPlatform * self, + const char * name, + NMLinkType type, + const NMPlatformLink **out_link) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get_by_ifname(self, name); + if (pllink) { + gboolean wrong_type; + + wrong_type = type != NM_LINK_TYPE_NONE && pllink->type != type; + _LOG2D("link: skip adding link due to existing interface of type %s%s%s", + nm_link_type_to_string(pllink->type), + wrong_type ? ", expected " : "", + wrong_type ? nm_link_type_to_string(type) : ""); + if (out_link) + *out_link = pllink; + if (wrong_type) + return -NME_PL_WRONG_TYPE; + return -NME_PL_EXISTS; + } + if (out_link) + *out_link = NULL; + return 0; } /** @@ -1179,103 +1224,128 @@ _link_add_check_existing (NMPlatform *self, const char *name, NMLinkType type, c * Returns: the negative nm-error on failure. */ int -nm_platform_link_add (NMPlatform *self, - NMLinkType type, - const char *name, - int parent, - const void *address, - size_t address_len, - gconstpointer extra_data, - const NMPlatformLink **out_link) -{ - int r; - char addr_buf[NM_UTILS_HWADDR_LEN_MAX * 3]; - char parent_buf[64]; - char buf[512]; - - _CHECK_SELF (self, klass, -NME_BUG); - - g_return_val_if_fail (name, -NME_BUG); - g_return_val_if_fail ((address != NULL) ^ (address_len == 0) , -NME_BUG); - g_return_val_if_fail (address_len <= NM_UTILS_HWADDR_LEN_MAX, -NME_BUG); - g_return_val_if_fail (parent >= 0, -NME_BUG); - - r = _link_add_check_existing (self, name, type, out_link); - if (r < 0) - return r; - - _LOG2D ("link: adding link: " - "%s " /* type */ - "\"%s\"" /* name */ - "%s%s" /* parent */ - "%s%s" /* address */ - "%s" /* extra_data */ - "", - nm_link_type_to_string (type), - name, - parent > 0 ? ", parent " : "", - parent > 0 ? nm_sprintf_buf (parent_buf, "%d", parent) : "", - address ? ", address: " : "", - address ? nm_utils_hwaddr_ntoa_buf (address, address_len, FALSE, addr_buf, sizeof (addr_buf)) : "", - ({ - char *buf_p = buf; - gsize buf_len = sizeof (buf); - - buf[0] = '\0'; - - switch (type) { - case NM_LINK_TYPE_VLAN: - nm_utils_strbuf_append_str (&buf_p, &buf_len, ", "); - nm_platform_lnk_vlan_to_string ((const NMPlatformLnkVlan *) extra_data, buf_p, buf_len); - break; - case NM_LINK_TYPE_VRF: - nm_utils_strbuf_append_str (&buf_p, &buf_len, ", "); - nm_platform_lnk_vrf_to_string ((const NMPlatformLnkVrf *) extra_data, buf_p, buf_len); - break; - case NM_LINK_TYPE_VXLAN: - nm_utils_strbuf_append_str (&buf_p, &buf_len, ", "); - nm_platform_lnk_vxlan_to_string ((const NMPlatformLnkVxlan *) extra_data, buf_p, buf_len); - break; - case NM_LINK_TYPE_VETH: - nm_sprintf_buf (buf, ", veth-peer \"%s\"", (const char *) extra_data); - break; - case NM_LINK_TYPE_GRE: - case NM_LINK_TYPE_GRETAP: - nm_utils_strbuf_append_str (&buf_p, &buf_len, ", "); - nm_platform_lnk_gre_to_string ((const NMPlatformLnkGre *) extra_data, buf_p, buf_len); - break; - case NM_LINK_TYPE_SIT: - nm_utils_strbuf_append_str (&buf_p, &buf_len, ", "); - nm_platform_lnk_sit_to_string ((const NMPlatformLnkSit *) extra_data, buf_p, buf_len); - break; - case NM_LINK_TYPE_IP6TNL: - case NM_LINK_TYPE_IP6GRE: - case NM_LINK_TYPE_IP6GRETAP: - nm_utils_strbuf_append_str (&buf_p, &buf_len, ", "); - nm_platform_lnk_ip6tnl_to_string ((const NMPlatformLnkIp6Tnl *) extra_data, buf_p, buf_len); - break; - case NM_LINK_TYPE_IPIP: - nm_utils_strbuf_append_str (&buf_p, &buf_len, ", "); - nm_platform_lnk_ipip_to_string ((const NMPlatformLnkIpIp *) extra_data, buf_p, buf_len); - break; - case NM_LINK_TYPE_MACSEC: - nm_utils_strbuf_append_str (&buf_p, &buf_len, ", "); - nm_platform_lnk_macsec_to_string ((const NMPlatformLnkMacsec *) extra_data, buf_p, buf_len); - break; - case NM_LINK_TYPE_MACVLAN: - case NM_LINK_TYPE_MACVTAP: - nm_utils_strbuf_append_str (&buf_p, &buf_len, ", "); - nm_platform_lnk_macvlan_to_string ((const NMPlatformLnkMacvlan *) extra_data, buf_p, buf_len); - break; - default: - nm_assert (!extra_data); - break; - } - - buf; - })); - - return klass->link_add (self, type, name, parent, address, address_len, extra_data, out_link); +nm_platform_link_add(NMPlatform * self, + NMLinkType type, + const char * name, + int parent, + const void * address, + size_t address_len, + gconstpointer extra_data, + const NMPlatformLink **out_link) +{ + int r; + char addr_buf[NM_UTILS_HWADDR_LEN_MAX * 3]; + char parent_buf[64]; + char buf[512]; + + _CHECK_SELF(self, klass, -NME_BUG); + + g_return_val_if_fail(name, -NME_BUG); + g_return_val_if_fail((address != NULL) ^ (address_len == 0), -NME_BUG); + g_return_val_if_fail(address_len <= NM_UTILS_HWADDR_LEN_MAX, -NME_BUG); + g_return_val_if_fail(parent >= 0, -NME_BUG); + + r = _link_add_check_existing(self, name, type, out_link); + if (r < 0) + return r; + + _LOG2D("link: adding link: " + "%s " /* type */ + "\"%s\"" /* name */ + "%s%s" /* parent */ + "%s%s" /* address */ + "%s" /* extra_data */ + "", + nm_link_type_to_string(type), + name, + parent > 0 ? ", parent " : "", + parent > 0 ? nm_sprintf_buf(parent_buf, "%d", parent) : "", + address ? ", address: " : "", + address ? _nm_utils_hwaddr_ntoa(address, address_len, FALSE, addr_buf, sizeof(addr_buf)) + : "", + ({ + char *buf_p = buf; + gsize buf_len = sizeof(buf); + + buf[0] = '\0'; + + switch (type) { + case NM_LINK_TYPE_BRIDGE: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_bridge_to_string((const NMPlatformLnkBridge *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_VLAN: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_vlan_to_string((const NMPlatformLnkVlan *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_VRF: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_vrf_to_string((const NMPlatformLnkVrf *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_VXLAN: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_vxlan_to_string((const NMPlatformLnkVxlan *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_VETH: + nm_sprintf_buf(buf, ", veth-peer \"%s\"", (const char *) extra_data); + break; + case NM_LINK_TYPE_GRE: + case NM_LINK_TYPE_GRETAP: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_gre_to_string((const NMPlatformLnkGre *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_SIT: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_sit_to_string((const NMPlatformLnkSit *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_IP6TNL: + case NM_LINK_TYPE_IP6GRE: + case NM_LINK_TYPE_IP6GRETAP: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_ip6tnl_to_string((const NMPlatformLnkIp6Tnl *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_IPIP: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_ipip_to_string((const NMPlatformLnkIpIp *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_MACSEC: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_macsec_to_string((const NMPlatformLnkMacsec *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_MACVLAN: + case NM_LINK_TYPE_MACVTAP: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_macvlan_to_string((const NMPlatformLnkMacvlan *) extra_data, + buf_p, + buf_len); + break; + default: + nm_assert(!extra_data); + break; + } + + buf; + })); + + return klass->link_add(self, type, name, parent, address, address_len, extra_data, out_link); } /** @@ -1284,14 +1354,14 @@ nm_platform_link_add (NMPlatform *self, * @ifindex: Interface index */ gboolean -nm_platform_link_delete (NMPlatform *self, int ifindex) +nm_platform_link_delete(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - _LOG3D ("link: deleting"); - return klass->link_delete (self, ifindex); + _LOG3D("link: deleting"); + return klass->link_delete(self, ifindex); } /** @@ -1303,15 +1373,15 @@ nm_platform_link_delete (NMPlatform *self, int ifindex) * Returns: %TRUE on success. */ gboolean -nm_platform_link_set_netns (NMPlatform *self, int ifindex, int netns_fd) +nm_platform_link_set_netns(NMPlatform *self, int ifindex, int netns_fd) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (netns_fd > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(netns_fd > 0, FALSE); - _LOG3D ("link: move link to network namespace with fd %d", netns_fd); - return klass->link_set_netns (self, ifindex, netns_fd); + _LOG3D("link: move link to network namespace with fd %d", netns_fd); + return klass->link_set_netns(self, ifindex, netns_fd); } /** @@ -1323,28 +1393,28 @@ nm_platform_link_set_netns (NMPlatform *self, int ifindex, int netns_fd) * or 0. Interface name is owned by #NMPlatform, don't free it. */ int -nm_platform_link_get_ifindex (NMPlatform *self, const char *name) +nm_platform_link_get_ifindex(NMPlatform *self, const char *name) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - pllink = nm_platform_link_get_by_ifname (self, name); - return pllink ? pllink->ifindex : 0; + pllink = nm_platform_link_get_by_ifname(self, name); + return pllink ? pllink->ifindex : 0; } const char * -nm_platform_if_indextoname (NMPlatform *self, int ifindex, char out_ifname[static 16 /* IFNAMSIZ */]) +nm_platform_if_indextoname(NMPlatform *self, int ifindex, char out_ifname[static 16 /* IFNAMSIZ */]) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - return nmp_utils_if_indextoname (ifindex, out_ifname); + return nmp_utils_if_indextoname(ifindex, out_ifname); } int -nm_platform_if_nametoindex (NMPlatform *self, const char *ifname) +nm_platform_if_nametoindex(NMPlatform *self, const char *ifname) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - return nmp_utils_if_nametoindex (ifname); + return nmp_utils_if_nametoindex(ifname); } /** @@ -1356,12 +1426,12 @@ nm_platform_if_nametoindex (NMPlatform *self, const char *ifname) * or %NULL. */ const char * -nm_platform_link_get_name (NMPlatform *self, int ifindex) +nm_platform_link_get_name(NMPlatform *self, int ifindex) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - pllink = nm_platform_link_get (self, ifindex); - return pllink ? pllink->name : NULL; + pllink = nm_platform_link_get(self, ifindex); + return pllink ? pllink->name : NULL; } /** @@ -1373,12 +1443,12 @@ nm_platform_link_get_name (NMPlatform *self, int ifindex) * NM_LINK_TYPE_NONE is returned. */ NMLinkType -nm_platform_link_get_type (NMPlatform *self, int ifindex) +nm_platform_link_get_type(NMPlatform *self, int ifindex) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - pllink = nm_platform_link_get (self, ifindex); - return pllink ? pllink->type : NM_LINK_TYPE_NONE; + pllink = nm_platform_link_get(self, ifindex); + return pllink ? pllink->type : NM_LINK_TYPE_NONE; } /** @@ -1391,46 +1461,43 @@ nm_platform_link_get_type (NMPlatform *self, int ifindex) * other cases it may not. On error, %NULL is returned. */ const char * -nm_platform_link_get_type_name (NMPlatform *self, int ifindex) +nm_platform_link_get_type_name(NMPlatform *self, int ifindex) { - const NMPObject *obj; + const NMPObject *obj; - obj = nm_platform_link_get_obj (self, ifindex, TRUE); - if (!obj) - return NULL; + obj = nm_platform_link_get_obj(self, ifindex, TRUE); + if (!obj) + return NULL; - if (obj->link.type != NM_LINK_TYPE_UNKNOWN) { - /* We could detect the @link_type. In this case the function returns - * our internal module names, which differs from rtnl_link_get_type(): - * - NM_LINK_TYPE_INFINIBAND (gives "infiniband", instead of "ipoib") - * - NM_LINK_TYPE_TAP (gives "tap", instead of "tun"). - * Note that this functions is only used by NMDeviceGeneric to - * set type_description. */ - return nm_link_type_to_string (obj->link.type); - } - /* Link type not detected. Fallback to rtnl_link_get_type()/IFLA_INFO_KIND. */ - return obj->link.kind ?: "unknown"; + if (obj->link.type != NM_LINK_TYPE_UNKNOWN) { + /* We could detect the @link_type. In this case the function returns + * our internal module names, which differs from rtnl_link_get_type(): + * - NM_LINK_TYPE_INFINIBAND (gives "infiniband", instead of "ipoib") + * - NM_LINK_TYPE_TAP (gives "tap", instead of "tun"). + * Note that this functions is only used by NMDeviceGeneric to + * set type_description. */ + return nm_link_type_to_string(obj->link.type); + } + /* Link type not detected. Fallback to rtnl_link_get_type()/IFLA_INFO_KIND. */ + return obj->link.kind ?: "unknown"; } static gboolean -link_get_udev_property (NMPlatform *self, - int ifindex, - const char *name, - const char **out_value) +link_get_udev_property(NMPlatform *self, int ifindex, const char *name, const char **out_value) { - struct udev_device *udevice = NULL; - const char *uproperty; + struct udev_device *udevice = NULL; + const char * uproperty; - udevice = nm_platform_link_get_udev_device (self, ifindex); - if (!udevice) - return FALSE; + udevice = nm_platform_link_get_udev_device(self, ifindex); + if (!udevice) + return FALSE; - uproperty = udev_device_get_property_value (udevice, name); - if (!uproperty) - return FALSE; + uproperty = udev_device_get_property_value(udevice, name); + if (!uproperty) + return FALSE; - NM_SET_OUT (out_value, uproperty); - return TRUE; + NM_SET_OUT(out_value, uproperty); + return TRUE; } /** @@ -1443,16 +1510,16 @@ link_get_udev_property (NMPlatform *self, * %FALSE otherwise (with @unmanaged unmodified). */ gboolean -nm_platform_link_get_unmanaged (NMPlatform *self, int ifindex, gboolean *unmanaged) +nm_platform_link_get_unmanaged(NMPlatform *self, int ifindex, gboolean *unmanaged) { - const char *value; + const char *value; - if (link_get_udev_property (self, ifindex, "NM_UNMANAGED", &value)) { - NM_SET_OUT (unmanaged, nm_udev_utils_property_as_boolean (value)); - return TRUE; - } + if (link_get_udev_property(self, ifindex, "NM_UNMANAGED", &value)) { + NM_SET_OUT(unmanaged, nm_udev_utils_property_as_boolean(value)); + return TRUE; + } - return FALSE; + return FALSE; } /** @@ -1464,9 +1531,9 @@ nm_platform_link_get_unmanaged (NMPlatform *self, int ifindex, gboolean *unmanag * a physical device. */ gboolean -nm_platform_link_is_software (NMPlatform *self, int ifindex) +nm_platform_link_is_software(NMPlatform *self, int ifindex) { - return nm_link_type_is_software (nm_platform_link_get_type (self, ifindex)); + return nm_link_type_is_software(nm_platform_link_get_type(self, ifindex)); } /** @@ -1478,9 +1545,9 @@ nm_platform_link_is_software (NMPlatform *self, int ifindex) * other interfaces. */ gboolean -nm_platform_link_supports_slaves (NMPlatform *self, int ifindex) +nm_platform_link_supports_slaves(NMPlatform *self, int ifindex) { - return nm_link_type_supports_slaves (nm_platform_link_get_type (self, ifindex)); + return nm_link_type_supports_slaves(nm_platform_link_get_type(self, ifindex)); } /** @@ -1491,36 +1558,34 @@ nm_platform_link_supports_slaves (NMPlatform *self, int ifindex) * Reload the cache for ifindex synchronously. */ gboolean -nm_platform_link_refresh (NMPlatform *self, int ifindex) +nm_platform_link_refresh(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - if (klass->link_refresh) - return klass->link_refresh (self, ifindex); + if (klass->link_refresh) + return klass->link_refresh(self, ifindex); - return TRUE; + return TRUE; } int -nm_platform_link_get_ifi_flags (NMPlatform *self, - int ifindex, - guint requested_flags) +nm_platform_link_get_ifi_flags(NMPlatform *self, int ifindex, guint requested_flags) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - /* include invisible links (only in netlink, not udev). */ - pllink = NMP_OBJECT_CAST_LINK (nm_platform_link_get_obj (self, ifindex, FALSE)); - if (!pllink) - return -ENODEV; + /* include invisible links (only in netlink, not udev). */ + pllink = NMP_OBJECT_CAST_LINK(nm_platform_link_get_obj(self, ifindex, FALSE)); + if (!pllink) + return -ENODEV; - /* Errors are signaled as negative values. That means, you cannot request - * the most significant bit (2^31) with this API. Assert against that. */ - nm_assert ((int) requested_flags >= 0); - nm_assert (requested_flags < (guint) G_MAXINT); + /* Errors are signaled as negative values. That means, you cannot request + * the most significant bit (2^31) with this API. Assert against that. */ + nm_assert((int) requested_flags >= 0); + nm_assert(requested_flags < (guint) G_MAXINT); - return (int) (pllink->n_ifi_flags & requested_flags); + return (int) (pllink->n_ifi_flags & requested_flags); } /** @@ -1531,9 +1596,9 @@ nm_platform_link_get_ifi_flags (NMPlatform *self, * Check if the interface is up. */ gboolean -nm_platform_link_is_up (NMPlatform *self, int ifindex) +nm_platform_link_is_up(NMPlatform *self, int ifindex) { - return nm_platform_link_get_ifi_flags (self, ifindex, IFF_UP) == IFF_UP; + return nm_platform_link_get_ifi_flags(self, ifindex, IFF_UP) == IFF_UP; } /** @@ -1544,12 +1609,12 @@ nm_platform_link_is_up (NMPlatform *self, int ifindex) * Check if the interface is connected. */ gboolean -nm_platform_link_is_connected (NMPlatform *self, int ifindex) +nm_platform_link_is_connected(NMPlatform *self, int ifindex) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - pllink = nm_platform_link_get (self, ifindex); - return pllink ? pllink->connected : FALSE; + pllink = nm_platform_link_get(self, ifindex); + return pllink ? pllink->connected : FALSE; } /** @@ -1560,17 +1625,17 @@ nm_platform_link_is_connected (NMPlatform *self, int ifindex) * Check if the interface is configured to use ARP. */ gboolean -nm_platform_link_uses_arp (NMPlatform *self, int ifindex) +nm_platform_link_uses_arp(NMPlatform *self, int ifindex) { - int f; + int f; - f = nm_platform_link_get_ifi_flags (self, ifindex, IFF_NOARP); + f = nm_platform_link_get_ifi_flags(self, ifindex, IFF_NOARP); - if (f < 0) - return FALSE; - if (f == IFF_NOARP) - return FALSE; - return TRUE; + if (f < 0) + return FALSE; + if (f == IFF_NOARP) + return FALSE; + return TRUE; } /** @@ -1584,43 +1649,43 @@ nm_platform_link_uses_arp (NMPlatform *self, int ifindex) * Returns: %TRUE a tokenized identifier was available */ gboolean -nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid) +nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); - if (klass->link_set_token) - return klass->link_set_token (self, ifindex, iid); - return FALSE; + if (klass->link_set_token) + return klass->link_set_token(self, ifindex, iid); + return FALSE; } const char * -nm_platform_link_get_udi (NMPlatform *self, int ifindex) +nm_platform_link_get_udi(NMPlatform *self, int ifindex) { - struct udev_device *device; + struct udev_device *device; - device = nm_platform_link_get_udev_device (self, ifindex); - return device ? udev_device_get_syspath (device) : NULL; + device = nm_platform_link_get_udev_device(self, ifindex); + return device ? udev_device_get_syspath(device) : NULL; } const char * -nm_platform_link_get_path (NMPlatform *self, int ifindex) +nm_platform_link_get_path(NMPlatform *self, int ifindex) { - const char *value = NULL; + const char *value = NULL; - link_get_udev_property (self, ifindex, "ID_PATH", &value); + link_get_udev_property(self, ifindex, "ID_PATH", &value); - return value; + return value; } struct udev_device * -nm_platform_link_get_udev_device (NMPlatform *self, int ifindex) +nm_platform_link_get_udev_device(NMPlatform *self, int ifindex) { - const NMPObject *obj_cache; + const NMPObject *obj_cache; - obj_cache = nm_platform_link_get_obj (self, ifindex, FALSE); - return obj_cache ? obj_cache->_link.udev.device : NULL; + obj_cache = nm_platform_link_get_obj(self, ifindex, FALSE); + return obj_cache ? obj_cache->_link.udev.device : NULL; } /** @@ -1635,14 +1700,14 @@ nm_platform_link_get_udev_device (NMPlatform *self, int ifindex) * Returns: %TRUE if NM handles the IPv6LL address for @ifindex */ gboolean -nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex) +nm_platform_link_get_user_ipv6ll_enabled(NMPlatform *self, int ifindex) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - pllink = nm_platform_link_get (self, ifindex); - if (pllink && pllink->inet6_addr_gen_mode_inv) - return _nm_platform_uint8_inv (pllink->inet6_addr_gen_mode_inv) == NM_IN6_ADDR_GEN_MODE_NONE; - return FALSE; + pllink = nm_platform_link_get(self, ifindex); + if (pllink && pllink->inet6_addr_gen_mode_inv) + return _nm_platform_uint8_inv(pllink->inet6_addr_gen_mode_inv) == NM_IN6_ADDR_GEN_MODE_NONE; + return FALSE; } /** @@ -1657,13 +1722,13 @@ nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex) * Returns: the negative nm-error on failure. */ int -nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled) +nm_platform_link_set_user_ipv6ll_enabled(NMPlatform *self, int ifindex, gboolean enabled) { - _CHECK_SELF (self, klass, -NME_BUG); + _CHECK_SELF(self, klass, -NME_BUG); - g_return_val_if_fail (ifindex > 0, -NME_BUG); + g_return_val_if_fail(ifindex > 0, -NME_BUG); - return klass->link_set_user_ipv6ll_enabled (self, ifindex, enabled); + return klass->link_set_user_ipv6ll_enabled(self, ifindex, enabled); } /** @@ -1675,19 +1740,18 @@ nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolea * Set interface MAC address. */ int -nm_platform_link_set_address (NMPlatform *self, int ifindex, gconstpointer address, size_t length) +nm_platform_link_set_address(NMPlatform *self, int ifindex, gconstpointer address, size_t length) { - gs_free char *mac = NULL; + gs_free char *mac = NULL; - _CHECK_SELF (self, klass, -NME_BUG); + _CHECK_SELF(self, klass, -NME_BUG); - g_return_val_if_fail (ifindex > 0, -NME_BUG); - g_return_val_if_fail (address, -NME_BUG); - g_return_val_if_fail (length > 0, -NME_BUG); + g_return_val_if_fail(ifindex > 0, -NME_BUG); + g_return_val_if_fail(address, -NME_BUG); + g_return_val_if_fail(length > 0, -NME_BUG); - _LOG3D ("link: setting hardware address to %s", - (mac = nm_utils_hwaddr_ntoa (address, length))); - return klass->link_set_address (self, ifindex, address, length); + _LOG3D("link: setting hardware address to %s", (mac = nm_utils_hwaddr_ntoa(address, length))); + return klass->link_set_address(self, ifindex, address, length); } /** @@ -1700,12 +1764,12 @@ nm_platform_link_set_address (NMPlatform *self, int ifindex, gconstpointer addre * length @length. */ gconstpointer -nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length) +nm_platform_link_get_address(NMPlatform *self, int ifindex, size_t *length) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - pllink = nm_platform_link_get (self, ifindex); - return nmp_link_address_get (pllink ? &pllink->l_address : NULL, length); + pllink = nm_platform_link_get(self, ifindex); + return nmp_link_address_get(pllink ? &pllink->l_address : NULL, length); } /** @@ -1720,50 +1784,50 @@ nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length) * address. */ gboolean -nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length) +nm_platform_link_get_permanent_address(NMPlatform *self, int ifindex, guint8 *buf, size_t *length) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - if (length) - *length = 0; + if (length) + *length = 0; - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (buf, FALSE); - g_return_val_if_fail (length, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(buf, FALSE); + g_return_val_if_fail(length, FALSE); - if (klass->link_get_permanent_address) - return klass->link_get_permanent_address (self, ifindex, buf, length); - return FALSE; + if (klass->link_get_permanent_address) + return klass->link_get_permanent_address(self, ifindex, buf, length); + return FALSE; } gboolean -nm_platform_link_supports_carrier_detect (NMPlatform *self, int ifindex) +nm_platform_link_supports_carrier_detect(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); - return klass->link_supports_carrier_detect (self, ifindex); + return klass->link_supports_carrier_detect(self, ifindex); } gboolean -nm_platform_link_supports_vlans (NMPlatform *self, int ifindex) +nm_platform_link_supports_vlans(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); - return klass->link_supports_vlans (self, ifindex); + return klass->link_supports_vlans(self, ifindex); } gboolean -nm_platform_link_supports_sriov (NMPlatform *self, int ifindex) +nm_platform_link_supports_sriov(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); - return klass->link_supports_sriov (self, ifindex); + return klass->link_supports_sriov(self, ifindex); } /** @@ -1782,66 +1846,69 @@ nm_platform_link_supports_sriov (NMPlatform *self, int ifindex) * always invoked, and asynchronously. */ void -nm_platform_link_set_sriov_params_async (NMPlatform *self, - int ifindex, - guint num_vfs, - NMTernary autoprobe, - NMPlatformAsyncCallback callback, - gpointer callback_data, - GCancellable *cancellable) +nm_platform_link_set_sriov_params_async(NMPlatform * self, + int ifindex, + guint num_vfs, + NMTernary autoprobe, + NMPlatformAsyncCallback callback, + gpointer callback_data, + GCancellable * cancellable) { - _CHECK_SELF_VOID (self, klass); + _CHECK_SELF_VOID(self, klass); - g_return_if_fail (ifindex > 0); + g_return_if_fail(ifindex > 0); - _LOG3D ("link: setting %u total VFs and autoprobe %d", num_vfs, (int) autoprobe); - klass->link_set_sriov_params_async (self, - ifindex, - num_vfs, - autoprobe, - callback, - callback_data, - cancellable); + _LOG3D("link: setting %u total VFs and autoprobe %d", num_vfs, (int) autoprobe); + klass->link_set_sriov_params_async(self, + ifindex, + num_vfs, + autoprobe, + callback, + callback_data, + cancellable); } gboolean -nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs) +nm_platform_link_set_sriov_vfs(NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs) { - guint i; - _CHECK_SELF (self, klass, FALSE); + guint i; + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - _LOG3D ("link: setting VFs"); - for (i = 0; vfs[i]; i++) { - const NMPlatformVF *vf = vfs[i]; + _LOG3D("link: setting VFs"); + for (i = 0; vfs[i]; i++) { + const NMPlatformVF *vf = vfs[i]; - _LOG3D ("link: VF %s", nm_platform_vf_to_string (vf, NULL, 0)); - } + _LOG3D("link: VF %s", nm_platform_vf_to_string(vf, NULL, 0)); + } - return klass->link_set_sriov_vfs (self, ifindex, vfs); + return klass->link_set_sriov_vfs(self, ifindex, vfs); } gboolean -nm_platform_link_set_bridge_vlans (NMPlatform *self, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans) +nm_platform_link_set_bridge_vlans(NMPlatform * self, + int ifindex, + gboolean on_master, + const NMPlatformBridgeVlan *const *vlans) { - guint i; - _CHECK_SELF (self, klass, FALSE); + guint i; + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - _LOG3D ("link: %s bridge VLANs on %s", - vlans ? "setting" : "clearing", - on_master ? "master" : "self"); - if (vlans) { - for (i = 0; vlans[i]; i++) { - const NMPlatformBridgeVlan *vlan = vlans[i]; + _LOG3D("link: %s bridge VLANs on %s", + vlans ? "setting" : "clearing", + on_master ? "master" : "self"); + if (vlans) { + for (i = 0; vlans[i]; i++) { + const NMPlatformBridgeVlan *vlan = vlans[i]; - _LOG3D ("link: bridge VLAN %s", nm_platform_bridge_vlan_to_string (vlan, NULL, 0)); - } - } + _LOG3D("link: bridge VLAN %s", nm_platform_bridge_vlan_to_string(vlan, NULL, 0)); + } + } - return klass->link_set_bridge_vlans (self, ifindex, on_master, vlans); + return klass->link_set_bridge_vlans(self, ifindex, on_master, vlans); } /** @@ -1853,14 +1920,14 @@ nm_platform_link_set_bridge_vlans (NMPlatform *self, int ifindex, gboolean on_ma * Bring the interface up. */ gboolean -nm_platform_link_set_up (NMPlatform *self, int ifindex, gboolean *out_no_firmware) +nm_platform_link_set_up(NMPlatform *self, int ifindex, gboolean *out_no_firmware) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - _LOG3D ("link: setting up"); - return klass->link_set_up (self, ifindex, out_no_firmware); + _LOG3D("link: setting up"); + return klass->link_set_up(self, ifindex, out_no_firmware); } /** @@ -1871,14 +1938,14 @@ nm_platform_link_set_up (NMPlatform *self, int ifindex, gboolean *out_no_firmwar * Take the interface down. */ gboolean -nm_platform_link_set_down (NMPlatform *self, int ifindex) +nm_platform_link_set_down(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - _LOG3D ("link: setting down"); - return klass->link_set_down (self, ifindex); + _LOG3D("link: setting down"); + return klass->link_set_down(self, ifindex); } /** @@ -1889,14 +1956,14 @@ nm_platform_link_set_down (NMPlatform *self, int ifindex) * Enable ARP on the interface. */ gboolean -nm_platform_link_set_arp (NMPlatform *self, int ifindex) +nm_platform_link_set_arp(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); - _LOG3D ("link: setting arp"); - return klass->link_set_arp (self, ifindex); + _LOG3D("link: setting arp"); + return klass->link_set_arp(self, ifindex); } /** @@ -1907,14 +1974,14 @@ nm_platform_link_set_arp (NMPlatform *self, int ifindex) * Disable ARP on the interface. */ gboolean -nm_platform_link_set_noarp (NMPlatform *self, int ifindex) +nm_platform_link_set_noarp(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); - _LOG3D ("link: setting noarp"); - return klass->link_set_noarp (self, ifindex); + _LOG3D("link: setting noarp"); + return klass->link_set_noarp(self, ifindex); } /** @@ -1926,15 +1993,15 @@ nm_platform_link_set_noarp (NMPlatform *self, int ifindex) * Set interface MTU. */ int -nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu) +nm_platform_link_set_mtu(NMPlatform *self, int ifindex, guint32 mtu) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); - g_return_val_if_fail (mtu > 0, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); + g_return_val_if_fail(mtu > 0, FALSE); - _LOG3D ("link: setting mtu %"G_GUINT32_FORMAT, mtu); - return klass->link_set_mtu (self, ifindex, mtu); + _LOG3D("link: setting mtu %" G_GUINT32_FORMAT, mtu); + return klass->link_set_mtu(self, ifindex, mtu); } /** @@ -1945,12 +2012,12 @@ nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu) * Returns: MTU value for the interface or 0 on error. */ guint32 -nm_platform_link_get_mtu (NMPlatform *self, int ifindex) +nm_platform_link_get_mtu(NMPlatform *self, int ifindex) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - pllink = nm_platform_link_get (self, ifindex); - return pllink ? pllink->mtu : 0; + pllink = nm_platform_link_get(self, ifindex); + return pllink ? pllink->mtu : 0; } /** @@ -1962,19 +2029,19 @@ nm_platform_link_get_mtu (NMPlatform *self, int ifindex) * Set interface name. */ gboolean -nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name) +nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); - g_return_val_if_fail (name, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); + g_return_val_if_fail(name, FALSE); - _LOG3D ("link: setting name %s", name); + _LOG3D("link: setting name %s", name); - if (strlen (name) + 1 > IFNAMSIZ) - return FALSE; + if (strlen(name) + 1 > IFNAMSIZ) + return FALSE; - return klass->link_set_name (self, ifindex, name); + return klass->link_set_name(self, ifindex, name); } /** @@ -1992,15 +2059,15 @@ nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name) * or if the interface has no physical port ID. */ char * -nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex) +nm_platform_link_get_physical_port_id(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, NULL); + _CHECK_SELF(self, klass, NULL); - g_return_val_if_fail (ifindex >= 0, NULL); + g_return_val_if_fail(ifindex >= 0, NULL); - if (klass->link_get_physical_port_id) - return klass->link_get_physical_port_id (self, ifindex); - return NULL; + if (klass->link_get_physical_port_id) + return klass->link_get_physical_port_id(self, ifindex); + return NULL; } /** @@ -2016,15 +2083,15 @@ nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex) * interface has no device ID. */ guint -nm_platform_link_get_dev_id (NMPlatform *self, int ifindex) +nm_platform_link_get_dev_id(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, 0); + _CHECK_SELF(self, klass, 0); - g_return_val_if_fail (ifindex >= 0, 0); + g_return_val_if_fail(ifindex >= 0, 0); - if (klass->link_get_dev_id) - return klass->link_get_dev_id (self, ifindex); - return 0; + if (klass->link_get_dev_id) + return klass->link_get_dev_id(self, ifindex); + return 0; } /** @@ -2035,15 +2102,15 @@ nm_platform_link_get_dev_id (NMPlatform *self, int ifindex) * Returns: the "Wake-on-LAN" status for @ifindex. */ gboolean -nm_platform_link_get_wake_on_lan (NMPlatform *self, int ifindex) +nm_platform_link_get_wake_on_lan(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); - if (klass->link_get_wake_on_lan) - return klass->link_get_wake_on_lan (self, ifindex); - return FALSE; + if (klass->link_get_wake_on_lan) + return klass->link_get_wake_on_lan(self, ifindex); + return FALSE; } /** @@ -2059,21 +2126,21 @@ nm_platform_link_get_wake_on_lan (NMPlatform *self, int ifindex) * failure. */ gboolean -nm_platform_link_get_driver_info (NMPlatform *self, - int ifindex, - char **out_driver_name, - char **out_driver_version, - char **out_fw_version) +nm_platform_link_get_driver_info(NMPlatform *self, + int ifindex, + char ** out_driver_name, + char ** out_driver_version, + char ** out_fw_version) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail(ifindex >= 0, FALSE); - return klass->link_get_driver_info (self, - ifindex, - out_driver_name, - out_driver_version, - out_fw_version); + return klass->link_get_driver_info(self, + ifindex, + out_driver_name, + out_driver_version, + out_fw_version); } /** @@ -2085,15 +2152,15 @@ nm_platform_link_get_driver_info (NMPlatform *self, * Enslave @ifindex to @master. */ gboolean -nm_platform_link_enslave (NMPlatform *self, int master, int ifindex) +nm_platform_link_enslave(NMPlatform *self, int master, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (master > 0, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(master > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - _LOG3D ("link: enslaving to master '%s'", nm_platform_link_get_name (self, master)); - return klass->link_enslave (self, master, ifindex); + _LOG3D("link: enslaving to master '%s'", nm_platform_link_get_name(self, master)); + return klass->link_enslave(self, master, ifindex); } /** @@ -2105,18 +2172,18 @@ nm_platform_link_enslave (NMPlatform *self, int master, int ifindex) * Release @slave from @master. */ gboolean -nm_platform_link_release (NMPlatform *self, int master, int ifindex) +nm_platform_link_release(NMPlatform *self, int master, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (master > 0, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(master > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - if (nm_platform_link_get_master (self, ifindex) != master) - return FALSE; + if (nm_platform_link_get_master(self, ifindex) != master) + return FALSE; - _LOG3D ("link: releasing from master '%s'", nm_platform_link_get_name (self, master)); - return klass->link_release (self, master, ifindex); + _LOG3D("link: releasing from master '%s'", nm_platform_link_get_name(self, master)); + return klass->link_release(self, master, ifindex); } /** @@ -2127,24 +2194,24 @@ nm_platform_link_release (NMPlatform *self, int master, int ifindex) * Returns: Interface index of the slave's master. */ int -nm_platform_link_get_master (NMPlatform *self, int slave) +nm_platform_link_get_master(NMPlatform *self, int slave) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - pllink = nm_platform_link_get (self, slave); - return pllink ? pllink->master : 0; + pllink = nm_platform_link_get(self, slave); + return pllink ? pllink->master : 0; } /*****************************************************************************/ gboolean -nm_platform_link_can_assume (NMPlatform *self, int ifindex) +nm_platform_link_can_assume(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - if (klass->link_can_assume) - return klass->link_can_assume (self, ifindex); - g_return_val_if_reached (FALSE); + if (klass->link_can_assume) + return klass->link_can_assume(self, ifindex); + g_return_val_if_reached(FALSE); } /*****************************************************************************/ @@ -2172,209 +2239,224 @@ nm_platform_link_can_assume (NMPlatform *self, int ifindex) * (but don't modify it). */ const NMPObject * -nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link) +nm_platform_link_get_lnk(NMPlatform * self, + int ifindex, + NMLinkType link_type, + const NMPlatformLink **out_link) { - const NMPObject *obj; + const NMPObject *obj; - obj = nm_platform_link_get_obj (self, ifindex, TRUE); - if (!obj) { - NM_SET_OUT (out_link, NULL); - return NULL; - } + obj = nm_platform_link_get_obj(self, ifindex, TRUE); + if (!obj) { + NM_SET_OUT(out_link, NULL); + return NULL; + } - NM_SET_OUT (out_link, &obj->link); + NM_SET_OUT(out_link, &obj->link); - if (!obj->_link.netlink.lnk) - return NULL; - if ( link_type != NM_LINK_TYPE_NONE - && ( link_type != obj->link.type - || link_type != NMP_OBJECT_GET_CLASS (obj->_link.netlink.lnk)->lnk_link_type)) - return NULL; + if (!obj->_link.netlink.lnk) + return NULL; + if (link_type != NM_LINK_TYPE_NONE + && (link_type != obj->link.type + || link_type != NMP_OBJECT_GET_CLASS(obj->_link.netlink.lnk)->lnk_link_type)) + return NULL; - return obj->_link.netlink.lnk; + return obj->_link.netlink.lnk; } static gconstpointer -_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link) +_link_get_lnk(NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link) { - const NMPObject *lnk; + const NMPObject *lnk; - lnk = nm_platform_link_get_lnk (self, ifindex, link_type, out_link); - return lnk ? &lnk->object : NULL; + lnk = nm_platform_link_get_lnk(self, ifindex, link_type, out_link); + return lnk ? &lnk->object : NULL; +} + +const NMPlatformLnkBridge * +nm_platform_link_get_lnk_bridge(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_BRIDGE, out_link); } const NMPlatformLnkGre * -nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_GRE, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_GRE, out_link); } const NMPlatformLnkGre * -nm_platform_link_get_lnk_gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_gretap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_GRETAP, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_GRETAP, out_link); } const NMPlatformLnkInfiniband * -nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_infiniband(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_INFINIBAND, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_INFINIBAND, out_link); } const NMPlatformLnkIp6Tnl * -nm_platform_link_get_lnk_ip6tnl (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_ip6tnl(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IP6TNL, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IP6TNL, out_link); } const NMPlatformLnkIp6Tnl * -nm_platform_link_get_lnk_ip6gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_ip6gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IP6GRE, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IP6GRE, out_link); } const NMPlatformLnkIp6Tnl * -nm_platform_link_get_lnk_ip6gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_ip6gretap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IP6GRETAP, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IP6GRETAP, out_link); } const NMPlatformLnkIpIp * -nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_ipip(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IPIP, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IPIP, out_link); } const NMPlatformLnkMacsec * -nm_platform_link_get_lnk_macsec (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_macsec(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACSEC, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_MACSEC, out_link); } const NMPlatformLnkMacvlan * -nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_macvlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVLAN, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_MACVLAN, out_link); } const NMPlatformLnkMacvlan * -nm_platform_link_get_lnk_macvtap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_macvtap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVTAP, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_MACVTAP, out_link); } const NMPlatformLnkSit * -nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_sit(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_SIT, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_SIT, out_link); } const NMPlatformLnkTun * -nm_platform_link_get_lnk_tun (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_tun(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_TUN, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_TUN, out_link); } const NMPlatformLnkVlan * -nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_vlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VLAN, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VLAN, out_link); } const NMPlatformLnkVrf * -nm_platform_link_get_lnk_vrf (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_vrf(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VRF, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VRF, out_link); } const NMPlatformLnkVxlan * -nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_vxlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VXLAN, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VXLAN, out_link); } const NMPlatformLnkWireGuard * -nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +nm_platform_link_get_lnk_wireguard(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_WIREGUARD, out_link); + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_WIREGUARD, out_link); } /*****************************************************************************/ -static -NM_UTILS_FLAGS2STR_DEFINE (_wireguard_change_flags_to_string, NMPlatformWireGuardChangeFlags, - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_FLAG_NONE, "none"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS, "replace-peers"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY, "has-private-key"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT, "has-listen-port"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK, "has-fwmark"), -); - -static -NM_UTILS_FLAGS2STR_DEFINE (_wireguard_change_peer_flags_to_string, NMPlatformWireGuardChangePeerFlags, - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE, "none"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REMOVE_ME, "remove"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY, "psk"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL, "ka"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT, "ep"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS, "aips"), - NM_UTILS_FLAGS2STR (NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS, "remove-aips"), -); +static NM_UTILS_FLAGS2STR_DEFINE( + _wireguard_change_flags_to_string, + NMPlatformWireGuardChangeFlags, + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_NONE, "none"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS, "replace-peers"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY, "has-private-key"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT, "has-listen-port"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK, "has-fwmark"), ); + +static NM_UTILS_FLAGS2STR_DEFINE( + _wireguard_change_peer_flags_to_string, + NMPlatformWireGuardChangePeerFlags, + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE, "none"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REMOVE_ME, "remove"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY, "psk"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL, "ka"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT, "ep"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS, "aips"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS, "remove-aips"), ); int -nm_platform_link_wireguard_change (NMPlatform *self, - int ifindex, - const NMPlatformLnkWireGuard *lnk_wireguard, - const NMPWireGuardPeer *peers, - const NMPlatformWireGuardChangePeerFlags *peer_flags, - guint peers_len, - NMPlatformWireGuardChangeFlags change_flags) -{ - _CHECK_SELF (self, klass, -NME_BUG); - - nm_assert (klass->link_wireguard_change); - - if (_LOGD_ENABLED ()) { - char buf_lnk[256]; - char buf_peers[512]; - char buf_change_flags[100]; - - buf_peers[0] = '\0'; - if (peers_len > 0) { - char *b = buf_peers; - gsize len = sizeof (buf_peers); - guint i; - - nm_utils_strbuf_append_str (&b, &len, " { "); - for (i = 0; i < peers_len; i++) { - nm_utils_strbuf_append_str (&b, &len, " { "); - nm_platform_wireguard_peer_to_string (&peers[i], b, len); - nm_utils_strbuf_seek_end (&b, &len); - if (peer_flags) { - nm_utils_strbuf_append (&b, &len, - " (%s)", - _wireguard_change_peer_flags_to_string (peer_flags[i], buf_change_flags, sizeof (buf_change_flags))); - } - nm_utils_strbuf_append_str (&b, &len, " } "); - } - nm_utils_strbuf_append_str (&b, &len, "}"); - } - - _LOG3D ("link: change wireguard ifindex %d, %s, (%s), %u peers%s", - ifindex, - nm_platform_lnk_wireguard_to_string (lnk_wireguard, buf_lnk, sizeof (buf_lnk)), - _wireguard_change_flags_to_string (change_flags, buf_change_flags, sizeof (buf_change_flags)), - peers_len, - buf_peers); - } - - return klass->link_wireguard_change (self, - ifindex, - lnk_wireguard, - peers, - peer_flags, - peers_len, - change_flags); +nm_platform_link_wireguard_change(NMPlatform * self, + int ifindex, + const NMPlatformLnkWireGuard * lnk_wireguard, + const NMPWireGuardPeer * peers, + const NMPlatformWireGuardChangePeerFlags *peer_flags, + guint peers_len, + NMPlatformWireGuardChangeFlags change_flags) +{ + _CHECK_SELF(self, klass, -NME_BUG); + + nm_assert(klass->link_wireguard_change); + + if (_LOGD_ENABLED()) { + char buf_lnk[256]; + char buf_peers[512]; + char buf_change_flags[100]; + + buf_peers[0] = '\0'; + if (peers_len > 0) { + char *b = buf_peers; + gsize len = sizeof(buf_peers); + guint i; + + nm_utils_strbuf_append_str(&b, &len, " { "); + for (i = 0; i < peers_len; i++) { + nm_utils_strbuf_append_str(&b, &len, " { "); + nm_platform_wireguard_peer_to_string(&peers[i], b, len); + nm_utils_strbuf_seek_end(&b, &len); + if (peer_flags) { + nm_utils_strbuf_append( + &b, + &len, + " (%s)", + _wireguard_change_peer_flags_to_string(peer_flags[i], + buf_change_flags, + sizeof(buf_change_flags))); + } + nm_utils_strbuf_append_str(&b, &len, " } "); + } + nm_utils_strbuf_append_str(&b, &len, "}"); + } + + _LOG3D("link: change wireguard ifindex %d, %s, (%s), %u peers%s", + ifindex, + nm_platform_lnk_wireguard_to_string(lnk_wireguard, buf_lnk, sizeof(buf_lnk)), + _wireguard_change_flags_to_string(change_flags, + buf_change_flags, + sizeof(buf_change_flags)), + peers_len, + buf_peers); + } + + return klass->link_wireguard_change(self, + ifindex, + lnk_wireguard, + peers, + peer_flags, + peers_len, + change_flags); } /*****************************************************************************/ @@ -2399,433 +2481,451 @@ nm_platform_link_wireguard_change (NMPlatform *self, * Create a TUN or TAP interface. */ int -nm_platform_link_tun_add (NMPlatform *self, - const char *name, - const NMPlatformLnkTun *props, - const NMPlatformLink **out_link, - int *out_fd) +nm_platform_link_tun_add(NMPlatform * self, + const char * name, + const NMPlatformLnkTun *props, + const NMPlatformLink ** out_link, + int * out_fd) { - char b[255]; - int r; + char b[255]; + int r; - _CHECK_SELF (self, klass, -NME_BUG); + _CHECK_SELF(self, klass, -NME_BUG); - g_return_val_if_fail (name, -NME_BUG); - g_return_val_if_fail (props, -NME_BUG); - g_return_val_if_fail (NM_IN_SET (props->type, IFF_TUN, IFF_TAP), -NME_BUG); + g_return_val_if_fail(name, -NME_BUG); + g_return_val_if_fail(props, -NME_BUG); + g_return_val_if_fail(NM_IN_SET(props->type, IFF_TUN, IFF_TAP), -NME_BUG); - /* creating a non-persistant device requires that the caller handles - * the file descriptor. */ - g_return_val_if_fail (props->persist || out_fd, -NME_BUG); + /* creating a non-persistent device requires that the caller handles + * the file descriptor. */ + g_return_val_if_fail(props->persist || out_fd, -NME_BUG); - NM_SET_OUT (out_fd, -1); + NM_SET_OUT(out_fd, -1); - r = _link_add_check_existing (self, name, NM_LINK_TYPE_TUN, out_link); - if (r < 0) - return r; + r = _link_add_check_existing(self, name, NM_LINK_TYPE_TUN, out_link); + if (r < 0) + return r; - _LOG2D ("link: adding link %s", nm_platform_lnk_tun_to_string (props, b, sizeof (b))); + _LOG2D("link: adding link %s", nm_platform_lnk_tun_to_string(props, b, sizeof(b))); - if (!klass->link_tun_add (self, name, props, out_link, out_fd)) - return -NME_UNSPEC; - return 0; + if (!klass->link_tun_add(self, name, props, out_link, out_fd)) + return -NME_UNSPEC; + return 0; } gboolean -nm_platform_link_6lowpan_get_properties (NMPlatform *self, int ifindex, int *out_parent) +nm_platform_link_6lowpan_get_properties(NMPlatform *self, int ifindex, int *out_parent) { - const NMPlatformLink *plink; + const NMPlatformLink *plink; - plink = nm_platform_link_get (self, ifindex); - if (!plink) - return FALSE; + plink = nm_platform_link_get(self, ifindex); + if (!plink) + return FALSE; - if (plink->type != NM_LINK_TYPE_6LOWPAN) - return FALSE; + if (plink->type != NM_LINK_TYPE_6LOWPAN) + return FALSE; - if (plink->parent != 0) { - NM_SET_OUT (out_parent, plink->parent); - return TRUE; - } + if (plink->parent != 0) { + NM_SET_OUT(out_parent, plink->parent); + return TRUE; + } - /* As of 4.16 kernel does not expose the peer_ifindex as IFA_LINK. - * Find the WPAN device with the same MAC address. */ - if (out_parent) { - const NMPlatformLink *parent_plink; + /* As of 4.16 kernel does not expose the peer_ifindex as IFA_LINK. + * Find the WPAN device with the same MAC address. */ + if (out_parent) { + const NMPlatformLink *parent_plink; - parent_plink = nm_platform_link_get_by_address (self, - NM_LINK_TYPE_WPAN, - plink->l_address.data, - plink->l_address.len); - NM_SET_OUT (out_parent, parent_plink ? parent_plink->ifindex : -1); - } + parent_plink = nm_platform_link_get_by_address(self, + NM_LINK_TYPE_WPAN, + plink->l_address.data, + plink->l_address.len); + NM_SET_OUT(out_parent, parent_plink ? parent_plink->ifindex : -1); + } - return TRUE; + return TRUE; } /*****************************************************************************/ static gboolean -link_set_option (NMPlatform *self, int ifindex, const char *category, const char *option, const char *value) +link_set_option(NMPlatform *self, + int ifindex, + const char *category, + const char *option, + const char *value) { - nm_auto_close int dirfd = -1; - char ifname_verified[IFNAMSIZ]; - const char *path; + nm_auto_close int dirfd = -1; + char ifname_verified[IFNAMSIZ]; + const char * path; - if (!category || !option) - return FALSE; + if (!category || !option) + return FALSE; - dirfd = nm_platform_sysctl_open_netdir (self, ifindex, ifname_verified); - if (dirfd < 0) - return FALSE; + dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname_verified); + if (dirfd < 0) + return FALSE; - path = nm_sprintf_buf_unsafe_a (strlen (category) + strlen (option) + 2, - "%s/%s", - category, - option); - return nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_NETDIR_unsafe (dirfd, ifname_verified, path), value); + path = + nm_sprintf_buf_unsafe_a(strlen(category) + strlen(option) + 2, "%s/%s", category, option); + return nm_platform_sysctl_set(self, + NMP_SYSCTL_PATHID_NETDIR_unsafe(dirfd, ifname_verified, path), + value); } static char * -link_get_option (NMPlatform *self, int ifindex, const char *category, const char *option) +link_get_option(NMPlatform *self, int ifindex, const char *category, const char *option) { - nm_auto_close int dirfd = -1; - char ifname_verified[IFNAMSIZ]; - const char *path; + nm_auto_close int dirfd = -1; + char ifname_verified[IFNAMSIZ]; + const char * path; - if (!category || !option) - return NULL; + if (!category || !option) + return NULL; - dirfd = nm_platform_sysctl_open_netdir (self, ifindex, ifname_verified); - if (dirfd < 0) - return NULL; + dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname_verified); + if (dirfd < 0) + return NULL; - path = nm_sprintf_buf_unsafe_a (strlen (category) + strlen (option) + 2, - "%s/%s", - category, option); - return nm_platform_sysctl_get (self, NMP_SYSCTL_PATHID_NETDIR_unsafe (dirfd, ifname_verified, path)); + path = + nm_sprintf_buf_unsafe_a(strlen(category) + strlen(option) + 2, "%s/%s", category, option); + return nm_platform_sysctl_get(self, + NMP_SYSCTL_PATHID_NETDIR_unsafe(dirfd, ifname_verified, path)); } static const char * -master_category (NMPlatform *self, int master) +master_category(NMPlatform *self, int master) { - switch (nm_platform_link_get_type (self, master)) { - case NM_LINK_TYPE_BRIDGE: - return "bridge"; - case NM_LINK_TYPE_BOND: - return "bonding"; - default: - return NULL; - } + switch (nm_platform_link_get_type(self, master)) { + case NM_LINK_TYPE_BRIDGE: + return "bridge"; + case NM_LINK_TYPE_BOND: + return "bonding"; + default: + return NULL; + } } static const char * -slave_category (NMPlatform *self, int slave) +slave_category(NMPlatform *self, int slave) { - int master = nm_platform_link_get_master (self, slave); + int master = nm_platform_link_get_master(self, slave); - if (master <= 0) - return NULL; + if (master <= 0) + return NULL; - switch (nm_platform_link_get_type (self, master)) { - case NM_LINK_TYPE_BRIDGE: - return "brport"; - default: - return NULL; - } + switch (nm_platform_link_get_type(self, master)) { + case NM_LINK_TYPE_BRIDGE: + return "brport"; + default: + return NULL; + } } gboolean -nm_platform_sysctl_master_set_option (NMPlatform *self, int ifindex, const char *option, const char *value) +nm_platform_sysctl_master_set_option(NMPlatform *self, + int ifindex, + const char *option, + const char *value) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (option, FALSE); - g_return_val_if_fail (value, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(option, FALSE); + g_return_val_if_fail(value, FALSE); - return link_set_option (self, ifindex, master_category (self, ifindex), option, value); + return link_set_option(self, ifindex, master_category(self, ifindex), option, value); } char * -nm_platform_sysctl_master_get_option (NMPlatform *self, int ifindex, const char *option) +nm_platform_sysctl_master_get_option(NMPlatform *self, int ifindex, const char *option) { - _CHECK_SELF (self, klass, NULL); + _CHECK_SELF(self, klass, NULL); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (option, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(option, FALSE); - return link_get_option (self, ifindex, master_category (self, ifindex), option); + return link_get_option(self, ifindex, master_category(self, ifindex), option); } gboolean -nm_platform_sysctl_slave_set_option (NMPlatform *self, int ifindex, const char *option, const char *value) +nm_platform_sysctl_slave_set_option(NMPlatform *self, + int ifindex, + const char *option, + const char *value) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (option, FALSE); - g_return_val_if_fail (value, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(option, FALSE); + g_return_val_if_fail(value, FALSE); - return link_set_option (self, ifindex, slave_category (self, ifindex), option, value); + return link_set_option(self, ifindex, slave_category(self, ifindex), option, value); } char * -nm_platform_sysctl_slave_get_option (NMPlatform *self, int ifindex, const char *option) +nm_platform_sysctl_slave_get_option(NMPlatform *self, int ifindex, const char *option) { - _CHECK_SELF (self, klass, NULL); + _CHECK_SELF(self, klass, NULL); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (option, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(option, FALSE); - return link_get_option (self, ifindex, slave_category (self, ifindex), option); + return link_get_option(self, ifindex, slave_category(self, ifindex), option); } /*****************************************************************************/ gboolean -nm_platform_link_vlan_change (NMPlatform *self, - int ifindex, - NMVlanFlags flags_mask, - NMVlanFlags flags_set, - gboolean ingress_reset_all, - const NMVlanQosMapping *ingress_map, - gsize n_ingress_map, - gboolean egress_reset_all, - const NMVlanQosMapping *egress_map, - gsize n_egress_map) -{ - _CHECK_SELF (self, klass, FALSE); - - nm_assert (klass->link_vlan_change); - - g_return_val_if_fail (!n_ingress_map || ingress_map, FALSE); - g_return_val_if_fail (!n_egress_map || egress_map, FALSE); - - flags_set &= flags_mask; - - if (_LOGD_ENABLED ()) { - char buf[512]; - char *b = buf; - gsize len, i; - - b[0] = '\0'; - len = sizeof (buf); - - if (flags_mask) - nm_utils_strbuf_append (&b, &len, " flags 0x%x/0x%x", (unsigned) flags_set, (unsigned) flags_mask); - - if (ingress_reset_all || n_ingress_map) { - nm_utils_strbuf_append_str (&b, &len, " ingress-qos-map"); - nm_platform_vlan_qos_mapping_to_string ("", ingress_map, n_ingress_map, b, len); - i = strlen (b); - b += i; - len -= i; - if (ingress_reset_all) - nm_utils_strbuf_append_str (&b, &len, " (reset-all)"); - } - - if (egress_reset_all || n_egress_map) { - nm_utils_strbuf_append_str (&b, &len, " egress-qos-map"); - nm_platform_vlan_qos_mapping_to_string ("", egress_map, n_egress_map, b, len); - i = strlen (b); - b += i; - len -= i; - if (egress_reset_all) - nm_utils_strbuf_append_str (&b, &len, " (reset-all)"); - } - - _LOG3D ("link: change vlan %s", buf); - } - return klass->link_vlan_change (self, - ifindex, - flags_mask, - flags_set, - ingress_reset_all, - ingress_map, - n_ingress_map, - egress_reset_all, - egress_map, - n_egress_map); +nm_platform_link_vlan_change(NMPlatform * self, + int ifindex, + NMVlanFlags flags_mask, + NMVlanFlags flags_set, + gboolean ingress_reset_all, + const NMVlanQosMapping *ingress_map, + gsize n_ingress_map, + gboolean egress_reset_all, + const NMVlanQosMapping *egress_map, + gsize n_egress_map) +{ + _CHECK_SELF(self, klass, FALSE); + + nm_assert(klass->link_vlan_change); + + g_return_val_if_fail(!n_ingress_map || ingress_map, FALSE); + g_return_val_if_fail(!n_egress_map || egress_map, FALSE); + + flags_set &= flags_mask; + + if (_LOGD_ENABLED()) { + char buf[512]; + char *b = buf; + gsize len, i; + + b[0] = '\0'; + len = sizeof(buf); + + if (flags_mask) + nm_utils_strbuf_append(&b, + &len, + " flags 0x%x/0x%x", + (unsigned) flags_set, + (unsigned) flags_mask); + + if (ingress_reset_all || n_ingress_map) { + nm_utils_strbuf_append_str(&b, &len, " ingress-qos-map"); + nm_platform_vlan_qos_mapping_to_string("", ingress_map, n_ingress_map, b, len); + i = strlen(b); + b += i; + len -= i; + if (ingress_reset_all) + nm_utils_strbuf_append_str(&b, &len, " (reset-all)"); + } + + if (egress_reset_all || n_egress_map) { + nm_utils_strbuf_append_str(&b, &len, " egress-qos-map"); + nm_platform_vlan_qos_mapping_to_string("", egress_map, n_egress_map, b, len); + i = strlen(b); + b += i; + len -= i; + if (egress_reset_all) + nm_utils_strbuf_append_str(&b, &len, " (reset-all)"); + } + + _LOG3D("link: change vlan %s", buf); + } + return klass->link_vlan_change(self, + ifindex, + flags_mask, + flags_set, + ingress_reset_all, + ingress_map, + n_ingress_map, + egress_reset_all, + egress_map, + n_egress_map); } gboolean -nm_platform_link_vlan_set_ingress_map (NMPlatform *self, int ifindex, int from, int to) +nm_platform_link_vlan_set_ingress_map(NMPlatform *self, int ifindex, int from, int to) { - NMVlanQosMapping map = { - .from = from, - .to = to, - }; + NMVlanQosMapping map = { + .from = from, + .to = to, + }; - return nm_platform_link_vlan_change (self, ifindex, 0, 0, FALSE, &map, 1, FALSE, NULL, 0); + return nm_platform_link_vlan_change(self, ifindex, 0, 0, FALSE, &map, 1, FALSE, NULL, 0); } gboolean -nm_platform_link_vlan_set_egress_map (NMPlatform *self, int ifindex, int from, int to) +nm_platform_link_vlan_set_egress_map(NMPlatform *self, int ifindex, int from, int to) { - NMVlanQosMapping map = { - .from = from, - .to = to, - }; + NMVlanQosMapping map = { + .from = from, + .to = to, + }; - return nm_platform_link_vlan_change (self, ifindex, 0, 0, FALSE, NULL, 0, FALSE, &map, 1); + return nm_platform_link_vlan_change(self, ifindex, 0, 0, FALSE, NULL, 0, FALSE, &map, 1); } static int -_infiniband_add_add_or_delete (NMPlatform *self, - int ifindex, - int p_key, - gboolean add, - const NMPlatformLink **out_link) +_infiniband_add_add_or_delete(NMPlatform * self, + int ifindex, + int p_key, + gboolean add, + const NMPlatformLink **out_link) { - char name[IFNAMSIZ]; - const NMPlatformLink *parent_link; - int r; + char name[IFNAMSIZ]; + const NMPlatformLink *parent_link; + int r; - _CHECK_SELF (self, klass, -NME_BUG); + _CHECK_SELF(self, klass, -NME_BUG); - g_return_val_if_fail (ifindex >= 0, -NME_BUG); - g_return_val_if_fail (p_key >= 0 && p_key <= 0xffff, -NME_BUG); + g_return_val_if_fail(ifindex >= 0, -NME_BUG); + g_return_val_if_fail(p_key >= 0 && p_key <= 0xffff, -NME_BUG); - /* the special keys 0x0000 and 0x8000 are not allowed. */ - if (NM_IN_SET (p_key, 0, 0x8000)) - return -NME_UNSPEC; + /* the special keys 0x0000 and 0x8000 are not allowed. */ + if (NM_IN_SET(p_key, 0, 0x8000)) + return -NME_UNSPEC; - parent_link = nm_platform_link_get (self, ifindex); - if (!parent_link) - return -NME_PL_NOT_FOUND; + parent_link = nm_platform_link_get(self, ifindex); + if (!parent_link) + return -NME_PL_NOT_FOUND; - if (parent_link->type != NM_LINK_TYPE_INFINIBAND) - return -NME_PL_WRONG_TYPE; + if (parent_link->type != NM_LINK_TYPE_INFINIBAND) + return -NME_PL_WRONG_TYPE; - nm_utils_new_infiniband_name (name, parent_link->name, p_key); + nm_utils_new_infiniband_name(name, parent_link->name, p_key); - if (add) { - r = _link_add_check_existing (self, name, NM_LINK_TYPE_INFINIBAND, out_link); - if (r < 0) - return r; + if (add) { + r = _link_add_check_existing(self, name, NM_LINK_TYPE_INFINIBAND, out_link); + if (r < 0) + return r; - _LOG3D ("link: adding infiniband partition %s, key %d", name, p_key); - if (!klass->infiniband_partition_add (self, ifindex, p_key, out_link)) - return -NME_UNSPEC; - } else { - _LOG3D ("link: deleting infiniband partition %s, key %d", name, p_key); + _LOG3D("link: adding infiniband partition %s, key %d", name, p_key); + if (!klass->infiniband_partition_add(self, ifindex, p_key, out_link)) + return -NME_UNSPEC; + } else { + _LOG3D("link: deleting infiniband partition %s, key %d", name, p_key); - if (!klass->infiniband_partition_delete (self, ifindex, p_key)) - return -NME_UNSPEC; - } + if (!klass->infiniband_partition_delete(self, ifindex, p_key)) + return -NME_UNSPEC; + } - return 0; + return 0; } int -nm_platform_link_infiniband_add (NMPlatform *self, - int parent, - int p_key, - const NMPlatformLink **out_link) +nm_platform_link_infiniband_add(NMPlatform * self, + int parent, + int p_key, + const NMPlatformLink **out_link) { - return _infiniband_add_add_or_delete (self, parent, p_key, TRUE, out_link); + return _infiniband_add_add_or_delete(self, parent, p_key, TRUE, out_link); } int -nm_platform_link_infiniband_delete (NMPlatform *self, - int parent, - int p_key) +nm_platform_link_infiniband_delete(NMPlatform *self, int parent, int p_key) { - return _infiniband_add_add_or_delete (self, parent, p_key, FALSE, NULL); + return _infiniband_add_add_or_delete(self, parent, p_key, FALSE, NULL); } gboolean -nm_platform_link_infiniband_get_properties (NMPlatform *self, - int ifindex, - int *out_parent, - int *out_p_key, - const char **out_mode) -{ - nm_auto_close int dirfd = -1; - char ifname_verified[IFNAMSIZ]; - const NMPlatformLnkInfiniband *plnk; - const NMPlatformLink *plink; - char *contents; - const char *mode; - int p_key = 0; - - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - plnk = nm_platform_link_get_lnk_infiniband (self, ifindex, &plink); - - if ( !plink - || plink->type != NM_LINK_TYPE_INFINIBAND) - return FALSE; - - if (plnk) { - NM_SET_OUT (out_parent, plink->parent); - NM_SET_OUT (out_p_key, plnk->p_key); - NM_SET_OUT (out_mode, plnk->mode); - return TRUE; - } - - /* Could not get the link information via netlink. To support older kernels, - * fallback to reading sysfs. */ - - dirfd = nm_platform_sysctl_open_netdir (self, ifindex, ifname_verified); - if (dirfd < 0) - return FALSE; - - contents = nm_platform_sysctl_get (self, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname_verified, "mode")); - if (!contents) - return FALSE; - if (strstr (contents, "datagram")) - mode = "datagram"; - else if (strstr (contents, "connected")) - mode = "connected"; - else - mode = NULL; - g_free (contents); - - p_key = nm_platform_sysctl_get_int_checked (self, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname_verified, "pkey"), 16, 0, 0xFFFF, -1); - if (p_key < 0) - return FALSE; - - NM_SET_OUT (out_parent, plink->parent); - NM_SET_OUT (out_p_key, p_key); - NM_SET_OUT (out_mode, mode); - return TRUE; +nm_platform_link_infiniband_get_properties(NMPlatform * self, + int ifindex, + int * out_parent, + int * out_p_key, + const char **out_mode) +{ + nm_auto_close int dirfd = -1; + char ifname_verified[IFNAMSIZ]; + const NMPlatformLnkInfiniband *plnk; + const NMPlatformLink * plink; + char * contents; + const char * mode; + int p_key = 0; + + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + plnk = nm_platform_link_get_lnk_infiniband(self, ifindex, &plink); + + if (!plink || plink->type != NM_LINK_TYPE_INFINIBAND) + return FALSE; + + if (plnk) { + NM_SET_OUT(out_parent, plink->parent); + NM_SET_OUT(out_p_key, plnk->p_key); + NM_SET_OUT(out_mode, plnk->mode); + return TRUE; + } + + /* Could not get the link information via netlink. To support older kernels, + * fallback to reading sysfs. */ + + dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname_verified); + if (dirfd < 0) + return FALSE; + + contents = + nm_platform_sysctl_get(self, NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname_verified, "mode")); + if (!contents) + return FALSE; + if (strstr(contents, "datagram")) + mode = "datagram"; + else if (strstr(contents, "connected")) + mode = "connected"; + else + mode = NULL; + g_free(contents); + + p_key = + nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname_verified, "pkey"), + 16, + 0, + 0xFFFF, + -1); + if (p_key < 0) + return FALSE; + + NM_SET_OUT(out_parent, plink->parent); + NM_SET_OUT(out_p_key, p_key); + NM_SET_OUT(out_mode, mode); + return TRUE; } gboolean -nm_platform_link_veth_get_properties (NMPlatform *self, int ifindex, int *out_peer_ifindex) +nm_platform_link_veth_get_properties(NMPlatform *self, int ifindex, int *out_peer_ifindex) { - const NMPlatformLink *plink; - int peer_ifindex; + const NMPlatformLink *plink; + int peer_ifindex; - plink = nm_platform_link_get (self, ifindex); - if (!plink) - return FALSE; + plink = nm_platform_link_get(self, ifindex); + if (!plink) + return FALSE; - if (plink->type != NM_LINK_TYPE_VETH) - return FALSE; + if (plink->type != NM_LINK_TYPE_VETH) + return FALSE; - if (plink->parent != 0) { - NM_SET_OUT (out_peer_ifindex, plink->parent); - return TRUE; - } + if (plink->parent != 0) { + NM_SET_OUT(out_peer_ifindex, plink->parent); + return TRUE; + } - /* Pre-4.1 kernel did not expose the peer_ifindex as IFA_LINK. Lookup via ethtool. */ - if (out_peer_ifindex) { - nm_auto_pop_netns NMPNetns *netns = NULL; + /* Pre-4.1 kernel did not expose the peer_ifindex as IFA_LINK. Lookup via ethtool. */ + if (out_peer_ifindex) { + nm_auto_pop_netns NMPNetns *netns = NULL; - if (!nm_platform_netns_push (self, &netns)) - return FALSE; - peer_ifindex = nmp_utils_ethtool_get_peer_ifindex (plink->ifindex); - if (peer_ifindex <= 0) - return FALSE; + if (!nm_platform_netns_push(self, &netns)) + return FALSE; + peer_ifindex = nmp_utils_ethtool_get_peer_ifindex(plink->ifindex); + if (peer_ifindex <= 0) + return FALSE; - *out_peer_ifindex = peer_ifindex; - } - return TRUE; + *out_peer_ifindex = peer_ifindex; + } + return TRUE; } /** @@ -2851,490 +2951,504 @@ nm_platform_link_veth_get_properties (NMPlatform *self, int ifindex, int *out_pe * * Returns: #TRUE, if the properties could be read. */ gboolean -nm_platform_link_tun_get_properties (NMPlatform *self, - int ifindex, - NMPlatformLnkTun *out_properties) -{ - const NMPObject *plobj; - const NMPObject *pllnk; - char ifname[IFNAMSIZ]; - gint64 owner; - gint64 group; - gint64 flags; - - /* we consider also invisible links (those that are not yet in udev). */ - plobj = nm_platform_link_get_obj (self, ifindex, FALSE); - if (!plobj) - return FALSE; - - if (NMP_OBJECT_CAST_LINK (plobj)->type != NM_LINK_TYPE_TUN) - return FALSE; - - pllnk = plobj->_link.netlink.lnk; - if (pllnk) { - nm_assert (NMP_OBJECT_GET_TYPE (pllnk) == NMP_OBJECT_TYPE_LNK_TUN); - nm_assert (NMP_OBJECT_GET_CLASS (pllnk)->lnk_link_type == NM_LINK_TYPE_TUN); - - /* recent kernels expose tun properties via netlink and thus we have them - * in the platform cache. */ - NM_SET_OUT (out_properties, pllnk->lnk_tun); - return TRUE; - } - - /* fallback to reading sysctl. */ - { - nm_auto_close int dirfd = -1; - - dirfd = nm_platform_sysctl_open_netdir (self, ifindex, ifname); - if (dirfd < 0) - return FALSE; - - owner = nm_platform_sysctl_get_int_checked (self, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "owner"), 10, -1, G_MAXUINT32, -2); - if (owner == -2) - return FALSE; - - group = nm_platform_sysctl_get_int_checked (self, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "group"), 10, -1, G_MAXUINT32, -2); - if (group == -2) - return FALSE; - - flags = nm_platform_sysctl_get_int_checked (self, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "tun_flags"), 16, 0, G_MAXINT64, -1); - if (flags == -1) - return FALSE; - } - - if (out_properties) { - memset (out_properties, 0, sizeof (*out_properties)); - if (owner != -1) { - out_properties->owner_valid = TRUE; - out_properties->owner = owner; - } - if (group != -1) { - out_properties->group_valid = TRUE; - out_properties->group = group; - } - out_properties->type = (flags & TUN_TYPE_MASK); - out_properties->pi = !(flags & IFF_NO_PI); - out_properties->vnet_hdr = !!(flags & IFF_VNET_HDR); - out_properties->multi_queue = !!(flags & NM_IFF_MULTI_QUEUE); - out_properties->persist = !!(flags & IFF_PERSIST); - } - return TRUE; +nm_platform_link_tun_get_properties(NMPlatform *self, int ifindex, NMPlatformLnkTun *out_properties) +{ + const NMPObject *plobj; + const NMPObject *pllnk; + char ifname[IFNAMSIZ]; + gint64 owner; + gint64 group; + gint64 flags; + + /* we consider also invisible links (those that are not yet in udev). */ + plobj = nm_platform_link_get_obj(self, ifindex, FALSE); + if (!plobj) + return FALSE; + + if (NMP_OBJECT_CAST_LINK(plobj)->type != NM_LINK_TYPE_TUN) + return FALSE; + + pllnk = plobj->_link.netlink.lnk; + if (pllnk) { + nm_assert(NMP_OBJECT_GET_TYPE(pllnk) == NMP_OBJECT_TYPE_LNK_TUN); + nm_assert(NMP_OBJECT_GET_CLASS(pllnk)->lnk_link_type == NM_LINK_TYPE_TUN); + + /* recent kernels expose tun properties via netlink and thus we have them + * in the platform cache. */ + NM_SET_OUT(out_properties, pllnk->lnk_tun); + return TRUE; + } + + /* fallback to reading sysctl. */ + { + nm_auto_close int dirfd = -1; + + dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname); + if (dirfd < 0) + return FALSE; + + owner = nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "owner"), + 10, + -1, + G_MAXUINT32, + -2); + if (owner == -2) + return FALSE; + + group = nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "group"), + 10, + -1, + G_MAXUINT32, + -2); + if (group == -2) + return FALSE; + + flags = + nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "tun_flags"), + 16, + 0, + G_MAXINT64, + -1); + if (flags == -1) + return FALSE; + } + + if (out_properties) { + memset(out_properties, 0, sizeof(*out_properties)); + if (owner != -1) { + out_properties->owner_valid = TRUE; + out_properties->owner = owner; + } + if (group != -1) { + out_properties->group_valid = TRUE; + out_properties->group = group; + } + out_properties->type = (flags & TUN_TYPE_MASK); + out_properties->pi = !(flags & IFF_NO_PI); + out_properties->vnet_hdr = !!(flags & IFF_VNET_HDR); + out_properties->multi_queue = !!(flags & NM_IFF_MULTI_QUEUE); + out_properties->persist = !!(flags & IFF_PERSIST); + } + return TRUE; } gboolean -nm_platform_wifi_get_capabilities (NMPlatform *self, int ifindex, NMDeviceWifiCapabilities *caps) +nm_platform_wifi_get_capabilities(NMPlatform *self, int ifindex, NMDeviceWifiCapabilities *caps) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->wifi_get_capabilities (self, ifindex, caps); + return klass->wifi_get_capabilities(self, ifindex, caps); } gboolean -nm_platform_wifi_get_bssid (NMPlatform *self, int ifindex, guint8 *bssid) +nm_platform_wifi_get_bssid(NMPlatform *self, int ifindex, guint8 *bssid) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->wifi_get_bssid (self, ifindex, bssid); + return klass->wifi_get_bssid(self, ifindex, bssid); } guint32 -nm_platform_wifi_get_frequency (NMPlatform *self, int ifindex) +nm_platform_wifi_get_frequency(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, 0); + _CHECK_SELF(self, klass, 0); - g_return_val_if_fail (ifindex > 0, 0); + g_return_val_if_fail(ifindex > 0, 0); - return klass->wifi_get_frequency (self, ifindex); + return klass->wifi_get_frequency(self, ifindex); } int -nm_platform_wifi_get_quality (NMPlatform *self, int ifindex) +nm_platform_wifi_get_quality(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, 0); + _CHECK_SELF(self, klass, 0); - g_return_val_if_fail (ifindex > 0, 0); + g_return_val_if_fail(ifindex > 0, 0); - return klass->wifi_get_quality (self, ifindex); + return klass->wifi_get_quality(self, ifindex); } guint32 -nm_platform_wifi_get_rate (NMPlatform *self, int ifindex) +nm_platform_wifi_get_rate(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, 0); + _CHECK_SELF(self, klass, 0); - g_return_val_if_fail (ifindex > 0, 0); + g_return_val_if_fail(ifindex > 0, 0); - return klass->wifi_get_rate (self, ifindex); + return klass->wifi_get_rate(self, ifindex); } NM80211Mode -nm_platform_wifi_get_mode (NMPlatform *self, int ifindex) +nm_platform_wifi_get_mode(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, NM_802_11_MODE_UNKNOWN); + _CHECK_SELF(self, klass, NM_802_11_MODE_UNKNOWN); - g_return_val_if_fail (ifindex > 0, NM_802_11_MODE_UNKNOWN); + g_return_val_if_fail(ifindex > 0, NM_802_11_MODE_UNKNOWN); - return klass->wifi_get_mode (self, ifindex); + return klass->wifi_get_mode(self, ifindex); } void -nm_platform_wifi_set_mode (NMPlatform *self, int ifindex, NM80211Mode mode) +nm_platform_wifi_set_mode(NMPlatform *self, int ifindex, NM80211Mode mode) { - _CHECK_SELF_VOID (self, klass); + _CHECK_SELF_VOID(self, klass); - g_return_if_fail (ifindex > 0); + g_return_if_fail(ifindex > 0); - klass->wifi_set_mode (self, ifindex, mode); + klass->wifi_set_mode(self, ifindex, mode); } static void -wifi_set_powersave (NMPlatform *p, int ifindex, guint32 powersave) +wifi_set_powersave(NMPlatform *p, int ifindex, guint32 powersave) { - /* empty */ + /* empty */ } void -nm_platform_wifi_set_powersave (NMPlatform *self, int ifindex, guint32 powersave) +nm_platform_wifi_set_powersave(NMPlatform *self, int ifindex, guint32 powersave) { - _CHECK_SELF_VOID (self, klass); + _CHECK_SELF_VOID(self, klass); - g_return_if_fail (ifindex > 0); + g_return_if_fail(ifindex > 0); - klass->wifi_set_powersave (self, ifindex, powersave); + klass->wifi_set_powersave(self, ifindex, powersave); } guint32 -nm_platform_wifi_find_frequency (NMPlatform *self, int ifindex, const guint32 *freqs) +nm_platform_wifi_find_frequency(NMPlatform *self, int ifindex, const guint32 *freqs) { - _CHECK_SELF (self, klass, 0); + _CHECK_SELF(self, klass, 0); - g_return_val_if_fail (ifindex > 0, 0); - g_return_val_if_fail (freqs != NULL, 0); + g_return_val_if_fail(ifindex > 0, 0); + g_return_val_if_fail(freqs != NULL, 0); - return klass->wifi_find_frequency (self, ifindex, freqs); + return klass->wifi_find_frequency(self, ifindex, freqs); } void -nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gboolean running) +nm_platform_wifi_indicate_addressing_running(NMPlatform *self, int ifindex, gboolean running) { - _CHECK_SELF_VOID (self, klass); + _CHECK_SELF_VOID(self, klass); - g_return_if_fail (ifindex > 0); + g_return_if_fail(ifindex > 0); - klass->wifi_indicate_addressing_running (self, ifindex, running); + klass->wifi_indicate_addressing_running(self, ifindex, running); } NMSettingWirelessWakeOnWLan -nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex) +nm_platform_wifi_get_wake_on_wlan(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->wifi_get_wake_on_wlan (self, ifindex); + return klass->wifi_get_wake_on_wlan(self, ifindex); } gboolean -nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl) +nm_platform_wifi_set_wake_on_wlan(NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->wifi_set_wake_on_wlan (self, ifindex, wowl); + return klass->wifi_set_wake_on_wlan(self, ifindex, wowl); } guint32 -nm_platform_mesh_get_channel (NMPlatform *self, int ifindex) +nm_platform_mesh_get_channel(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, 0); + _CHECK_SELF(self, klass, 0); - g_return_val_if_fail (ifindex > 0, 0); + g_return_val_if_fail(ifindex > 0, 0); - return klass->mesh_get_channel (self, ifindex); + return klass->mesh_get_channel(self, ifindex); } gboolean -nm_platform_mesh_set_channel (NMPlatform *self, int ifindex, guint32 channel) +nm_platform_mesh_set_channel(NMPlatform *self, int ifindex, guint32 channel) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->mesh_set_channel (self, ifindex, channel); + return klass->mesh_set_channel(self, ifindex, channel); } gboolean -nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, const guint8 *ssid, gsize len) +nm_platform_mesh_set_ssid(NMPlatform *self, int ifindex, const guint8 *ssid, gsize len) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (ssid != NULL, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(ssid != NULL, FALSE); - return klass->mesh_set_ssid (self, ifindex, ssid, len); + return klass->mesh_set_ssid(self, ifindex, ssid, len); } guint16 -nm_platform_wpan_get_pan_id (NMPlatform *self, int ifindex) +nm_platform_wpan_get_pan_id(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->wpan_get_pan_id (self, ifindex); + return klass->wpan_get_pan_id(self, ifindex); } gboolean -nm_platform_wpan_set_pan_id (NMPlatform *self, int ifindex, guint16 pan_id) +nm_platform_wpan_set_pan_id(NMPlatform *self, int ifindex, guint16 pan_id) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->wpan_set_pan_id (self, ifindex, pan_id); + return klass->wpan_set_pan_id(self, ifindex, pan_id); } guint16 -nm_platform_wpan_get_short_addr (NMPlatform *self, int ifindex) +nm_platform_wpan_get_short_addr(NMPlatform *self, int ifindex) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->wpan_get_short_addr (self, ifindex); + return klass->wpan_get_short_addr(self, ifindex); } gboolean -nm_platform_wpan_set_short_addr (NMPlatform *self, int ifindex, guint16 short_addr) +nm_platform_wpan_set_short_addr(NMPlatform *self, int ifindex, guint16 short_addr) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->wpan_set_short_addr (self, ifindex, short_addr); + return klass->wpan_set_short_addr(self, ifindex, short_addr); } gboolean -nm_platform_wpan_set_channel (NMPlatform *self, int ifindex, guint8 page, guint8 channel) +nm_platform_wpan_set_channel(NMPlatform *self, int ifindex, guint8 page, guint8 channel) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return klass->wpan_set_channel (self, ifindex, page, channel); + return klass->wpan_set_channel(self, ifindex, page, channel); } -#define TO_STRING_DEV_BUF_SIZE (5+15+1) +#define TO_STRING_DEV_BUF_SIZE (5 + 15 + 1) static const char * -_to_string_dev (NMPlatform *self, int ifindex, char *buf, size_t size) +_to_string_dev(NMPlatform *self, int ifindex, char *buf, size_t size) { - g_assert (buf && size >= TO_STRING_DEV_BUF_SIZE); + g_assert(buf && size >= TO_STRING_DEV_BUF_SIZE); - if (ifindex) { - const char *name = ifindex > 0 && self ? nm_platform_link_get_name (self, ifindex) : NULL; - char *buf2; + if (ifindex) { + const char *name = ifindex > 0 && self ? nm_platform_link_get_name(self, ifindex) : NULL; + char * buf2; - strcpy (buf, " dev "); - buf2 = buf + 5; - size -= 5; + strcpy(buf, " dev "); + buf2 = buf + 5; + size -= 5; - if (name) - g_strlcpy (buf2, name, size); - else - g_snprintf (buf2, size, "%d", ifindex); - } else - buf[0] = 0; + if (name) + g_strlcpy(buf2, name, size); + else + g_snprintf(buf2, size, "%d", ifindex); + } else + buf[0] = 0; - return buf; + return buf; } #define TO_STRING_IFA_FLAGS_BUF_SIZE 256 static const char * -_to_string_ifa_flags (guint32 ifa_flags, char *buf, gsize size) +_to_string_ifa_flags(guint32 ifa_flags, char *buf, gsize size) { #define S_FLAGS_PREFIX " flags " - nm_assert (buf && size >= TO_STRING_IFA_FLAGS_BUF_SIZE && size > NM_STRLEN (S_FLAGS_PREFIX)); - - if (!ifa_flags) - buf[0] = '\0'; - else { - nm_platform_addr_flags2str (ifa_flags, &buf[NM_STRLEN (S_FLAGS_PREFIX)], size - NM_STRLEN (S_FLAGS_PREFIX)); - if (buf[NM_STRLEN (S_FLAGS_PREFIX)] == '\0') - buf[0] = '\0'; - else - memcpy (buf, S_FLAGS_PREFIX, NM_STRLEN (S_FLAGS_PREFIX)); - } - return buf; + nm_assert(buf && size >= TO_STRING_IFA_FLAGS_BUF_SIZE && size > NM_STRLEN(S_FLAGS_PREFIX)); + + if (!ifa_flags) + buf[0] = '\0'; + else { + nm_platform_addr_flags2str(ifa_flags, + &buf[NM_STRLEN(S_FLAGS_PREFIX)], + size - NM_STRLEN(S_FLAGS_PREFIX)); + if (buf[NM_STRLEN(S_FLAGS_PREFIX)] == '\0') + buf[0] = '\0'; + else + memcpy(buf, S_FLAGS_PREFIX, NM_STRLEN(S_FLAGS_PREFIX)); + } + return buf; } /*****************************************************************************/ gboolean -nm_platform_ethtool_set_wake_on_lan (NMPlatform *self, int ifindex, NMSettingWiredWakeOnLan wol, const char *wol_password) +nm_platform_ethtool_set_wake_on_lan(NMPlatform * self, + int ifindex, + NMSettingWiredWakeOnLan wol, + const char * wol_password) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return nmp_utils_ethtool_set_wake_on_lan (ifindex, wol, wol_password); + return nmp_utils_ethtool_set_wake_on_lan(ifindex, wol, wol_password); } gboolean -nm_platform_ethtool_set_link_settings (NMPlatform *self, int ifindex, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex) +nm_platform_ethtool_set_link_settings(NMPlatform * self, + int ifindex, + gboolean autoneg, + guint32 speed, + NMPlatformLinkDuplexType duplex) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return nmp_utils_ethtool_set_link_settings (ifindex, autoneg, speed, duplex); + return nmp_utils_ethtool_set_link_settings(ifindex, autoneg, speed, duplex); } gboolean -nm_platform_ethtool_get_link_settings (NMPlatform *self, int ifindex, gboolean *out_autoneg, guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex) +nm_platform_ethtool_get_link_settings(NMPlatform * self, + int ifindex, + gboolean * out_autoneg, + guint32 * out_speed, + NMPlatformLinkDuplexType *out_duplex) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return nmp_utils_ethtool_get_link_settings (ifindex, out_autoneg, out_speed, out_duplex); + return nmp_utils_ethtool_get_link_settings(ifindex, out_autoneg, out_speed, out_duplex); } -NM_UTILS_LOOKUP_STR_DEFINE (nm_platform_link_duplex_type_to_string, NMPlatformLinkDuplexType, - NM_UTILS_LOOKUP_DEFAULT_WARN (NULL), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_LINK_DUPLEX_UNKNOWN, "unknown"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_LINK_DUPLEX_FULL, "full"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_LINK_DUPLEX_HALF, "half"), -); +NM_UTILS_LOOKUP_STR_DEFINE(nm_platform_link_duplex_type_to_string, + NMPlatformLinkDuplexType, + NM_UTILS_LOOKUP_DEFAULT_WARN(NULL), + NM_UTILS_LOOKUP_STR_ITEM(NM_PLATFORM_LINK_DUPLEX_UNKNOWN, "unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_PLATFORM_LINK_DUPLEX_FULL, "full"), + NM_UTILS_LOOKUP_STR_ITEM(NM_PLATFORM_LINK_DUPLEX_HALF, "half"), ); /*****************************************************************************/ NMEthtoolFeatureStates * -nm_platform_ethtool_get_link_features (NMPlatform *self, int ifindex) +nm_platform_ethtool_get_link_features(NMPlatform *self, int ifindex) { - _CHECK_SELF_NETNS (self, klass, netns, NULL); + _CHECK_SELF_NETNS(self, klass, netns, NULL); - g_return_val_if_fail (ifindex > 0, NULL); + g_return_val_if_fail(ifindex > 0, NULL); - return nmp_utils_ethtool_get_features (ifindex); + return nmp_utils_ethtool_get_features(ifindex); } gboolean -nm_platform_ethtool_set_features (NMPlatform *self, - int ifindex, - const NMEthtoolFeatureStates *features, - const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, - gboolean do_set /* or reset */) +nm_platform_ethtool_set_features( + NMPlatform * self, + int ifindex, + const NMEthtoolFeatureStates *features, + const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, + gboolean do_set /* or reset */) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return nmp_utils_ethtool_set_features (ifindex, features, requested, do_set); + return nmp_utils_ethtool_set_features(ifindex, features, requested, do_set); } gboolean -nm_platform_ethtool_get_link_coalesce (NMPlatform *self, - int ifindex, - NMEthtoolCoalesceState *coalesce) +nm_platform_ethtool_get_link_coalesce(NMPlatform * self, + int ifindex, + NMEthtoolCoalesceState *coalesce) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (coalesce, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(coalesce, FALSE); - return nmp_utils_ethtool_get_coalesce (ifindex, coalesce); + return nmp_utils_ethtool_get_coalesce(ifindex, coalesce); } gboolean -nm_platform_ethtool_set_coalesce (NMPlatform *self, - int ifindex, - const NMEthtoolCoalesceState *coalesce) +nm_platform_ethtool_set_coalesce(NMPlatform * self, + int ifindex, + const NMEthtoolCoalesceState *coalesce) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return nmp_utils_ethtool_set_coalesce (ifindex, coalesce); + return nmp_utils_ethtool_set_coalesce(ifindex, coalesce); } gboolean -nm_platform_ethtool_get_link_ring (NMPlatform *self, - int ifindex, - NMEthtoolRingState *ring) +nm_platform_ethtool_get_link_ring(NMPlatform *self, int ifindex, NMEthtoolRingState *ring) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (ring, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(ring, FALSE); - return nmp_utils_ethtool_get_ring (ifindex, ring); + return nmp_utils_ethtool_get_ring(ifindex, ring); } gboolean -nm_platform_ethtool_set_ring (NMPlatform *self, - int ifindex, - const NMEthtoolRingState *ring) +nm_platform_ethtool_set_ring(NMPlatform *self, int ifindex, const NMEthtoolRingState *ring) { - _CHECK_SELF_NETNS (self, klass, netns, FALSE); + _CHECK_SELF_NETNS(self, klass, netns, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); - return nmp_utils_ethtool_set_ring (ifindex, ring); + return nmp_utils_ethtool_set_ring(ifindex, ring); } /*****************************************************************************/ const NMDedupMultiHeadEntry * -nm_platform_lookup_all (NMPlatform *self, - NMPCacheIdType cache_id_type, - const NMPObject *obj) +nm_platform_lookup_all(NMPlatform *self, NMPCacheIdType cache_id_type, const NMPObject *obj) { - return nmp_cache_lookup_all (nm_platform_get_cache (self), - cache_id_type, - obj); + return nmp_cache_lookup_all(nm_platform_get_cache(self), cache_id_type, obj); } const NMDedupMultiEntry * -nm_platform_lookup_entry (NMPlatform *self, - NMPCacheIdType cache_id_type, - const NMPObject *obj) +nm_platform_lookup_entry(NMPlatform *self, NMPCacheIdType cache_id_type, const NMPObject *obj) { - return nmp_cache_lookup_entry_with_idx_type (nm_platform_get_cache (self), - cache_id_type, - obj); + return nmp_cache_lookup_entry_with_idx_type(nm_platform_get_cache(self), cache_id_type, obj); } const NMDedupMultiHeadEntry * -nm_platform_lookup (NMPlatform *self, - const NMPLookup *lookup) +nm_platform_lookup(NMPlatform *self, const NMPLookup *lookup) { - return nmp_cache_lookup (nm_platform_get_cache (self), - lookup); + return nmp_cache_lookup(nm_platform_get_cache(self), lookup); } gboolean -nm_platform_lookup_predicate_routes_main (const NMPObject *obj, - gpointer user_data) +nm_platform_lookup_predicate_routes_main(const NMPObject *obj, gpointer user_data) { - nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, - NMP_OBJECT_TYPE_IP6_ROUTE)); - return nm_platform_route_table_is_main (obj->ip_route.table_coerced); + nm_assert( + NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); + return nm_platform_route_table_is_main( + nm_platform_ip_route_get_effective_table(&obj->ip_route)); } gboolean -nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel (const NMPObject *obj, - gpointer user_data) +nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel(const NMPObject *obj, + gpointer user_data) { - nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, - NMP_OBJECT_TYPE_IP6_ROUTE)); - return nm_platform_route_table_is_main (obj->ip_route.table_coerced) - && obj->ip_route.rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL; + nm_assert( + NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); + return nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&obj->ip_route)) + && obj->ip_route.rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL; } /** @@ -3356,347 +3470,401 @@ nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel (const NMPObject *ob * Returns: the result of the lookup. */ GPtrArray * -nm_platform_lookup_clone (NMPlatform *self, - const NMPLookup *lookup, - NMPObjectPredicateFunc predicate, - gpointer user_data) +nm_platform_lookup_clone(NMPlatform * self, + const NMPLookup * lookup, + NMPObjectPredicateFunc predicate, + gpointer user_data) { - return nm_dedup_multi_objs_to_ptr_array_head (nm_platform_lookup (self, lookup), - (NMDedupMultiFcnSelectPredicate) predicate, - user_data); + return nm_dedup_multi_objs_to_ptr_array_head(nm_platform_lookup(self, lookup), + (NMDedupMultiFcnSelectPredicate) predicate, + user_data); } void -nm_platform_ip4_address_set_addr (NMPlatformIP4Address *addr, in_addr_t address, guint8 plen) +nm_platform_ip4_address_set_addr(NMPlatformIP4Address *addr, in_addr_t address, guint8 plen) { - nm_assert (plen <= 32); + nm_assert(plen <= 32); - addr->address = address; - addr->peer_address = address; - addr->plen = plen; + addr->address = address; + addr->peer_address = address; + addr->plen = plen; } const struct in6_addr * -nm_platform_ip6_address_get_peer (const NMPlatformIP6Address *addr) +nm_platform_ip6_address_get_peer(const NMPlatformIP6Address *addr) { - if ( IN6_IS_ADDR_UNSPECIFIED (&addr->peer_address) - || IN6_ARE_ADDR_EQUAL (&addr->peer_address, &addr->address)) - return &addr->address; - return &addr->peer_address; + if (IN6_IS_ADDR_UNSPECIFIED(&addr->peer_address) + || IN6_ARE_ADDR_EQUAL(&addr->peer_address, &addr->address)) + return &addr->address; + return &addr->peer_address; +} + +gboolean +nm_platform_ip6_address_match(const NMPlatformIP6Address *addr, NMPlatformMatchFlags match_flag) +{ + nm_assert(!NM_FLAGS_ANY( + match_flag, + ~(NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY))); + nm_assert(NM_FLAGS_ANY(match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY)); + nm_assert(NM_FLAGS_ANY(match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY)); + + if (IN6_IS_ADDR_LINKLOCAL(&addr->address)) { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL)) + return FALSE; + } else { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL)) + return FALSE; + } + + if (NM_FLAGS_HAS(addr->n_ifa_flags, IFA_F_DADFAILED)) { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE_DADFAILED)) + return FALSE; + } else if (NM_FLAGS_HAS(addr->n_ifa_flags, IFA_F_TENTATIVE) + && !NM_FLAGS_HAS(addr->n_ifa_flags, IFA_F_OPTIMISTIC)) { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) + return FALSE; + } else { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) + return FALSE; + } + + return TRUE; } gboolean -nm_platform_ip4_address_add (NMPlatform *self, - int ifindex, - in_addr_t address, - guint8 plen, - in_addr_t peer_address, - in_addr_t broadcast_address, - guint32 lifetime, - guint32 preferred, - guint32 flags, - const char *label) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (plen <= 32, FALSE); - g_return_val_if_fail (lifetime > 0, FALSE); - g_return_val_if_fail (preferred <= lifetime, FALSE); - g_return_val_if_fail (!label || strlen (label) < sizeof (((NMPlatformIP4Address *) NULL)->label), FALSE); - - if (_LOGD_ENABLED ()) { - NMPlatformIP4Address addr; - - addr = (NMPlatformIP4Address) { - .ifindex = ifindex, - .address = address, - .peer_address = peer_address, - .plen = plen, - .timestamp = 0, /* set it at zero, which to_string will treat as *now* */ - .lifetime = lifetime, - .preferred = preferred, - .n_ifa_flags = flags, - .broadcast_address = broadcast_address, - .use_ip4_broadcast_address = TRUE, - }; - if (label) - g_strlcpy (addr.label, label, sizeof (addr.label)); - - _LOG3D ("address: adding or updating IPv4 address: %s", nm_platform_ip4_address_to_string (&addr, NULL, 0)); - } - return klass->ip4_address_add (self, ifindex, address, plen, peer_address, broadcast_address, lifetime, preferred, flags, label); +nm_platform_ip4_address_add(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address, + in_addr_t broadcast_address, + guint32 lifetime, + guint32 preferred, + guint32 flags, + const char *label) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(plen <= 32, FALSE); + g_return_val_if_fail(lifetime > 0, FALSE); + g_return_val_if_fail(preferred <= lifetime, FALSE); + g_return_val_if_fail(!label || strlen(label) < sizeof(((NMPlatformIP4Address *) NULL)->label), + FALSE); + + if (_LOGD_ENABLED()) { + NMPlatformIP4Address addr; + + addr = (NMPlatformIP4Address){ + .ifindex = ifindex, + .address = address, + .peer_address = peer_address, + .plen = plen, + .timestamp = 0, /* set it at zero, which to_string will treat as *now* */ + .lifetime = lifetime, + .preferred = preferred, + .n_ifa_flags = flags, + .broadcast_address = broadcast_address, + .use_ip4_broadcast_address = TRUE, + }; + if (label) + g_strlcpy(addr.label, label, sizeof(addr.label)); + + _LOG3D("address: adding or updating IPv4 address: %s", + nm_platform_ip4_address_to_string(&addr, NULL, 0)); + } + return klass->ip4_address_add(self, + ifindex, + address, + plen, + peer_address, + broadcast_address, + lifetime, + preferred, + flags, + label); } gboolean -nm_platform_ip6_address_add (NMPlatform *self, - int ifindex, - struct in6_addr address, - guint8 plen, - struct in6_addr peer_address, - guint32 lifetime, - guint32 preferred, - guint32 flags) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (plen <= 128, FALSE); - g_return_val_if_fail (lifetime > 0, FALSE); - g_return_val_if_fail (preferred <= lifetime, FALSE); - - if (_LOGD_ENABLED ()) { - NMPlatformIP6Address addr = { 0 }; - - addr.ifindex = ifindex; - addr.address = address; - addr.peer_address = peer_address; - addr.plen = plen; - addr.timestamp = 0; /* set it to zero, which to_string will treat as *now* */ - addr.lifetime = lifetime; - addr.preferred = preferred; - addr.n_ifa_flags = flags; - - _LOG3D ("address: adding or updating IPv6 address: %s", nm_platform_ip6_address_to_string (&addr, NULL, 0)); - } - return klass->ip6_address_add (self, ifindex, address, plen, peer_address, lifetime, preferred, flags); +nm_platform_ip6_address_add(NMPlatform * self, + int ifindex, + struct in6_addr address, + guint8 plen, + struct in6_addr peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(plen <= 128, FALSE); + g_return_val_if_fail(lifetime > 0, FALSE); + g_return_val_if_fail(preferred <= lifetime, FALSE); + + if (_LOGD_ENABLED()) { + NMPlatformIP6Address addr = {0}; + + addr.ifindex = ifindex; + addr.address = address; + addr.peer_address = peer_address; + addr.plen = plen; + addr.timestamp = 0; /* set it to zero, which to_string will treat as *now* */ + addr.lifetime = lifetime; + addr.preferred = preferred; + addr.n_ifa_flags = flags; + + _LOG3D("address: adding or updating IPv6 address: %s", + nm_platform_ip6_address_to_string(&addr, NULL, 0)); + } + return klass + ->ip6_address_add(self, ifindex, address, plen, peer_address, lifetime, preferred, flags); } gboolean -nm_platform_ip4_address_delete (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address) +nm_platform_ip4_address_delete(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address) { - char str_dev[TO_STRING_DEV_BUF_SIZE]; - char b1[NM_UTILS_INET_ADDRSTRLEN]; - char b2[NM_UTILS_INET_ADDRSTRLEN]; - char str_peer[INET_ADDRSTRLEN + 50]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + char str_peer[INET_ADDRSTRLEN + 50]; - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (plen <= 32, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(plen <= 32, FALSE); - _LOG3D ("address: deleting IPv4 address %s/%d, %s%s", - _nm_utils_inet4_ntop (address, b1), - plen, - peer_address != address - ? nm_sprintf_buf (str_peer, - "peer %s, ", - _nm_utils_inet4_ntop (peer_address, b2)) - : "", - _to_string_dev (self, ifindex, str_dev, sizeof (str_dev))); - return klass->ip4_address_delete (self, ifindex, address, plen, peer_address); + _LOG3D("address: deleting IPv4 address %s/%d, %s%s", + _nm_utils_inet4_ntop(address, b1), + plen, + peer_address != address + ? nm_sprintf_buf(str_peer, "peer %s, ", _nm_utils_inet4_ntop(peer_address, b2)) + : "", + _to_string_dev(self, ifindex, str_dev, sizeof(str_dev))); + return klass->ip4_address_delete(self, ifindex, address, plen, peer_address); } gboolean -nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen) +nm_platform_ip6_address_delete(NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen) { - char str_dev[TO_STRING_DEV_BUF_SIZE]; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (plen <= 128, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(plen <= 128, FALSE); - _LOG3D ("address: deleting IPv6 address %s/%d, %s", - _nm_utils_inet6_ntop (&address, sbuf), plen, - _to_string_dev (self, ifindex, str_dev, sizeof (str_dev))); - return klass->ip6_address_delete (self, ifindex, address, plen); + _LOG3D("address: deleting IPv6 address %s/%d, %s", + _nm_utils_inet6_ntop(&address, sbuf), + plen, + _to_string_dev(self, ifindex, str_dev, sizeof(str_dev))); + return klass->ip6_address_delete(self, ifindex, address, plen); } const NMPlatformIP4Address * -nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, guint32 peer_address) +nm_platform_ip4_address_get(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address) { - NMPObject obj_id; - const NMPObject *obj; + NMPObject obj_id; + const NMPObject *obj; - _CHECK_SELF (self, klass, NULL); + _CHECK_SELF(self, klass, NULL); - g_return_val_if_fail (plen <= 32, NULL); + g_return_val_if_fail(plen <= 32, NULL); - nmp_object_stackinit_id_ip4_address (&obj_id, ifindex, address, plen, peer_address); - obj = nmp_cache_lookup_obj (nm_platform_get_cache (self), &obj_id); - nm_assert (!obj || nmp_object_is_visible (obj)); - return NMP_OBJECT_CAST_IP4_ADDRESS (obj); + nmp_object_stackinit_id_ip4_address(&obj_id, ifindex, address, plen, peer_address); + obj = nmp_cache_lookup_obj(nm_platform_get_cache(self), &obj_id); + nm_assert(!obj || nmp_object_is_visible(obj)); + return NMP_OBJECT_CAST_IP4_ADDRESS(obj); } const NMPlatformIP6Address * -nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address) +nm_platform_ip6_address_get(NMPlatform *self, int ifindex, const struct in6_addr *address) { - NMPObject obj_id; - const NMPObject *obj; + NMPObject obj_id; + const NMPObject *obj; + + _CHECK_SELF(self, klass, NULL); - _CHECK_SELF (self, klass, NULL); + nm_assert(address); - nmp_object_stackinit_id_ip6_address (&obj_id, ifindex, &address); - obj = nmp_cache_lookup_obj (nm_platform_get_cache (self), &obj_id); - nm_assert (!obj || nmp_object_is_visible (obj)); - return NMP_OBJECT_CAST_IP6_ADDRESS (obj); + nmp_object_stackinit_id_ip6_address(&obj_id, ifindex, address); + obj = nmp_cache_lookup_obj(nm_platform_get_cache(self), &obj_id); + nm_assert(!obj || nmp_object_is_visible(obj)); + return NMP_OBJECT_CAST_IP6_ADDRESS(obj); } static gboolean -_addr_array_clean_expired (int addr_family, int ifindex, GPtrArray *array, guint32 now, GHashTable **idx) +_addr_array_clean_expired(int addr_family, + int ifindex, + GPtrArray * array, + guint32 now, + GHashTable **idx) { - guint i; - gboolean any_addrs = FALSE; + guint i; + gboolean any_addrs = FALSE; - nm_assert_addr_family (addr_family); - nm_assert (ifindex > 0); - nm_assert (now > 0); + nm_assert_addr_family(addr_family); + nm_assert(ifindex > 0); + nm_assert(now > 0); - if (!array) - return FALSE; + if (!array) + return FALSE; - /* remove all addresses that are already expired. */ - for (i = 0; i < array->len; i++) { - const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS (array->pdata[i]); + /* remove all addresses that are already expired. */ + for (i = 0; i < array->len; i++) { + const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS(array->pdata[i]); #if NM_MORE_ASSERTS > 10 - nm_assert (a); - nm_assert (a->ifindex == ifindex); - { - const NMPObject *o = NMP_OBJECT_UP_CAST (a); - guint j; - - nm_assert (NMP_OBJECT_GET_CLASS (o)->addr_family == addr_family); - for (j = i + 1; j < array->len; j++) { - const NMPObject *o2 = array->pdata[j]; - - nm_assert (NMP_OBJECT_GET_TYPE (o) == NMP_OBJECT_GET_TYPE (o2)); - nm_assert (!nmp_object_id_equal (o, o2)); - } - } + nm_assert(a); + nm_assert(a->ifindex == ifindex); + { + const NMPObject *o = NMP_OBJECT_UP_CAST(a); + guint j; + + nm_assert(NMP_OBJECT_GET_CLASS(o)->addr_family == addr_family); + for (j = i + 1; j < array->len; j++) { + const NMPObject *o2 = array->pdata[j]; + + nm_assert(NMP_OBJECT_GET_TYPE(o) == NMP_OBJECT_GET_TYPE(o2)); + nm_assert(!nmp_object_id_equal(o, o2)); + } + } #endif - if ( addr_family == AF_INET6 - && NM_FLAGS_HAS (a->n_ifa_flags, IFA_F_TEMPORARY)) { - /* temporary addresses are never added explicitly by NetworkManager but - * kernel adds them via mngtempaddr flag. - * - * We drop them from this list. */ - goto clear_and_next; - } - - if (!nm_utils_lifetime_get (a->timestamp, a->lifetime, a->preferred, - now, NULL)) - goto clear_and_next; - - if (idx) { - if (G_UNLIKELY (!*idx)) { - *idx = g_hash_table_new ((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal); - } - if (!g_hash_table_add (*idx, (gpointer) NMP_OBJECT_UP_CAST (a))) - nm_assert_not_reached (); - } - any_addrs = TRUE; - continue; + if (addr_family == AF_INET6 && NM_FLAGS_HAS(a->n_ifa_flags, IFA_F_TEMPORARY)) { + /* temporary addresses are never added explicitly by NetworkManager but + * kernel adds them via mngtempaddr flag. + * + * We drop them from this list. */ + goto clear_and_next; + } + + if (!nm_utils_lifetime_get(a->timestamp, a->lifetime, a->preferred, now, NULL)) + goto clear_and_next; + + if (idx) { + if (G_UNLIKELY(!*idx)) { + *idx = g_hash_table_new((GHashFunc) nmp_object_id_hash, + (GEqualFunc) nmp_object_id_equal); + } + if (!g_hash_table_add(*idx, (gpointer) NMP_OBJECT_UP_CAST(a))) + nm_assert_not_reached(); + } + any_addrs = TRUE; + continue; clear_and_next: - nmp_object_unref (g_steal_pointer (&array->pdata[i])); - } + nmp_object_unref(g_steal_pointer(&array->pdata[i])); + } - return any_addrs; + return any_addrs; } static gboolean -ip4_addr_subnets_is_plain_address (const GPtrArray *addresses, gconstpointer needle) +ip4_addr_subnets_is_plain_address(const GPtrArray *addresses, gconstpointer needle) { - return needle >= (gconstpointer) &addresses->pdata[0] - && needle < (gconstpointer) &addresses->pdata[addresses->len]; + return needle >= (gconstpointer) &addresses->pdata[0] + && needle < (gconstpointer) &addresses->pdata[addresses->len]; } static const NMPObject ** -ip4_addr_subnets_addr_list_get (const GPtrArray *addr_list, guint idx) +ip4_addr_subnets_addr_list_get(const GPtrArray *addr_list, guint idx) { - nm_assert (addr_list); - nm_assert (addr_list->len > 1); - nm_assert (idx < addr_list->len); - nm_assert (addr_list->pdata[idx]); - nm_assert ( !(*((gpointer *) addr_list->pdata[idx])) - || NMP_OBJECT_CAST_IP4_ADDRESS (*((gpointer *) addr_list->pdata[idx]))); - nm_assert (idx == 0 || ip4_addr_subnets_addr_list_get (addr_list, idx - 1)); - return addr_list->pdata[idx]; + nm_assert(addr_list); + nm_assert(addr_list->len > 1); + nm_assert(idx < addr_list->len); + nm_assert(addr_list->pdata[idx]); + nm_assert(!(*((gpointer *) addr_list->pdata[idx])) + || NMP_OBJECT_CAST_IP4_ADDRESS(*((gpointer *) addr_list->pdata[idx]))); + nm_assert(idx == 0 || ip4_addr_subnets_addr_list_get(addr_list, idx - 1)); + return addr_list->pdata[idx]; } static void -ip4_addr_subnets_destroy_index (GHashTable *subnets, const GPtrArray *addresses) +ip4_addr_subnets_destroy_index(GHashTable *subnets, const GPtrArray *addresses) { - GHashTableIter iter; - gpointer p; + GHashTableIter iter; + gpointer p; - if (!subnets) - return; + if (!subnets) + return; - g_hash_table_iter_init (&iter, subnets); - while (g_hash_table_iter_next (&iter, NULL, &p)) { - if (!ip4_addr_subnets_is_plain_address (addresses, p)) - g_ptr_array_free ((GPtrArray *) p, TRUE); - } + g_hash_table_iter_init(&iter, subnets); + while (g_hash_table_iter_next(&iter, NULL, &p)) { + if (!ip4_addr_subnets_is_plain_address(addresses, p)) + g_ptr_array_free((GPtrArray *) p, TRUE); + } - g_hash_table_unref (subnets); + g_hash_table_unref(subnets); } static GHashTable * -ip4_addr_subnets_build_index (const GPtrArray *addresses, - gboolean consider_flags, - gboolean full_index) -{ - GHashTable *subnets; - guint i; - - nm_assert (addresses && addresses->len); - - subnets = g_hash_table_new (nm_direct_hash, NULL); - - /* Build a hash table of all addresses per subnet */ - for (i = 0; i < addresses->len; i++) { - const NMPlatformIP4Address *address; - gpointer p_address; - GPtrArray *addr_list; - guint32 net; - int position; - gpointer p; - - if (!addresses->pdata[i]) - continue; - - p_address = &addresses->pdata[i]; - address = NMP_OBJECT_CAST_IP4_ADDRESS (addresses->pdata[i]); - - net = address->address & _nm_utils_ip4_prefix_to_netmask (address->plen); - if (!g_hash_table_lookup_extended (subnets, GUINT_TO_POINTER (net), NULL, &p)) { - g_hash_table_insert (subnets, GUINT_TO_POINTER (net), p_address); - continue; - } - nm_assert (p); - - if (full_index) { - if (ip4_addr_subnets_is_plain_address (addresses, p)) { - addr_list = g_ptr_array_new (); - g_hash_table_insert (subnets, GUINT_TO_POINTER (net), addr_list); - g_ptr_array_add (addr_list, p); - } else - addr_list = p; - - if ( !consider_flags - || NM_FLAGS_HAS (address->n_ifa_flags, IFA_F_SECONDARY)) - position = -1; /* append */ - else - position = 0; /* prepend */ - g_ptr_array_insert (addr_list, position, p_address); - } else { - /* we only care about the primary. No need to track the secondaries - * as a GPtrArray. */ - nm_assert (ip4_addr_subnets_is_plain_address (addresses, p)); - if ( consider_flags - && !NM_FLAGS_HAS (address->n_ifa_flags, IFA_F_SECONDARY)) { - g_hash_table_insert (subnets, GUINT_TO_POINTER (net), p_address); - } - } - } - - return subnets; +ip4_addr_subnets_build_index(const GPtrArray *addresses, + gboolean consider_flags, + gboolean full_index) +{ + GHashTable *subnets; + guint i; + + nm_assert(addresses && addresses->len); + + subnets = g_hash_table_new(nm_direct_hash, NULL); + + /* Build a hash table of all addresses per subnet */ + for (i = 0; i < addresses->len; i++) { + const NMPlatformIP4Address *address; + gpointer p_address; + GPtrArray * addr_list; + guint32 net; + int position; + gpointer p; + + if (!addresses->pdata[i]) + continue; + + p_address = &addresses->pdata[i]; + address = NMP_OBJECT_CAST_IP4_ADDRESS(addresses->pdata[i]); + + net = address->address & _nm_utils_ip4_prefix_to_netmask(address->plen); + if (!g_hash_table_lookup_extended(subnets, GUINT_TO_POINTER(net), NULL, &p)) { + g_hash_table_insert(subnets, GUINT_TO_POINTER(net), p_address); + continue; + } + nm_assert(p); + + if (full_index) { + if (ip4_addr_subnets_is_plain_address(addresses, p)) { + addr_list = g_ptr_array_new(); + g_hash_table_insert(subnets, GUINT_TO_POINTER(net), addr_list); + g_ptr_array_add(addr_list, p); + } else + addr_list = p; + + if (!consider_flags || NM_FLAGS_HAS(address->n_ifa_flags, IFA_F_SECONDARY)) + position = -1; /* append */ + else + position = 0; /* prepend */ + g_ptr_array_insert(addr_list, position, p_address); + } else { + /* we only care about the primary. No need to track the secondaries + * as a GPtrArray. */ + nm_assert(ip4_addr_subnets_is_plain_address(addresses, p)); + if (consider_flags && !NM_FLAGS_HAS(address->n_ifa_flags, IFA_F_SECONDARY)) { + g_hash_table_insert(subnets, GUINT_TO_POINTER(net), p_address); + } + } + } + + return subnets; } /** @@ -3712,237 +3880,76 @@ ip4_addr_subnets_build_index (const GPtrArray *addresses, * Returns: %TRUE if the address is secondary, %FALSE otherwise */ static gboolean -ip4_addr_subnets_is_secondary (const NMPObject *address, - GHashTable *subnets, - const GPtrArray *addresses, - const GPtrArray **out_addr_list) -{ - const NMPlatformIP4Address *a; - const GPtrArray *addr_list; - gconstpointer p; - guint32 net; - const NMPObject **o; - - a = NMP_OBJECT_CAST_IP4_ADDRESS (address); - - net = a->address & _nm_utils_ip4_prefix_to_netmask (a->plen); - p = g_hash_table_lookup (subnets, GUINT_TO_POINTER (net)); - nm_assert (p); - if (!ip4_addr_subnets_is_plain_address (addresses, p)) { - addr_list = p; - nm_assert (addr_list->len > 1); - NM_SET_OUT (out_addr_list, addr_list); - o = ip4_addr_subnets_addr_list_get (addr_list, 0); - nm_assert (o && *o); - if (*o != address) - return TRUE; - } else { - NM_SET_OUT (out_addr_list, NULL); - return address != *((gconstpointer *) p); - } - return FALSE; -} - -/** - * nm_platform_ip4_address_sync: - * @self: platform instance - * @ifindex: Interface index - * @known_addresses: List of addresses. The list will be modified and only - * addresses that were successfully added will be kept in the list. - * That means, expired addresses and addresses that could not be added - * will be dropped. - * Hence, the input argument @known_addresses is also an output argument - * telling which addresses were successfully added. - * Addresses are removed by unrefing the instance via nmp_object_unref() - * and leaving a NULL tombstone. - * - * A convenience function to synchronize addresses for a specific interface - * with the least possible disturbance. It simply removes addresses that are - * not listed and adds addresses that are. - * - * Returns: %TRUE on success. - */ -gboolean -nm_platform_ip4_address_sync (NMPlatform *self, - int ifindex, - GPtrArray *known_addresses) -{ - gs_unref_ptrarray GPtrArray *plat_addresses = NULL; - const NMPlatformIP4Address *known_address; - gint32 now = nm_utils_get_monotonic_timestamp_sec (); - GHashTable *plat_subnets = NULL; - GHashTable *known_subnets = NULL; - gs_unref_hashtable GHashTable *known_addresses_idx = NULL; - guint i, j, len; - NMPLookup lookup; - guint32 lifetime, preferred; - guint32 ifa_flags; - - _CHECK_SELF (self, klass, FALSE); - - if (!_addr_array_clean_expired (AF_INET, ifindex, known_addresses, now, &known_addresses_idx)) - known_addresses = NULL; - - plat_addresses = nm_platform_lookup_clone (self, - nmp_lookup_init_object (&lookup, - NMP_OBJECT_TYPE_IP4_ADDRESS, - ifindex), - NULL, NULL); - if (plat_addresses) - plat_subnets = ip4_addr_subnets_build_index (plat_addresses, TRUE, TRUE); - - /* Delete unknown addresses */ - len = plat_addresses ? plat_addresses->len : 0; - for (i = 0; i < len; i++) { - const NMPObject *plat_obj; - const NMPlatformIP4Address *plat_address; - const GPtrArray *addr_list; - - plat_obj = plat_addresses->pdata[i]; - if (!plat_obj) { - /* Already deleted */ - continue; - } - - plat_address = NMP_OBJECT_CAST_IP4_ADDRESS (plat_obj); - - if (known_addresses) { - const NMPObject *o; - - o = g_hash_table_lookup (known_addresses_idx, plat_obj); - if (o) { - gboolean secondary; - - if (!known_subnets) - known_subnets = ip4_addr_subnets_build_index (known_addresses, FALSE, FALSE); - - secondary = ip4_addr_subnets_is_secondary (o, known_subnets, known_addresses, NULL); - if (secondary == NM_FLAGS_HAS (plat_address->n_ifa_flags, IFA_F_SECONDARY)) { - /* if we have an existing known-address, with matching secondary role, - * do not delete the platform-address. */ - continue; - } - } - } - - nm_platform_ip4_address_delete (self, ifindex, - plat_address->address, - plat_address->plen, - plat_address->peer_address); - - if ( !ip4_addr_subnets_is_secondary (plat_obj, plat_subnets, plat_addresses, &addr_list) - && addr_list) { - /* If we just deleted a primary addresses and there were - * secondary ones the kernel can do two things, depending on - * version and sysctl setting: delete also secondary addresses - * or promote a secondary to primary. Ensure that secondary - * addresses are deleted, so that we can start with a clean - * slate and add addresses in the right order. */ - for (j = 1; j < addr_list->len; j++) { - const NMPObject **o; - - o = ip4_addr_subnets_addr_list_get (addr_list, j); - nm_assert (o); - - if (*o) { - const NMPlatformIP4Address *a; - - a = NMP_OBJECT_CAST_IP4_ADDRESS (*o); - nm_platform_ip4_address_delete (self, ifindex, - a->address, - a->plen, - a->peer_address); - nmp_object_unref (*o); - *o = NULL; - } - } - } - } - ip4_addr_subnets_destroy_index (plat_subnets, plat_addresses); - - if (!known_addresses) - return TRUE; - - ip4_addr_subnets_destroy_index (known_subnets, known_addresses); - - ifa_flags = nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS) - ? IFA_F_NOPREFIXROUTE - : 0; - - /* Add missing addresses */ - for (i = 0; i < known_addresses->len; i++) { - const NMPObject *o; - - o = known_addresses->pdata[i]; - if (!o) - continue; - - known_address = NMP_OBJECT_CAST_IP4_ADDRESS (o); - - lifetime = nm_utils_lifetime_get (known_address->timestamp, known_address->lifetime, known_address->preferred, - now, &preferred); - if (!lifetime) - goto delete_and_next2; - - if (!nm_platform_ip4_address_add (self, - ifindex, - known_address->address, - known_address->plen, - known_address->peer_address, - nm_platform_ip4_broadcast_address_from_addr (known_address), - lifetime, - preferred, - ifa_flags, - known_address->label)) - goto delete_and_next2; - - continue; -delete_and_next2: - nmp_object_unref (o); - known_addresses->pdata[i] = NULL; - } - - return TRUE; +ip4_addr_subnets_is_secondary(const NMPObject * address, + GHashTable * subnets, + const GPtrArray * addresses, + const GPtrArray **out_addr_list) +{ + const NMPlatformIP4Address *a; + const GPtrArray * addr_list; + gconstpointer p; + guint32 net; + const NMPObject ** o; + + a = NMP_OBJECT_CAST_IP4_ADDRESS(address); + + net = a->address & _nm_utils_ip4_prefix_to_netmask(a->plen); + p = g_hash_table_lookup(subnets, GUINT_TO_POINTER(net)); + nm_assert(p); + if (!ip4_addr_subnets_is_plain_address(addresses, p)) { + addr_list = p; + nm_assert(addr_list->len > 1); + NM_SET_OUT(out_addr_list, addr_list); + o = ip4_addr_subnets_addr_list_get(addr_list, 0); + nm_assert(o && *o); + if (*o != address) + return TRUE; + } else { + NM_SET_OUT(out_addr_list, NULL); + return address != *((gconstpointer *) p); + } + return FALSE; } typedef enum { - IP6_ADDR_SCOPE_LOOPBACK, - IP6_ADDR_SCOPE_LINKLOCAL, - IP6_ADDR_SCOPE_SITELOCAL, - IP6_ADDR_SCOPE_OTHER, + IP6_ADDR_SCOPE_LOOPBACK, + IP6_ADDR_SCOPE_LINKLOCAL, + IP6_ADDR_SCOPE_SITELOCAL, + IP6_ADDR_SCOPE_OTHER, } IP6AddrScope; static IP6AddrScope -ip6_address_scope (const NMPlatformIP6Address *a) +ip6_address_scope(const NMPlatformIP6Address *a) { - if (IN6_IS_ADDR_LOOPBACK (&a->address)) - return IP6_ADDR_SCOPE_LOOPBACK; - if (IN6_IS_ADDR_LINKLOCAL (&a->address)) - return IP6_ADDR_SCOPE_LINKLOCAL; - if (IN6_IS_ADDR_SITELOCAL (&a->address)) - return IP6_ADDR_SCOPE_SITELOCAL; - return IP6_ADDR_SCOPE_OTHER; + if (IN6_IS_ADDR_LOOPBACK(&a->address)) + return IP6_ADDR_SCOPE_LOOPBACK; + if (IN6_IS_ADDR_LINKLOCAL(&a->address)) + return IP6_ADDR_SCOPE_LINKLOCAL; + if (IN6_IS_ADDR_SITELOCAL(&a->address)) + return IP6_ADDR_SCOPE_SITELOCAL; + return IP6_ADDR_SCOPE_OTHER; } static int -ip6_address_scope_cmp (gconstpointer p_a, gconstpointer p_b, gpointer increasing) +ip6_address_scope_cmp(gconstpointer p_a, gconstpointer p_b, gpointer increasing) { - const NMPlatformIP6Address *a; - const NMPlatformIP6Address *b; + const NMPlatformIP6Address *a; + const NMPlatformIP6Address *b; - if (!increasing) - NM_SWAP (p_a, p_b); + if (!increasing) + NM_SWAP(&p_a, &p_b); - a = NMP_OBJECT_CAST_IP6_ADDRESS (*(const NMPObject *const*) p_a); - b = NMP_OBJECT_CAST_IP6_ADDRESS (*(const NMPObject *const*) p_b); + a = NMP_OBJECT_CAST_IP6_ADDRESS(*(const NMPObject *const *) p_a); + b = NMP_OBJECT_CAST_IP6_ADDRESS(*(const NMPObject *const *) p_b); - NM_CMP_DIRECT (ip6_address_scope (a), ip6_address_scope (b)); - return 0; + NM_CMP_DIRECT(ip6_address_scope(a), ip6_address_scope(b)); + return 0; } /** - * nm_platform_ip6_address_sync: + * nm_platform_ip_address_sync: * @self: platform instance + * @addr_family: the address family AF_INET or AF_INET6. * @ifindex: Interface index * @known_addresses: List of addresses. The list will be modified and only * addresses that were successfully added will be kept in the list. @@ -3952,7 +3959,13 @@ ip6_address_scope_cmp (gconstpointer p_a, gconstpointer p_b, gpointer increasing * telling which addresses were successfully added. * Addresses are removed by unrefing the instance via nmp_object_unref() * and leaving a NULL tombstone. - * @full_sync: Also remove link-local and temporary addresses. + * @addresses_prune: (allow-none): the list of addresses to delete. + * If platform has such an address configured, it will be deleted + * at the beginning of the sync. Note that the array will be modified + * by the function. + * Note that the addresses must be properly sorted, by their priority. + * Create this list with nm_platform_ip_address_get_prune_list() which + * gets the sorting right. * * A convenience function to synchronize addresses for a specific interface * with the least possible disturbance. It simply removes addresses that are @@ -3961,286 +3974,446 @@ ip6_address_scope_cmp (gconstpointer p_a, gconstpointer p_b, gpointer increasing * Returns: %TRUE on success. */ gboolean -nm_platform_ip6_address_sync (NMPlatform *self, - int ifindex, - GPtrArray *known_addresses, - gboolean full_sync) -{ - gs_unref_ptrarray GPtrArray *plat_addresses = NULL; - gint32 now = nm_utils_get_monotonic_timestamp_sec (); - guint i_plat, i_know; - gs_unref_hashtable GHashTable *known_addresses_idx = NULL; - NMPLookup lookup; - guint32 ifa_flags; - - /* The order we want to enforce is only among addresses with the same - * scope, as the kernel keeps addresses sorted by scope. Therefore, - * apply the same sorting to known addresses, so that we don't try to - * unnecessary change the order of addresses with different scopes. */ - if (known_addresses) - g_ptr_array_sort_with_data (known_addresses, ip6_address_scope_cmp, GINT_TO_POINTER (TRUE)); - - if (!_addr_array_clean_expired (AF_INET6, ifindex, known_addresses, now, &known_addresses_idx)) - known_addresses = NULL; - - /* @plat_addresses is in decreasing priority order (highest priority addresses first), contrary to - * @known_addresses which is in increasing priority order (lowest priority addresses first). */ - plat_addresses = nm_platform_lookup_clone (self, - nmp_lookup_init_object (&lookup, - NMP_OBJECT_TYPE_IP6_ADDRESS, - ifindex), - NULL, NULL); - - if (plat_addresses) { - guint known_addresses_len; - IP6AddrScope cur_scope; - gboolean delete_remaining_addrs; - - g_ptr_array_sort_with_data (plat_addresses, ip6_address_scope_cmp, GINT_TO_POINTER (FALSE)); - - known_addresses_len = known_addresses ? known_addresses->len : 0; - - /* First, compare every address whether it is still a "known address", that is, whether - * to keep it or to delete it. - * - * If we don't find a matching valid address in @known_addresses, we will delete - * plat_addr. - * - * Certain addresses, like temporary addresses, are ignored by this function - * if not run with full_sync. These addresses are usually not managed by NetworkManager - * directly, or at least, they are not managed via nm_platform_ip6_address_sync(). - * Only in full_sync mode, we really want to get rid of them (usually, when we take - * the interface down). - * - * Note that we mark handled addresses by setting it to %NULL in @plat_addresses array. */ - for (i_plat = 0; i_plat < plat_addresses->len; i_plat++) { - const NMPObject *plat_obj = plat_addresses->pdata[i_plat]; - const NMPObject *know_obj; - const NMPlatformIP6Address *plat_addr = NMP_OBJECT_CAST_IP6_ADDRESS (plat_obj); - - if (NM_FLAGS_HAS (plat_addr->n_ifa_flags, IFA_F_TEMPORARY)) { - if (!full_sync) { - /* just mark as handled, without actually deleting the address. */ - goto clear_and_next; - } - } else if (known_addresses_idx) { - know_obj = g_hash_table_lookup (known_addresses_idx, plat_obj); - if ( know_obj - && plat_addr->plen == NMP_OBJECT_CAST_IP6_ADDRESS (know_obj)->plen) { - /* technically, plen is not part of the ID for IPv6 addresses and thus - * @plat_addr is essentially the same address as @know_addr (regrading - * its identity, not its other attributes). - * However, we cannot modify an existing addresses' plen without - * removing and readding it. Thus, only keep plat_addr, if the plen - * matches. - * - * keep this one, and continue */ - continue; - } - } - - nm_platform_ip6_address_delete (self, ifindex, plat_addr->address, plat_addr->plen); -clear_and_next: - nmp_object_unref (g_steal_pointer (&plat_addresses->pdata[i_plat])); - } - - /* Next, we must preserve the priority of the routes. That is, source address - * selection will choose addresses in the order as they are reported by kernel. - * Note that the order in @plat_addresses of the remaining matches is highest - * priority first. - * We need to compare this to the order of addresses with same scope in - * @known_addresses (which has lowest priority first). - * - * If we find a first discrepancy, we need to delete all remaining addresses - * with same scope from that point on, because below we must re-add all the - * addresses in the right order to get their priority right. */ - cur_scope = IP6_ADDR_SCOPE_LOOPBACK; - delete_remaining_addrs = FALSE; - i_plat = plat_addresses->len; - i_know = 0; - while (i_plat > 0) { - const NMPlatformIP6Address *plat_addr = NMP_OBJECT_CAST_IP6_ADDRESS (plat_addresses->pdata[--i_plat]); - IP6AddrScope plat_scope; - - if (!plat_addr) - continue; - - plat_scope = ip6_address_scope (plat_addr); - if (cur_scope != plat_scope) { - nm_assert (cur_scope < plat_scope); - delete_remaining_addrs = FALSE; - cur_scope = plat_scope; - } - - if (!delete_remaining_addrs) { - delete_remaining_addrs = TRUE; - for (; i_know < known_addresses_len; i_know++) { - const NMPlatformIP6Address *know_addr = NMP_OBJECT_CAST_IP6_ADDRESS (known_addresses->pdata[i_know]); - IP6AddrScope know_scope; - - if (!know_addr) - continue; - - know_scope = ip6_address_scope (know_addr); - if (know_scope < plat_scope) - continue; - - if (IN6_ARE_ADDR_EQUAL (&plat_addr->address, &know_addr->address)) { - /* we have a match. Mark address as handled. */ - i_know++; - delete_remaining_addrs = FALSE; - goto next_plat; - } - - /* plat_address has no match. Now delete_remaining_addrs is TRUE and we will - * delete all the remaining addresses with cur_scope. */ - break; - } - } - - nm_platform_ip6_address_delete (self, ifindex, plat_addr->address, plat_addr->plen); -next_plat: - ; - } - } - - if (!known_addresses) - return TRUE; - - ifa_flags = nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS) - ? IFA_F_NOPREFIXROUTE - : 0; - - /* Add missing addresses. New addresses are added by kernel with top - * priority. - */ - for (i_know = 0; i_know < known_addresses->len; i_know++) { - const NMPlatformIP6Address *known_address = NMP_OBJECT_CAST_IP6_ADDRESS (known_addresses->pdata[i_know]); - guint32 lifetime, preferred; - - if (!known_address) - continue; - - lifetime = nm_utils_lifetime_get (known_address->timestamp, known_address->lifetime, known_address->preferred, - now, &preferred); - - if (!nm_platform_ip6_address_add (self, ifindex, known_address->address, - known_address->plen, known_address->peer_address, - lifetime, preferred, - ifa_flags | known_address->n_ifa_flags)) - return FALSE; - } - - return TRUE; +nm_platform_ip_address_sync(NMPlatform *self, + int addr_family, + int ifindex, + GPtrArray * known_addresses, + GPtrArray * addresses_prune) +{ + const gint32 now = nm_utils_get_monotonic_timestamp_sec(); + const gboolean IS_IPv4 = NM_IS_IPv4(addr_family); + gs_unref_hashtable GHashTable *known_addresses_idx = NULL; + GPtrArray * plat_addresses; + GHashTable * known_subnets = NULL; + guint32 ifa_flags; + guint i_plat; + guint i_know; + guint i; + guint j; + + _CHECK_SELF(self, klass, FALSE); + + /* The order we want to enforce is only among addresses with the same + * scope, as the kernel keeps addresses sorted by scope. Therefore, + * apply the same sorting to known addresses, so that we don't try to + * unnecessary change the order of addresses with different scopes. */ + if (!IS_IPv4) { + if (known_addresses) + g_ptr_array_sort_with_data(known_addresses, + ip6_address_scope_cmp, + GINT_TO_POINTER(TRUE)); + } + + if (!_addr_array_clean_expired(addr_family, + ifindex, + known_addresses, + now, + &known_addresses_idx)) + known_addresses = NULL; + + /* @plat_addresses must be sorted in decreasing priority order (highest priority addresses first), contrary to + * @known_addresses which is in increasing priority order (lowest priority addresses first). */ + plat_addresses = addresses_prune; + + if (nm_g_ptr_array_len(plat_addresses) > 0) { + /* Delete unknown addresses */ + if (IS_IPv4) { + GHashTable *plat_subnets; + + plat_subnets = ip4_addr_subnets_build_index(plat_addresses, TRUE, TRUE); + + for (i = 0; i < plat_addresses->len; i++) { + const NMPObject * plat_obj; + const NMPlatformIP4Address *plat_address; + const GPtrArray * addr_list; + + plat_obj = plat_addresses->pdata[i]; + if (!plat_obj) { + /* Already deleted */ + continue; + } + + plat_address = NMP_OBJECT_CAST_IP4_ADDRESS(plat_obj); + + if (known_addresses) { + const NMPObject *o; + + o = g_hash_table_lookup(known_addresses_idx, plat_obj); + if (o) { + gboolean secondary; + + if (!known_subnets) + known_subnets = + ip4_addr_subnets_build_index(known_addresses, FALSE, FALSE); + + secondary = + ip4_addr_subnets_is_secondary(o, known_subnets, known_addresses, NULL); + if (secondary == NM_FLAGS_HAS(plat_address->n_ifa_flags, IFA_F_SECONDARY)) { + /* if we have an existing known-address, with matching secondary role, + * do not delete the platform-address. */ + continue; + } + } + } + + nm_platform_ip4_address_delete(self, + ifindex, + plat_address->address, + plat_address->plen, + plat_address->peer_address); + + if (!ip4_addr_subnets_is_secondary(plat_obj, + plat_subnets, + plat_addresses, + &addr_list) + && addr_list) { + /* If we just deleted a primary addresses and there were + * secondary ones the kernel can do two things, depending on + * version and sysctl setting: delete also secondary addresses + * or promote a secondary to primary. Ensure that secondary + * addresses are deleted, so that we can start with a clean + * slate and add addresses in the right order. */ + for (j = 1; j < addr_list->len; j++) { + const NMPObject **o; + + o = ip4_addr_subnets_addr_list_get(addr_list, j); + nm_assert(o); + + if (*o) { + const NMPlatformIP4Address *a; + + a = NMP_OBJECT_CAST_IP4_ADDRESS(*o); + nm_platform_ip4_address_delete(self, + ifindex, + a->address, + a->plen, + a->peer_address); + nmp_object_unref(*o); + *o = NULL; + } + } + } + } + ip4_addr_subnets_destroy_index(plat_subnets, plat_addresses); + } else { + guint known_addresses_len; + IP6AddrScope cur_scope; + gboolean delete_remaining_addrs; + + g_ptr_array_sort_with_data(plat_addresses, + ip6_address_scope_cmp, + GINT_TO_POINTER(FALSE)); + + known_addresses_len = known_addresses ? known_addresses->len : 0; + + /* First, compare every address whether it is still a "known address", that is, whether + * to keep it or to delete it. + * + * If we don't find a matching valid address in @known_addresses, we will delete + * plat_addr. + * + * Certain addresses, like temporary addresses, are ignored by this function + * if not run with full_sync. These addresses are usually not managed by NetworkManager + * directly, or at least, they are not managed via nm_platform_ip6_address_sync(). + * Only in full_sync mode, we really want to get rid of them (usually, when we take + * the interface down). + * + * Note that we mark handled addresses by setting it to %NULL in @plat_addresses array. */ + for (i_plat = 0; i_plat < plat_addresses->len; i_plat++) { + const NMPObject * plat_obj = plat_addresses->pdata[i_plat]; + const NMPObject * know_obj; + const NMPlatformIP6Address *plat_addr = NMP_OBJECT_CAST_IP6_ADDRESS(plat_obj); + + if (known_addresses_idx) { + know_obj = g_hash_table_lookup(known_addresses_idx, plat_obj); + if (know_obj + && plat_addr->plen == NMP_OBJECT_CAST_IP6_ADDRESS(know_obj)->plen) { + /* technically, plen is not part of the ID for IPv6 addresses and thus + * @plat_addr is essentially the same address as @know_addr (regrading + * its identity, not its other attributes). + * However, we cannot modify an existing addresses' plen without + * removing and readding it. Thus, only keep plat_addr, if the plen + * matches. + * + * keep this one, and continue */ + continue; + } + } + + nm_platform_ip6_address_delete(self, ifindex, plat_addr->address, plat_addr->plen); + nmp_object_unref(g_steal_pointer(&plat_addresses->pdata[i_plat])); + } + + /* Next, we must preserve the priority of the routes. That is, source address + * selection will choose addresses in the order as they are reported by kernel. + * Note that the order in @plat_addresses of the remaining matches is highest + * priority first. + * We need to compare this to the order of addresses with same scope in + * @known_addresses (which has lowest priority first). + * + * If we find a first discrepancy, we need to delete all remaining addresses + * with same scope from that point on, because below we must re-add all the + * addresses in the right order to get their priority right. */ + cur_scope = IP6_ADDR_SCOPE_LOOPBACK; + delete_remaining_addrs = FALSE; + i_plat = plat_addresses->len; + i_know = 0; + while (i_plat > 0) { + const NMPlatformIP6Address *plat_addr = + NMP_OBJECT_CAST_IP6_ADDRESS(plat_addresses->pdata[--i_plat]); + IP6AddrScope plat_scope; + + if (!plat_addr) + continue; + + plat_scope = ip6_address_scope(plat_addr); + if (cur_scope != plat_scope) { + nm_assert(cur_scope < plat_scope); + delete_remaining_addrs = FALSE; + cur_scope = plat_scope; + } + + if (!delete_remaining_addrs) { + delete_remaining_addrs = TRUE; + for (; i_know < known_addresses_len; i_know++) { + const NMPlatformIP6Address *know_addr = + NMP_OBJECT_CAST_IP6_ADDRESS(known_addresses->pdata[i_know]); + IP6AddrScope know_scope; + + if (!know_addr) + continue; + + know_scope = ip6_address_scope(know_addr); + if (know_scope < plat_scope) + continue; + + if (IN6_ARE_ADDR_EQUAL(&plat_addr->address, &know_addr->address)) { + /* we have a match. Mark address as handled. */ + i_know++; + delete_remaining_addrs = FALSE; + goto next_plat; + } + + /* plat_address has no match. Now delete_remaining_addrs is TRUE and we will + * delete all the remaining addresses with cur_scope. */ + break; + } + } + + nm_platform_ip6_address_delete(self, ifindex, plat_addr->address, plat_addr->plen); +next_plat:; + } + } + } + + if (!known_addresses) + return TRUE; + + if (IS_IPv4) + ip4_addr_subnets_destroy_index(known_subnets, known_addresses); + + ifa_flags = nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS) + ? IFA_F_NOPREFIXROUTE + : 0; + + /* Add missing addresses. New addresses are added by kernel with top + * priority. + */ + for (i_know = 0; i_know < known_addresses->len; i_know++) { + const NMPlatformIPXAddress *known_address; + const NMPObject * o; + guint32 lifetime; + guint32 preferred; + + o = known_addresses->pdata[i_know]; + if (!o) + continue; + + nm_assert(NMP_OBJECT_GET_TYPE(o) == NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4)); + + known_address = NMP_OBJECT_CAST_IPX_ADDRESS(o); + + lifetime = nm_utils_lifetime_get(known_address->ax.timestamp, + known_address->ax.lifetime, + known_address->ax.preferred, + now, + &preferred); + nm_assert(lifetime > 0); + + if (IS_IPv4) { + if (!nm_platform_ip4_address_add( + self, + ifindex, + known_address->a4.address, + known_address->a4.plen, + known_address->a4.peer_address, + nm_platform_ip4_broadcast_address_from_addr(&known_address->a4), + lifetime, + preferred, + ifa_flags, + known_address->a4.label)) { + /* ignore error, for unclear reasons. */ + } + } else { + if (!nm_platform_ip6_address_add(self, + ifindex, + known_address->a6.address, + known_address->a6.plen, + known_address->a6.peer_address, + lifetime, + preferred, + ifa_flags | known_address->a6.n_ifa_flags)) + return FALSE; + } + } + + return TRUE; } gboolean -nm_platform_ip_address_flush (NMPlatform *self, - int addr_family, - int ifindex) +nm_platform_ip_address_flush(NMPlatform *self, int addr_family, int ifindex) { - gboolean success = TRUE; + gboolean success = TRUE; - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - nm_assert (NM_IN_SET (addr_family, AF_UNSPEC, - AF_INET, - AF_INET6)); + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); - if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET)) - success &= nm_platform_ip4_address_sync (self, ifindex, NULL); - if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET6)) - success &= nm_platform_ip6_address_sync (self, ifindex, NULL, TRUE); - return success; + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) + success &= nm_platform_ip4_address_sync(self, ifindex, NULL); + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) + success &= nm_platform_ip6_address_sync(self, ifindex, NULL, TRUE); + return success; } /*****************************************************************************/ static gboolean -_err_inval_due_to_ipv6_tentative_pref_src (NMPlatform *self, const NMPObject *obj) +_err_inval_due_to_ipv6_tentative_pref_src(NMPlatform *self, const NMPObject *obj) +{ + const NMPlatformIP6Route * r; + const NMPlatformIP6Address *a; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(NMP_OBJECT_IS_VALID(obj)); + + /* trying to add an IPv6 route with pref-src fails, if the address is + * still tentative (rh#1452684). We need to hack around that. + * + * Detect it, by guessing whether that's the case. */ + + if (NMP_OBJECT_GET_TYPE(obj) != NMP_OBJECT_TYPE_IP6_ROUTE) + return FALSE; + + r = NMP_OBJECT_CAST_IP6_ROUTE(obj); + + /* we only allow this workaround for routes added manually by the user. */ + if (r->rt_source != NM_IP_CONFIG_SOURCE_USER) + return FALSE; + + if (IN6_IS_ADDR_UNSPECIFIED(&r->pref_src)) + return FALSE; + + a = nm_platform_ip6_address_get(self, r->ifindex, &r->pref_src); + if (!a) + return FALSE; + if (!NM_FLAGS_HAS(a->n_ifa_flags, IFA_F_TENTATIVE) + || NM_FLAGS_HAS(a->n_ifa_flags, IFA_F_DADFAILED)) + return FALSE; + + return TRUE; +} + +GPtrArray * +nm_platform_ip_address_get_prune_list(NMPlatform *self, + int addr_family, + int ifindex, + gboolean exclude_ipv6_temporary_addrs) { - const NMPlatformIP6Route *r; - const NMPlatformIP6Address *a; + const gboolean IS_IPv4 = NM_IS_IPv4(addr_family); + const NMDedupMultiHeadEntry *head_entry; + NMPLookup lookup; + GPtrArray * result; + CList * iter; - nm_assert (NM_IS_PLATFORM (self)); - nm_assert (NMP_OBJECT_IS_VALID (obj)); + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(NM_IS_IPv4(addr_family)), ifindex); - /* trying to add an IPv6 route with pref-src fails, if the address is - * still tentative (rh#1452684). We need to hack around that. - * - * Detect it, by guessing whether that's the case. */ + head_entry = nm_platform_lookup(self, &lookup); - if (NMP_OBJECT_GET_TYPE (obj) != NMP_OBJECT_TYPE_IP6_ROUTE) - return FALSE; + if (!head_entry) + return NULL; - r = NMP_OBJECT_CAST_IP6_ROUTE (obj); + result = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nmp_object_unref); - /* we only allow this workaround for routes added manually by the user. */ - if (r->rt_source != NM_IP_CONFIG_SOURCE_USER) - return FALSE; + c_list_for_each (iter, &head_entry->lst_entries_head) { + const NMPObject *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; - if (IN6_IS_ADDR_UNSPECIFIED (&r->pref_src)) - return FALSE; + if (!IS_IPv4) { + if (exclude_ipv6_temporary_addrs + && NM_FLAGS_HAS(NMP_OBJECT_CAST_IP_ADDRESS(obj)->n_ifa_flags, IFA_F_TEMPORARY)) + continue; + } - a = nm_platform_ip6_address_get (self, r->ifindex, r->pref_src); - if (!a) - return FALSE; - if ( !NM_FLAGS_HAS (a->n_ifa_flags, IFA_F_TENTATIVE) - || NM_FLAGS_HAS (a->n_ifa_flags, IFA_F_DADFAILED)) - return FALSE; + g_ptr_array_add(result, (gpointer) nmp_object_ref(obj)); + } - return TRUE; + if (result->len == 0) { + g_ptr_array_unref(result); + return NULL; + } + return result; } GPtrArray * -nm_platform_ip_route_get_prune_list (NMPlatform *self, - int addr_family, - int ifindex, - NMIPRouteTableSyncMode route_table_sync) -{ - NMPLookup lookup; - GPtrArray *routes_prune; - const NMDedupMultiHeadEntry *head_entry; - CList *iter; - - nm_assert (NM_IS_PLATFORM (self)); - nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - nm_assert (NM_IN_SET (route_table_sync, NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN, - NM_IP_ROUTE_TABLE_SYNC_MODE_FULL, - NM_IP_ROUTE_TABLE_SYNC_MODE_ALL)); - - nmp_lookup_init_object (&lookup, - addr_family == AF_INET - ? NMP_OBJECT_TYPE_IP4_ROUTE - : NMP_OBJECT_TYPE_IP6_ROUTE, - ifindex); - head_entry = nm_platform_lookup (self, &lookup); - if (!head_entry) - return NULL; - - routes_prune = g_ptr_array_new_full (head_entry->len, - (GDestroyNotify) nm_dedup_multi_obj_unref); - - c_list_for_each (iter, &head_entry->lst_entries_head) { - const NMPObject *obj = c_list_entry (iter, NMDedupMultiEntry, lst_entries)->obj; - - if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_FULL) { - if (nm_platform_route_table_uncoerce (NMP_OBJECT_CAST_IP_ROUTE (obj)->table_coerced, TRUE) == RT_TABLE_LOCAL) - continue; - } else if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN) { - if (!nm_platform_route_table_is_main (NMP_OBJECT_CAST_IP_ROUTE (obj)->table_coerced)) - continue; - } else - nm_assert (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_ALL); - - g_ptr_array_add (routes_prune, (gpointer) nmp_object_ref (obj)); - } - - if (routes_prune->len == 0) { - g_ptr_array_unref (routes_prune); - return NULL; - } - return routes_prune; +nm_platform_ip_route_get_prune_list(NMPlatform * self, + int addr_family, + int ifindex, + NMIPRouteTableSyncMode route_table_sync) +{ + NMPLookup lookup; + GPtrArray * routes_prune; + const NMDedupMultiHeadEntry *head_entry; + CList * iter; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + nm_assert(NM_IN_SET(route_table_sync, + NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN, + NM_IP_ROUTE_TABLE_SYNC_MODE_FULL, + NM_IP_ROUTE_TABLE_SYNC_MODE_ALL)); + + nmp_lookup_init_object(&lookup, + addr_family == AF_INET ? NMP_OBJECT_TYPE_IP4_ROUTE + : NMP_OBJECT_TYPE_IP6_ROUTE, + ifindex); + head_entry = nm_platform_lookup(self, &lookup); + if (!head_entry) + return NULL; + + routes_prune = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nm_dedup_multi_obj_unref); + + c_list_for_each (iter, &head_entry->lst_entries_head) { + const NMPObject *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; + + if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_FULL) { + if (nm_platform_ip_route_get_effective_table(NMP_OBJECT_CAST_IP_ROUTE(obj)) + == RT_TABLE_LOCAL) + continue; + } else if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN) { + if (!nm_platform_route_table_is_main( + nm_platform_ip_route_get_effective_table(NMP_OBJECT_CAST_IP_ROUTE(obj)))) + continue; + } else + nm_assert(route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_ALL); + + g_ptr_array_add(routes_prune, (gpointer) nmp_object_ref(obj)); + } + + if (routes_prune->len == 0) { + g_ptr_array_unref(routes_prune); + return NULL; + } + return routes_prune; } /** @@ -4261,288 +4434,319 @@ nm_platform_ip_route_get_prune_list (NMPlatform *self, * Returns: %TRUE on success. */ gboolean -nm_platform_ip_route_sync (NMPlatform *self, - int addr_family, - int ifindex, - GPtrArray *routes, - GPtrArray *routes_prune, - GPtrArray **out_temporary_not_available) -{ - const NMPlatformVTableRoute *vt; - gs_unref_hashtable GHashTable *routes_idx = NULL; - const NMPObject *conf_o; - const NMDedupMultiEntry *plat_entry; - guint i; - int i_type; - gboolean success = TRUE; - char sbuf1[sizeof (_nm_utils_to_string_buffer)]; - char sbuf2[sizeof (_nm_utils_to_string_buffer)]; - const gboolean IS_IPv4 = (addr_family == AF_INET); - - nm_assert (NM_IS_PLATFORM (self)); - nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - nm_assert (ifindex > 0); - - vt = &nm_platform_vtable_route.vx[IS_IPv4]; - - for (i_type = 0; routes && i_type < 2; i_type++) { - for (i = 0; i < routes->len; i++) { - int r, r2; - gboolean gateway_route_added = FALSE; - - conf_o = routes->pdata[i]; - -#define VTABLE_IS_DEVICE_ROUTE(vt, o) (vt->is_ip4 \ - ? (NMP_OBJECT_CAST_IP4_ROUTE (o)->gateway == 0) \ - : IN6_IS_ADDR_UNSPECIFIED (&NMP_OBJECT_CAST_IP6_ROUTE (o)->gateway) ) - - if ( (i_type == 0 && !VTABLE_IS_DEVICE_ROUTE (vt, conf_o)) - || (i_type == 1 && VTABLE_IS_DEVICE_ROUTE (vt, conf_o))) { - /* we add routes in two runs over @i_type. - * - * First device routes, then gateway routes. */ - continue; - } - - if (!routes_idx) { - routes_idx = g_hash_table_new ((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal); - } - if (!g_hash_table_insert (routes_idx, (gpointer) conf_o, (gpointer) conf_o)) { - _LOG3D ("route-sync: skip adding duplicate route %s", - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1))); - continue; - } - - if ( !IS_IPv4 - && NMP_OBJECT_CAST_IP6_ROUTE (conf_o)->metric == 0) { - /* User space cannot add routes with metric 0. However, kernel can, and we might track such - * routes in @route as they are present external. Skip them silently. */ - continue; - } - - plat_entry = nm_platform_lookup_entry (self, - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - conf_o); - if (plat_entry) { - const NMPObject *plat_o; - - plat_o = plat_entry->obj; - - if (vt->route_cmp (NMP_OBJECT_CAST_IPX_ROUTE (conf_o), - NMP_OBJECT_CAST_IPX_ROUTE (plat_o), - NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) == 0) - continue; - - /* we need to replace the existing route with a (slightly) different - * one. Delete it first. */ - if (!nm_platform_object_delete (self, plat_o)) { - /* ignore error. */ - } - } +nm_platform_ip_route_sync(NMPlatform *self, + int addr_family, + int ifindex, + GPtrArray * routes, + GPtrArray * routes_prune, + GPtrArray **out_temporary_not_available) +{ + const NMPlatformVTableRoute *vt; + gs_unref_hashtable GHashTable *routes_idx = NULL; + const NMPObject * conf_o; + const NMDedupMultiEntry * plat_entry; + guint i; + int i_type; + gboolean success = TRUE; + char sbuf1[sizeof(_nm_utils_to_string_buffer)]; + char sbuf2[sizeof(_nm_utils_to_string_buffer)]; + const gboolean IS_IPv4 = (addr_family == AF_INET); + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + nm_assert(ifindex > 0); + + vt = &nm_platform_vtable_route.vx[IS_IPv4]; + + for (i_type = 0; routes && i_type < 2; i_type++) { + for (i = 0; i < routes->len; i++) { + int r, r2; + gboolean gateway_route_added = FALSE; + + conf_o = routes->pdata[i]; + +#define VTABLE_IS_DEVICE_ROUTE(vt, o) \ + (vt->is_ip4 ? (NMP_OBJECT_CAST_IP4_ROUTE(o)->gateway == 0) \ + : IN6_IS_ADDR_UNSPECIFIED(&NMP_OBJECT_CAST_IP6_ROUTE(o)->gateway)) + + if ((i_type == 0 && !VTABLE_IS_DEVICE_ROUTE(vt, conf_o)) + || (i_type == 1 && VTABLE_IS_DEVICE_ROUTE(vt, conf_o))) { + /* we add routes in two runs over @i_type. + * + * First device routes, then gateway routes. */ + continue; + } + + if (!routes_idx) { + routes_idx = g_hash_table_new((GHashFunc) nmp_object_id_hash, + (GEqualFunc) nmp_object_id_equal); + } + if (!g_hash_table_insert(routes_idx, (gpointer) conf_o, (gpointer) conf_o)) { + _LOG3D("route-sync: skip adding duplicate route %s", + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1))); + continue; + } + + if (!IS_IPv4 + && nm_platform_ip6_route_get_effective_metric(NMP_OBJECT_CAST_IP6_ROUTE(conf_o)) + == 0) { + /* User space cannot add routes with metric 0. However, kernel can, and we might track such + * routes in @route as they are present external. Skip them silently. */ + continue; + } + + plat_entry = nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, conf_o); + if (plat_entry) { + const NMPObject *plat_o; + + plat_o = plat_entry->obj; + + if (vt->route_cmp(NMP_OBJECT_CAST_IPX_ROUTE(conf_o), + NMP_OBJECT_CAST_IPX_ROUTE(plat_o), + NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + == 0) + continue; + + /* we need to replace the existing route with a (slightly) different + * one. Delete it first. */ + if (!nm_platform_object_delete(self, plat_o)) { + /* ignore error. */ + } + } sync_route_add: - r = nm_platform_ip_route_add (self, - NMP_NLM_FLAG_APPEND - | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, - conf_o); - if (r < 0) { - if (r == -EEXIST) { - /* Don't fail for EEXIST. It's not clear that the existing route - * is identical to the one that we were about to add. However, - * above we should have deleted conflicting (non-identical) routes. */ - if (_LOGD_ENABLED ()) { - plat_entry = nm_platform_lookup_entry (self, - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - conf_o); - if (!plat_entry) { - _LOG3D ("route-sync: adding route %s failed with EEXIST, however we cannot find such a route", - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1))); - } else if (vt->route_cmp (NMP_OBJECT_CAST_IPX_ROUTE (conf_o), - NMP_OBJECT_CAST_IPX_ROUTE (plat_entry->obj), - NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) != 0) { - _LOG3D ("route-sync: adding route %s failed due to existing (different!) route %s", - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nmp_object_to_string (plat_entry->obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf2, sizeof (sbuf2))); - } - } - } else if (NMP_OBJECT_CAST_IP_ROUTE (conf_o)->rt_source < NM_IP_CONFIG_SOURCE_USER) { - _LOG3D ("route-sync: ignore failure to add IPv%c route: %s: %s", - vt->is_ip4 ? '4' : '6', - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_strerror (r)); - } else if ( r == -EINVAL - && out_temporary_not_available - && _err_inval_due_to_ipv6_tentative_pref_src (self, conf_o)) { - _LOG3D ("route-sync: ignore failure to add IPv6 route with tentative IPv6 pref-src: %s: %s", - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_strerror (r)); - if (!*out_temporary_not_available) - *out_temporary_not_available = g_ptr_array_new_full (0, (GDestroyNotify) nmp_object_unref); - g_ptr_array_add (*out_temporary_not_available, (gpointer) nmp_object_ref (conf_o)); - } else if ( !gateway_route_added - && ( ( r == -ENETUNREACH - && vt->is_ip4 - && !!NMP_OBJECT_CAST_IP4_ROUTE (conf_o)->gateway) - || ( r == -EHOSTUNREACH - && !vt->is_ip4 - && !IN6_IS_ADDR_UNSPECIFIED (&NMP_OBJECT_CAST_IP6_ROUTE (conf_o)->gateway)))) { - NMPObject oo; - - if (vt->is_ip4) { - const NMPlatformIP4Route *rt = NMP_OBJECT_CAST_IP4_ROUTE (conf_o); - - nmp_object_stackinit (&oo, - NMP_OBJECT_TYPE_IP4_ROUTE, - &((NMPlatformIP4Route) { - .ifindex = rt->ifindex, - .network = rt->gateway, - .plen = 32, - .metric = rt->metric, - .rt_source = rt->rt_source, - .table_coerced = rt->table_coerced, - })); - } else { - const NMPlatformIP6Route *rt = NMP_OBJECT_CAST_IP6_ROUTE (conf_o); - - nmp_object_stackinit (&oo, - NMP_OBJECT_TYPE_IP6_ROUTE, - &((NMPlatformIP6Route) { - .ifindex = rt->ifindex, - .network = rt->gateway, - .plen = 128, - .metric = rt->metric, - .rt_source = rt->rt_source, - .table_coerced = rt->table_coerced, - })); - } - - _LOG3D ("route-sync: failure to add IPv%c route: %s: %s; try adding direct route to gateway %s", - vt->is_ip4 ? '4' : '6', - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_strerror (r), - nmp_object_to_string (&oo, NMP_OBJECT_TO_STRING_PUBLIC, sbuf2, sizeof (sbuf2))); - - r2 = nm_platform_ip_route_add (self, - NMP_NLM_FLAG_APPEND - | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, - &oo); - - if (r2 < 0) { - _LOG3D ("route-sync: failure to add gateway IPv%c route: %s: %s", - vt->is_ip4 ? '4' : '6', - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_strerror (r2)); - } - - gateway_route_added = TRUE; - goto sync_route_add; - } else { - _LOG3W ("route-sync: failure to add IPv%c route: %s: %s", - vt->is_ip4 ? '4' : '6', - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_strerror (r)); - success = FALSE; - } - } - } - } - - if (routes_prune) { - for (i = 0; i < routes_prune->len; i++) { - const NMPObject *prune_o; - - prune_o = routes_prune->pdata[i]; - - nm_assert ( (addr_family == AF_INET && NMP_OBJECT_GET_TYPE (prune_o) == NMP_OBJECT_TYPE_IP4_ROUTE) - || (addr_family == AF_INET6 && NMP_OBJECT_GET_TYPE (prune_o) == NMP_OBJECT_TYPE_IP6_ROUTE)); - - if ( routes_idx - && g_hash_table_lookup (routes_idx, prune_o)) - continue; - - if (!nm_platform_lookup_entry (self, - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - prune_o)) - continue; - - if (!nm_platform_object_delete (self, prune_o)) { - /* ignore error... */ - } - } - } - - return success; + r = nm_platform_ip_route_add(self, + NMP_NLM_FLAG_APPEND + | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, + conf_o); + if (r < 0) { + if (r == -EEXIST) { + /* Don't fail for EEXIST. It's not clear that the existing route + * is identical to the one that we were about to add. However, + * above we should have deleted conflicting (non-identical) routes. */ + if (_LOGD_ENABLED()) { + plat_entry = + nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, conf_o); + if (!plat_entry) { + _LOG3D("route-sync: adding route %s failed with EEXIST, however we " + "cannot find such a route", + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1))); + } else if (vt->route_cmp(NMP_OBJECT_CAST_IPX_ROUTE(conf_o), + NMP_OBJECT_CAST_IPX_ROUTE(plat_entry->obj), + NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + != 0) { + _LOG3D("route-sync: adding route %s failed due to existing " + "(different!) route %s", + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nmp_object_to_string(plat_entry->obj, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf2, + sizeof(sbuf2))); + } + } + } else if (NMP_OBJECT_CAST_IP_ROUTE(conf_o)->rt_source < NM_IP_CONFIG_SOURCE_USER) { + _LOG3D("route-sync: ignore failure to add IPv%c route: %s: %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r)); + } else if (r == -EINVAL && out_temporary_not_available + && _err_inval_due_to_ipv6_tentative_pref_src(self, conf_o)) { + _LOG3D("route-sync: ignore failure to add IPv6 route with tentative IPv6 " + "pref-src: %s: %s", + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r)); + if (!*out_temporary_not_available) + *out_temporary_not_available = + g_ptr_array_new_full(0, (GDestroyNotify) nmp_object_unref); + g_ptr_array_add(*out_temporary_not_available, + (gpointer) nmp_object_ref(conf_o)); + } else if (!gateway_route_added + && ((r == -ENETUNREACH && vt->is_ip4 + && !!NMP_OBJECT_CAST_IP4_ROUTE(conf_o)->gateway) + || (r == -EHOSTUNREACH && !vt->is_ip4 + && !IN6_IS_ADDR_UNSPECIFIED( + &NMP_OBJECT_CAST_IP6_ROUTE(conf_o)->gateway)))) { + NMPObject oo; + + if (vt->is_ip4) { + const NMPlatformIP4Route *rt = NMP_OBJECT_CAST_IP4_ROUTE(conf_o); + + nmp_object_stackinit( + &oo, + NMP_OBJECT_TYPE_IP4_ROUTE, + &((NMPlatformIP4Route){ + .ifindex = rt->ifindex, + .network = rt->gateway, + .plen = 32, + .metric = nm_platform_ip4_route_get_effective_metric(rt), + .rt_source = rt->rt_source, + .table_coerced = nm_platform_ip_route_get_effective_table( + NM_PLATFORM_IP_ROUTE_CAST(rt)), + })); + } else { + const NMPlatformIP6Route *rt = NMP_OBJECT_CAST_IP6_ROUTE(conf_o); + + nmp_object_stackinit( + &oo, + NMP_OBJECT_TYPE_IP6_ROUTE, + &((NMPlatformIP6Route){ + .ifindex = rt->ifindex, + .network = rt->gateway, + .plen = 128, + .metric = nm_platform_ip6_route_get_effective_metric(rt), + .rt_source = rt->rt_source, + .table_coerced = nm_platform_ip_route_get_effective_table( + NM_PLATFORM_IP_ROUTE_CAST(rt)), + })); + } + + _LOG3D("route-sync: failure to add IPv%c route: %s: %s; try adding direct " + "route to gateway %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r), + nmp_object_to_string(&oo, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf2, + sizeof(sbuf2))); + + r2 = nm_platform_ip_route_add(self, + NMP_NLM_FLAG_APPEND + | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, + &oo); + + if (r2 < 0) { + _LOG3D("route-sync: failure to add gateway IPv%c route: %s: %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r2)); + } + + gateway_route_added = TRUE; + goto sync_route_add; + } else { + _LOG3W("route-sync: failure to add IPv%c route: %s: %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r)); + success = FALSE; + } + } + } + } + + if (routes_prune) { + for (i = 0; i < routes_prune->len; i++) { + const NMPObject *prune_o; + + prune_o = routes_prune->pdata[i]; + + nm_assert((addr_family == AF_INET + && NMP_OBJECT_GET_TYPE(prune_o) == NMP_OBJECT_TYPE_IP4_ROUTE) + || (addr_family == AF_INET6 + && NMP_OBJECT_GET_TYPE(prune_o) == NMP_OBJECT_TYPE_IP6_ROUTE)); + + if (routes_idx && g_hash_table_lookup(routes_idx, prune_o)) + continue; + + if (!nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, prune_o)) + continue; + + if (!nm_platform_object_delete(self, prune_o)) { + /* ignore error... */ + } + } + } + + return success; } gboolean -nm_platform_ip_route_flush (NMPlatform *self, - int addr_family, - int ifindex) +nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex) { - gboolean success = TRUE; + gboolean success = TRUE; - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - nm_assert (NM_IN_SET (addr_family, AF_UNSPEC, - AF_INET, - AF_INET6)); + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); - if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET)) { - gs_unref_ptrarray GPtrArray *routes_prune = NULL; + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { + gs_unref_ptrarray GPtrArray *routes_prune = NULL; - routes_prune = nm_platform_ip_route_get_prune_list (self, - AF_INET, - ifindex, - NM_IP_ROUTE_TABLE_SYNC_MODE_ALL); - success &= nm_platform_ip_route_sync (self, AF_INET, ifindex, NULL, routes_prune, NULL); - } - if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET6)) { - gs_unref_ptrarray GPtrArray *routes_prune = NULL; + routes_prune = nm_platform_ip_route_get_prune_list(self, + AF_INET, + ifindex, + NM_IP_ROUTE_TABLE_SYNC_MODE_ALL); + success &= nm_platform_ip_route_sync(self, AF_INET, ifindex, NULL, routes_prune, NULL); + } + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { + gs_unref_ptrarray GPtrArray *routes_prune = NULL; - routes_prune = nm_platform_ip_route_get_prune_list (self, - AF_INET6, - ifindex, - NM_IP_ROUTE_TABLE_SYNC_MODE_ALL); - success &= nm_platform_ip_route_sync (self, AF_INET6, ifindex, NULL, routes_prune, NULL); - } - return success; + routes_prune = nm_platform_ip_route_get_prune_list(self, + AF_INET6, + ifindex, + NM_IP_ROUTE_TABLE_SYNC_MODE_ALL); + success &= nm_platform_ip_route_sync(self, AF_INET6, ifindex, NULL, routes_prune, NULL); + } + return success; } /*****************************************************************************/ static guint8 -_ip_route_scope_inv_get_normalized (const NMPlatformIP4Route *route) -{ - /* in kernel, you cannot set scope to RT_SCOPE_NOWHERE (255). - * That means, in NM, we treat RT_SCOPE_NOWHERE as unset, and detect - * it based on the presence of the gateway. In other words, when adding - * a route with scope RT_SCOPE_NOWHERE (in NetworkManager) to kernel, - * the resulting scope will be either "link" or "universe" (depending - * on the gateway). - * - * Note that internally, we track @scope_inv is the inverse of scope, - * so that the default equals zero (~(RT_SCOPE_NOWHERE)). - **/ - if (route->scope_inv == 0) { - if (route->type_coerced == nm_platform_route_type_coerce (RTN_LOCAL)) - return nm_platform_route_scope_inv (RT_SCOPE_HOST); - else { - return nm_platform_route_scope_inv (!route->gateway - ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); - } - } - return route->scope_inv; +_ip_route_scope_inv_get_normalized(const NMPlatformIP4Route *route) +{ + /* in kernel, you cannot set scope to RT_SCOPE_NOWHERE (255). + * That means, in NM, we treat RT_SCOPE_NOWHERE as unset, and detect + * it based on the presence of the gateway. In other words, when adding + * a route with scope RT_SCOPE_NOWHERE (in NetworkManager) to kernel, + * the resulting scope will be either "link" or "universe" (depending + * on the gateway). + * + * Note that internally, we track @scope_inv is the inverse of scope, + * so that the default equals zero (~(RT_SCOPE_NOWHERE)). + **/ + if (route->scope_inv == 0) { + if (route->type_coerced == nm_platform_route_type_coerce(RTN_LOCAL)) + return nm_platform_route_scope_inv(RT_SCOPE_HOST); + else { + return nm_platform_route_scope_inv(!route->gateway ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); + } + } + return route->scope_inv; } static guint8 -_route_pref_normalize (guint8 pref) +_route_pref_normalize(guint8 pref) { - /* for kernel (and ICMPv6) pref can only have one of 3 values. Normalize. */ - return NM_IN_SET (pref, NM_ICMPV6_ROUTER_PREF_LOW, - NM_ICMPV6_ROUTER_PREF_HIGH) - ? pref - : NM_ICMPV6_ROUTER_PREF_MEDIUM; + /* for kernel (and ICMPv6) pref can only have one of 3 values. Normalize. */ + return NM_IN_SET(pref, NM_ICMPV6_ROUTER_PREF_LOW, NM_ICMPV6_ROUTER_PREF_HIGH) + ? pref + : NM_ICMPV6_ROUTER_PREF_MEDIUM; } /** @@ -4559,340 +4763,328 @@ _route_pref_normalize (guint8 pref) * compare equal with NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL. */ void -nm_platform_ip_route_normalize (int addr_family, - NMPlatformIPRoute *route) -{ - NMPlatformIP4Route *r4; - NMPlatformIP6Route *r6; - - switch (addr_family) { - case AF_INET: - r4 = (NMPlatformIP4Route *) route; - r4->table_coerced = nm_platform_route_table_coerce (nm_platform_route_table_uncoerce (r4->table_coerced, TRUE)); - r4->network = nm_utils_ip4_address_clear_host_address (r4->network, r4->plen); - r4->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (r4->rt_source); - r4->scope_inv = _ip_route_scope_inv_get_normalized (r4); - break; - case AF_INET6: - r6 = (NMPlatformIP6Route *) route; - r6->table_coerced = nm_platform_route_table_coerce (nm_platform_route_table_uncoerce (r6->table_coerced, TRUE)); - nm_utils_ip6_address_clear_host_address (&r6->network, &r6->network, r6->plen); - r6->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (r6->rt_source), - nm_utils_ip6_address_clear_host_address (&r6->src, &r6->src, r6->src_plen); - break; - default: - nm_assert_not_reached (); - break; - } +nm_platform_ip_route_normalize(int addr_family, NMPlatformIPRoute *route) +{ + NMPlatformIP4Route *r4; + NMPlatformIP6Route *r6; + + route->table_coerced = + nm_platform_route_table_coerce(nm_platform_ip_route_get_effective_table(route)); + route->table_any = FALSE; + + route->rt_source = nmp_utils_ip_config_source_round_trip_rtprot(route->rt_source); + + switch (addr_family) { + case AF_INET: + r4 = (NMPlatformIP4Route *) route; + route->metric = nm_platform_ip4_route_get_effective_metric(r4); + route->metric_any = FALSE; + r4->network = nm_utils_ip4_address_clear_host_address(r4->network, r4->plen); + r4->scope_inv = _ip_route_scope_inv_get_normalized(r4); + break; + case AF_INET6: + r6 = (NMPlatformIP6Route *) route; + route->metric = nm_platform_ip6_route_get_effective_metric(r6); + route->metric_any = FALSE; + nm_utils_ip6_address_clear_host_address(&r6->network, &r6->network, r6->plen); + nm_utils_ip6_address_clear_host_address(&r6->src, &r6->src, r6->src_plen); + break; + default: + nm_assert_not_reached(); + break; + } } static int -_ip_route_add (NMPlatform *self, - NMPNlmFlags flags, - int addr_family, - gconstpointer route) +_ip_route_add(NMPlatform *self, NMPNlmFlags flags, int addr_family, gconstpointer route) { - char sbuf[sizeof (_nm_utils_to_string_buffer)]; - int ifindex; + char sbuf[sizeof(_nm_utils_to_string_buffer)]; + int ifindex; - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF(self, klass, FALSE); - nm_assert (route); - nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + nm_assert(route); + nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); - ifindex = ((const NMPlatformIPRoute *) route)->ifindex; - _LOG3D ("route: %-10s IPv%c route: %s", - _nmp_nlm_flag_to_string (flags & NMP_NLM_FLAG_FMASK), - nm_utils_addr_family_to_char (addr_family), - addr_family == AF_INET - ? nm_platform_ip4_route_to_string (route, sbuf, sizeof (sbuf)) - : nm_platform_ip6_route_to_string (route, sbuf, sizeof (sbuf))); + ifindex = ((const NMPlatformIPRoute *) route)->ifindex; + _LOG3D("route: %-10s IPv%c route: %s", + _nmp_nlm_flag_to_string(flags & NMP_NLM_FLAG_FMASK), + nm_utils_addr_family_to_char(addr_family), + addr_family == AF_INET ? nm_platform_ip4_route_to_string(route, sbuf, sizeof(sbuf)) + : nm_platform_ip6_route_to_string(route, sbuf, sizeof(sbuf))); - return klass->ip_route_add (self, flags, addr_family, route); + return klass->ip_route_add(self, flags, addr_family, route); } int -nm_platform_ip_route_add (NMPlatform *self, - NMPNlmFlags flags, - const NMPObject *route) +nm_platform_ip_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPObject *route) { - int addr_family; + int addr_family; - switch (NMP_OBJECT_GET_TYPE (route)) { - case NMP_OBJECT_TYPE_IP4_ROUTE: - addr_family = AF_INET; - break; - case NMP_OBJECT_TYPE_IP6_ROUTE: - addr_family = AF_INET6; - break; - default: - g_return_val_if_reached (FALSE); - } + switch (NMP_OBJECT_GET_TYPE(route)) { + case NMP_OBJECT_TYPE_IP4_ROUTE: + addr_family = AF_INET; + break; + case NMP_OBJECT_TYPE_IP6_ROUTE: + addr_family = AF_INET6; + break; + default: + g_return_val_if_reached(FALSE); + } - return _ip_route_add (self, flags, addr_family, NMP_OBJECT_CAST_IP_ROUTE (route)); + return _ip_route_add(self, flags, addr_family, NMP_OBJECT_CAST_IP_ROUTE(route)); } int -nm_platform_ip4_route_add (NMPlatform *self, - NMPNlmFlags flags, - const NMPlatformIP4Route *route) +nm_platform_ip4_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP4Route *route) { - return _ip_route_add (self, flags, AF_INET, route); + return _ip_route_add(self, flags, AF_INET, route); } int -nm_platform_ip6_route_add (NMPlatform *self, - NMPNlmFlags flags, - const NMPlatformIP6Route *route) +nm_platform_ip6_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP6Route *route) { - return _ip_route_add (self, flags, AF_INET6, route); + return _ip_route_add(self, flags, AF_INET6, route); } gboolean -nm_platform_object_delete (NMPlatform *self, - const NMPObject *obj) -{ - int ifindex; - - _CHECK_SELF (self, klass, FALSE); - - switch (NMP_OBJECT_GET_TYPE (obj)) { - case NMP_OBJECT_TYPE_ROUTING_RULE: - _LOGD ("%s: delete %s", - NMP_OBJECT_GET_CLASS (obj)->obj_type_name, - nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - break; - case NMP_OBJECT_TYPE_IP4_ROUTE: - case NMP_OBJECT_TYPE_IP6_ROUTE: - case NMP_OBJECT_TYPE_QDISC: - case NMP_OBJECT_TYPE_TFILTER: - ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj)->ifindex; - _LOG3D ("%s: delete %s", - NMP_OBJECT_GET_CLASS (obj)->obj_type_name, - nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - break; - default: - g_return_val_if_reached (FALSE); - } - - return klass->object_delete (self, obj); +nm_platform_object_delete(NMPlatform *self, const NMPObject *obj) +{ + int ifindex; + + _CHECK_SELF(self, klass, FALSE); + + switch (NMP_OBJECT_GET_TYPE(obj)) { + case NMP_OBJECT_TYPE_ROUTING_RULE: + _LOGD("%s: delete %s", + NMP_OBJECT_GET_CLASS(obj)->obj_type_name, + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + break; + case NMP_OBJECT_TYPE_IP4_ROUTE: + case NMP_OBJECT_TYPE_IP6_ROUTE: + case NMP_OBJECT_TYPE_QDISC: + case NMP_OBJECT_TYPE_TFILTER: + ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj)->ifindex; + _LOG3D("%s: delete %s", + NMP_OBJECT_GET_CLASS(obj)->obj_type_name, + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + break; + default: + g_return_val_if_reached(FALSE); + } + + return klass->object_delete(self, obj); } /*****************************************************************************/ int -nm_platform_ip_route_get (NMPlatform *self, - int addr_family, - gconstpointer address /* in_addr_t or struct in6_addr */, - int oif_ifindex, - NMPObject **out_route) -{ - nm_auto_nmpobj NMPObject *route = NULL; - int result; - char buf[NM_UTILS_INET_ADDRSTRLEN]; - char buf_oif[64]; - - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (address, -NME_BUG); - g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, - AF_INET6), -NME_BUG); - - _LOGT ("route: get IPv%c route for: %s%s", - nm_utils_addr_family_to_char (addr_family), - inet_ntop (addr_family, address, buf, sizeof (buf)), - oif_ifindex > 0 ? nm_sprintf_buf (buf_oif, " oif %d", oif_ifindex) : ""); - - if (!klass->ip_route_get) - result = -NME_PL_OPNOTSUPP; - else { - result = klass->ip_route_get (self, - addr_family, - address, - oif_ifindex, - &route); - } - - if (result < 0) { - nm_assert (!route); - _LOGW ("route: get IPv%c route for: %s failed with %s", - nm_utils_addr_family_to_char (addr_family), - inet_ntop (addr_family, address, buf, sizeof (buf)), - nm_strerror (result)); - } else { - nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (route), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); - nm_assert (!NMP_OBJECT_IS_STACKINIT (route)); - nm_assert (route->parent._ref_count == 1); - _LOGD ("route: get IPv%c route for: %s succeeded: %s", - nm_utils_addr_family_to_char (addr_family), - inet_ntop (addr_family, address, buf, sizeof (buf)), - nmp_object_to_string (route, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - NM_SET_OUT (out_route, g_steal_pointer (&route)); - } - return result; +nm_platform_ip_route_get(NMPlatform * self, + int addr_family, + gconstpointer address /* in_addr_t or struct in6_addr */, + int oif_ifindex, + NMPObject ** out_route) +{ + nm_auto_nmpobj NMPObject *route = NULL; + int result; + char buf[NM_UTILS_INET_ADDRSTRLEN]; + char buf_oif[64]; + + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(address, -NME_BUG); + g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), -NME_BUG); + + _LOGT("route: get IPv%c route for: %s%s", + nm_utils_addr_family_to_char(addr_family), + inet_ntop(addr_family, address, buf, sizeof(buf)), + oif_ifindex > 0 ? nm_sprintf_buf(buf_oif, " oif %d", oif_ifindex) : ""); + + if (!klass->ip_route_get) + result = -NME_PL_OPNOTSUPP; + else { + result = klass->ip_route_get(self, addr_family, address, oif_ifindex, &route); + } + + if (result < 0) { + nm_assert(!route); + _LOGW("route: get IPv%c route for: %s failed with %s", + nm_utils_addr_family_to_char(addr_family), + inet_ntop(addr_family, address, buf, sizeof(buf)), + nm_strerror(result)); + } else { + nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(route), + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); + nm_assert(!NMP_OBJECT_IS_STACKINIT(route)); + nm_assert(route->parent._ref_count == 1); + _LOGD("route: get IPv%c route for: %s succeeded: %s", + nm_utils_addr_family_to_char(addr_family), + inet_ntop(addr_family, address, buf, sizeof(buf)), + nmp_object_to_string(route, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + NM_SET_OUT(out_route, g_steal_pointer(&route)); + } + return result; } /*****************************************************************************/ -#define IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS ((int) 1500) -#define IP4_DEV_ROUTE_BLACKLIST_GC_TIMEOUT_S ((int) (((IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS + 999) * 3) / 1000)) +#define IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS ((int) 1500) +#define IP4_DEV_ROUTE_BLACKLIST_GC_TIMEOUT_S \ + ((int) (((IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS + 999) * 3) / 1000)) static gint64 -_ip4_dev_route_blacklist_timeout_ms_get (gint64 timeout_msec) +_ip4_dev_route_blacklist_timeout_ms_get(gint64 timeout_msec) { - return timeout_msec >> 1; + return timeout_msec >> 1; } static gint64 -_ip4_dev_route_blacklist_timeout_ms_marked (gint64 timeout_msec) +_ip4_dev_route_blacklist_timeout_ms_marked(gint64 timeout_msec) { - return !!(timeout_msec & ((gint64) 1)); + return !!(timeout_msec & ((gint64) 1)); } static gboolean -_ip4_dev_route_blacklist_check_cb (gpointer user_data) +_ip4_dev_route_blacklist_check_cb(gpointer user_data) { - NMPlatform *self = user_data; - NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE (self); - GHashTableIter iter; - const NMPObject *p_obj; - gint64 *p_timeout_ms; - gint64 now_ms; + NMPlatform * self = user_data; + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + GHashTableIter iter; + const NMPObject * p_obj; + gint64 * p_timeout_ms; + gint64 now_ms; - priv->ip4_dev_route_blacklist_check_id = 0; + priv->ip4_dev_route_blacklist_check_id = 0; again: - if (!priv->ip4_dev_route_blacklist_hash) - goto out; + if (!priv->ip4_dev_route_blacklist_hash) + goto out; - now_ms = nm_utils_get_monotonic_timestamp_msec (); + now_ms = nm_utils_get_monotonic_timestamp_msec(); - g_hash_table_iter_init (&iter, priv->ip4_dev_route_blacklist_hash); - while (g_hash_table_iter_next (&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) { - if (!_ip4_dev_route_blacklist_timeout_ms_marked (*p_timeout_ms)) - continue; + g_hash_table_iter_init(&iter, priv->ip4_dev_route_blacklist_hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) { + if (!_ip4_dev_route_blacklist_timeout_ms_marked(*p_timeout_ms)) + continue; - /* unmark because we checked it. */ - *p_timeout_ms = *p_timeout_ms & ~((gint64) 1); + /* unmark because we checked it. */ + *p_timeout_ms = *p_timeout_ms & ~((gint64) 1); - if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get (*p_timeout_ms)) - continue; + if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get(*p_timeout_ms)) + continue; - if (!nm_platform_lookup_entry (self, - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - p_obj)) - continue; + if (!nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, p_obj)) + continue; - _LOGT ("ip4-dev-route: delete %s", - nmp_object_to_string (p_obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - nm_platform_object_delete (self, p_obj); - goto again; - } + _LOGT("ip4-dev-route: delete %s", + nmp_object_to_string(p_obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + nm_platform_object_delete(self, p_obj); + goto again; + } out: - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static void -_ip4_dev_route_blacklist_check_schedule (NMPlatform *self) +_ip4_dev_route_blacklist_check_schedule(NMPlatform *self) { - NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE (self); + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); - if (!priv->ip4_dev_route_blacklist_check_id) { - priv->ip4_dev_route_blacklist_check_id = g_idle_add_full (G_PRIORITY_HIGH, - _ip4_dev_route_blacklist_check_cb, - self, - NULL); - } + if (!priv->ip4_dev_route_blacklist_check_id) { + priv->ip4_dev_route_blacklist_check_id = + g_idle_add_full(G_PRIORITY_HIGH, _ip4_dev_route_blacklist_check_cb, self, NULL); + } } static void -_ip4_dev_route_blacklist_notify_route (NMPlatform *self, - const NMPObject *obj) +_ip4_dev_route_blacklist_notify_route(NMPlatform *self, const NMPObject *obj) { - NMPlatformPrivate *priv; - const NMPObject *p_obj; - gint64 *p_timeout_ms; - gint64 now_ms; + NMPlatformPrivate *priv; + const NMPObject * p_obj; + gint64 * p_timeout_ms; + gint64 now_ms; - nm_assert (NM_IS_PLATFORM (self)); - nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_IP4_ROUTE); + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_IP4_ROUTE); - priv = NM_PLATFORM_GET_PRIVATE (self); + priv = NM_PLATFORM_GET_PRIVATE(self); - nm_assert (priv->ip4_dev_route_blacklist_gc_timeout_id); + nm_assert(priv->ip4_dev_route_blacklist_gc_timeout_id); - if (!g_hash_table_lookup_extended (priv->ip4_dev_route_blacklist_hash, - obj, - (gpointer *) &p_obj, - (gpointer *) &p_timeout_ms)) - return; + if (!g_hash_table_lookup_extended(priv->ip4_dev_route_blacklist_hash, + obj, + (gpointer *) &p_obj, + (gpointer *) &p_timeout_ms)) + return; - now_ms = nm_utils_get_monotonic_timestamp_msec (); - if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get (*p_timeout_ms)) { - /* already expired. Wait for gc. */ - return; - } + now_ms = nm_utils_get_monotonic_timestamp_msec(); + if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get(*p_timeout_ms)) { + /* already expired. Wait for gc. */ + return; + } - if (_ip4_dev_route_blacklist_timeout_ms_marked (*p_timeout_ms)) { - nm_assert (priv->ip4_dev_route_blacklist_check_id); - return; - } + if (_ip4_dev_route_blacklist_timeout_ms_marked(*p_timeout_ms)) { + nm_assert(priv->ip4_dev_route_blacklist_check_id); + return; + } - /* We cannot delete it right away because we are in the process of receiving netlink messages. - * It may be possible to do so, but complicated and error prone. - * - * Instead, we mark the entry and schedule an idle action (with high priority). */ - *p_timeout_ms = (*p_timeout_ms) | ((gint64) 1); - _ip4_dev_route_blacklist_check_schedule (self); + /* We cannot delete it right away because we are in the process of receiving netlink messages. + * It may be possible to do so, but complicated and error prone. + * + * Instead, we mark the entry and schedule an idle action (with high priority). */ + *p_timeout_ms = (*p_timeout_ms) | ((gint64) 1); + _ip4_dev_route_blacklist_check_schedule(self); } static gboolean -_ip4_dev_route_blacklist_gc_timeout_handle (gpointer user_data) +_ip4_dev_route_blacklist_gc_timeout_handle(gpointer user_data) { - NMPlatform *self = user_data; - NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE (self); - GHashTableIter iter; - const NMPObject *p_obj; - gint64 *p_timeout_ms; - gint64 now_ms; + NMPlatform * self = user_data; + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + GHashTableIter iter; + const NMPObject * p_obj; + gint64 * p_timeout_ms; + gint64 now_ms; - nm_assert (priv->ip4_dev_route_blacklist_gc_timeout_id); + nm_assert(priv->ip4_dev_route_blacklist_gc_timeout_id); - now_ms = nm_utils_get_monotonic_timestamp_msec (); + now_ms = nm_utils_get_monotonic_timestamp_msec(); - g_hash_table_iter_init (&iter, priv->ip4_dev_route_blacklist_hash); - while (g_hash_table_iter_next (&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) { - if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get (*p_timeout_ms)) { - _LOGT ("ip4-dev-route: cleanup %s", - nmp_object_to_string (p_obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - g_hash_table_iter_remove (&iter); - } - } + g_hash_table_iter_init(&iter, priv->ip4_dev_route_blacklist_hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) { + if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get(*p_timeout_ms)) { + _LOGT("ip4-dev-route: cleanup %s", + nmp_object_to_string(p_obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + g_hash_table_iter_remove(&iter); + } + } - _ip4_dev_route_blacklist_schedule (self); - return G_SOURCE_CONTINUE; + _ip4_dev_route_blacklist_schedule(self); + return G_SOURCE_CONTINUE; } static void -_ip4_dev_route_blacklist_schedule (NMPlatform *self) -{ - NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE (self); - - if ( !priv->ip4_dev_route_blacklist_hash - || g_hash_table_size (priv->ip4_dev_route_blacklist_hash) == 0) { - nm_clear_pointer (&priv->ip4_dev_route_blacklist_hash, g_hash_table_unref); - nm_clear_g_source (&priv->ip4_dev_route_blacklist_gc_timeout_id); - } else { - if (!priv->ip4_dev_route_blacklist_gc_timeout_id) { - /* this timeout is only to garbage collect the expired entries from priv->ip4_dev_route_blacklist_hash. - * It can run infrequently, and it doesn't hurt if expired entries linger around a bit - * longer then necessary. */ - priv->ip4_dev_route_blacklist_gc_timeout_id = g_timeout_add_seconds (IP4_DEV_ROUTE_BLACKLIST_GC_TIMEOUT_S, - _ip4_dev_route_blacklist_gc_timeout_handle, - self); - } - } +_ip4_dev_route_blacklist_schedule(NMPlatform *self) +{ + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + + if (!priv->ip4_dev_route_blacklist_hash + || g_hash_table_size(priv->ip4_dev_route_blacklist_hash) == 0) { + nm_clear_pointer(&priv->ip4_dev_route_blacklist_hash, g_hash_table_unref); + nm_clear_g_source(&priv->ip4_dev_route_blacklist_gc_timeout_id); + } else { + if (!priv->ip4_dev_route_blacklist_gc_timeout_id) { + /* this timeout is only to garbage collect the expired entries from priv->ip4_dev_route_blacklist_hash. + * It can run infrequently, and it doesn't hurt if expired entries linger around a bit + * longer then necessary. */ + priv->ip4_dev_route_blacklist_gc_timeout_id = + g_timeout_add_seconds(IP4_DEV_ROUTE_BLACKLIST_GC_TIMEOUT_S, + _ip4_dev_route_blacklist_gc_timeout_handle, + self); + } + } } /** @@ -4920,116 +5112,116 @@ _ip4_dev_route_blacklist_schedule (NMPlatform *self) * routes as well. */ void -nm_platform_ip4_dev_route_blacklist_set (NMPlatform *self, - int ifindex, - GPtrArray *ip4_dev_route_blacklist) -{ - NMPlatformPrivate *priv; - GHashTableIter iter; - const NMPObject *p_obj; - guint i; - gint64 timeout_msec; - gint64 timeout_msec_val; - gint64 *p_timeout_ms; - gboolean needs_check = FALSE; - - nm_assert (NM_IS_PLATFORM (self)); - nm_assert (ifindex > 0); - - priv = NM_PLATFORM_GET_PRIVATE (self); - - /* first, expire all for current ifindex... */ - if (priv->ip4_dev_route_blacklist_hash) { - g_hash_table_iter_init (&iter, priv->ip4_dev_route_blacklist_hash); - while (g_hash_table_iter_next (&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) { - if (NMP_OBJECT_CAST_IP4_ROUTE (p_obj)->ifindex == ifindex) { - /* we could g_hash_table_iter_remove(&iter) the current entry. - * Instead, just expire it and let _ip4_dev_route_blacklist_gc_timeout_handle() - * handle it. - * - * The assumption is, that ip4_dev_route_blacklist contains the very same entry - * again, with a new timeout. So, we can un-expire it below. */ - *p_timeout_ms = 0; - } - } - } - - if ( ip4_dev_route_blacklist - && ip4_dev_route_blacklist->len > 0) { - - if (!priv->ip4_dev_route_blacklist_hash) { - priv->ip4_dev_route_blacklist_hash = g_hash_table_new_full ((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal, - (GDestroyNotify) nmp_object_unref, - nm_g_slice_free_fcn_gint64); - } - - timeout_msec = nm_utils_get_monotonic_timestamp_msec () + IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS; - timeout_msec_val = (timeout_msec << 1) | ((gint64) 1); - for (i = 0; i < ip4_dev_route_blacklist->len; i++) { - const NMPObject *o; - - needs_check = TRUE; - o = ip4_dev_route_blacklist->pdata[i]; - if (g_hash_table_lookup_extended (priv->ip4_dev_route_blacklist_hash, - o, - (gpointer *) &p_obj, - (gpointer *) &p_timeout_ms)) { - if (nmp_object_equal (p_obj, o)) { - /* un-expire and reuse the entry. */ - _LOGT ("ip4-dev-route: register %s (update)", - nmp_object_to_string (p_obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - *p_timeout_ms = timeout_msec_val; - continue; - } - } - - _LOGT ("ip4-dev-route: register %s", - nmp_object_to_string (o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - p_timeout_ms = g_slice_new (gint64); - *p_timeout_ms = timeout_msec_val; - g_hash_table_replace (priv->ip4_dev_route_blacklist_hash, - (gpointer) nmp_object_ref (o), - p_timeout_ms); - } - } - - _ip4_dev_route_blacklist_schedule (self); - - if (needs_check) - _ip4_dev_route_blacklist_check_schedule (self); +nm_platform_ip4_dev_route_blacklist_set(NMPlatform *self, + int ifindex, + GPtrArray * ip4_dev_route_blacklist) +{ + NMPlatformPrivate *priv; + GHashTableIter iter; + const NMPObject * p_obj; + guint i; + gint64 timeout_msec; + gint64 timeout_msec_val; + gint64 * p_timeout_ms; + gboolean needs_check = FALSE; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(ifindex > 0); + + /* TODO: the blacklist should be maintained by NML3Cfg. */ + + priv = NM_PLATFORM_GET_PRIVATE(self); + + /* first, expire all for current ifindex... */ + if (priv->ip4_dev_route_blacklist_hash) { + g_hash_table_iter_init(&iter, priv->ip4_dev_route_blacklist_hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) { + if (NMP_OBJECT_CAST_IP4_ROUTE(p_obj)->ifindex == ifindex) { + /* we could g_hash_table_iter_remove(&iter) the current entry. + * Instead, just expire it and let _ip4_dev_route_blacklist_gc_timeout_handle() + * handle it. + * + * The assumption is, that ip4_dev_route_blacklist contains the very same entry + * again, with a new timeout. So, we can un-expire it below. */ + *p_timeout_ms = 0; + } + } + } + + if (ip4_dev_route_blacklist && ip4_dev_route_blacklist->len > 0) { + if (!priv->ip4_dev_route_blacklist_hash) { + priv->ip4_dev_route_blacklist_hash = + g_hash_table_new_full((GHashFunc) nmp_object_id_hash, + (GEqualFunc) nmp_object_id_equal, + (GDestroyNotify) nmp_object_unref, + nm_g_slice_free_fcn_gint64); + } + + timeout_msec = nm_utils_get_monotonic_timestamp_msec() + IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS; + timeout_msec_val = (timeout_msec << 1) | ((gint64) 1); + for (i = 0; i < ip4_dev_route_blacklist->len; i++) { + const NMPObject *o; + + needs_check = TRUE; + o = ip4_dev_route_blacklist->pdata[i]; + if (g_hash_table_lookup_extended(priv->ip4_dev_route_blacklist_hash, + o, + (gpointer *) &p_obj, + (gpointer *) &p_timeout_ms)) { + if (nmp_object_equal(p_obj, o)) { + /* un-expire and reuse the entry. */ + _LOGT("ip4-dev-route: register %s (update)", + nmp_object_to_string(p_obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + *p_timeout_ms = timeout_msec_val; + continue; + } + } + + _LOGT("ip4-dev-route: register %s", + nmp_object_to_string(o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + p_timeout_ms = g_slice_new(gint64); + *p_timeout_ms = timeout_msec_val; + g_hash_table_replace(priv->ip4_dev_route_blacklist_hash, + (gpointer) nmp_object_ref(o), + p_timeout_ms); + } + } + + _ip4_dev_route_blacklist_schedule(self); + + if (needs_check) + _ip4_dev_route_blacklist_check_schedule(self); } /*****************************************************************************/ int -nm_platform_routing_rule_add (NMPlatform *self, - NMPNlmFlags flags, - const NMPlatformRoutingRule *routing_rule) +nm_platform_routing_rule_add(NMPlatform * self, + NMPNlmFlags flags, + const NMPlatformRoutingRule *routing_rule) { - _CHECK_SELF (self, klass, -NME_BUG); + _CHECK_SELF(self, klass, -NME_BUG); - g_return_val_if_fail (routing_rule, -NME_BUG); + g_return_val_if_fail(routing_rule, -NME_BUG); - _LOGD ("routing-rule: adding or updating: %s", nm_platform_routing_rule_to_string (routing_rule, NULL, 0)); - return klass->routing_rule_add (self, flags, routing_rule); + _LOGD("routing-rule: adding or updating: %s", + nm_platform_routing_rule_to_string(routing_rule, NULL, 0)); + return klass->routing_rule_add(self, flags, routing_rule); } /*****************************************************************************/ int -nm_platform_qdisc_add (NMPlatform *self, - NMPNlmFlags flags, - const NMPlatformQdisc *qdisc) +nm_platform_qdisc_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformQdisc *qdisc) { - int ifindex = qdisc->ifindex; - _CHECK_SELF (self, klass, -NME_BUG); + int ifindex = qdisc->ifindex; + _CHECK_SELF(self, klass, -NME_BUG); - /* Note: @qdisc must not be copied or kept alive because the lifetime of qdisc.kind - * is undefined. */ + /* Note: @qdisc must not be copied or kept alive because the lifetime of qdisc.kind + * is undefined. */ - _LOG3D ("adding or updating a qdisc: %s", nm_platform_qdisc_to_string (qdisc, NULL, 0)); - return klass->qdisc_add (self, flags, qdisc); + _LOG3D("adding or updating a qdisc: %s", nm_platform_qdisc_to_string(qdisc, NULL, 0)); + return klass->qdisc_add(self, flags, qdisc); } /** @@ -5047,98 +5239,92 @@ nm_platform_qdisc_add (NMPlatform *self, * Returns: %TRUE on success. */ gboolean -nm_platform_qdisc_sync (NMPlatform *self, - int ifindex, - GPtrArray *known_qdiscs) -{ - gs_unref_ptrarray GPtrArray *plat_qdiscs = NULL; - NMPLookup lookup; - guint i; - gboolean success = TRUE; - gs_unref_hashtable GHashTable *known_qdiscs_idx = NULL; - - nm_assert (NM_IS_PLATFORM (self)); - nm_assert (ifindex > 0); - - known_qdiscs_idx = g_hash_table_new ((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal); - if (known_qdiscs) { - for (i = 0; i < known_qdiscs->len; i++) { - const NMPObject *q = g_ptr_array_index (known_qdiscs, i); - - if (!g_hash_table_insert (known_qdiscs_idx, (gpointer) q, (gpointer) q)) { - _LOGW ("duplicate qdisc %s", nm_platform_qdisc_to_string (&q->qdisc, NULL, 0)); - return FALSE; - } - - } - } - - plat_qdiscs = nm_platform_lookup_clone (self, - nmp_lookup_init_object (&lookup, - NMP_OBJECT_TYPE_QDISC, - ifindex), - NULL, NULL); - if (plat_qdiscs) { - for (i = 0; i < plat_qdiscs->len; i++) { - const NMPObject *p = g_ptr_array_index (plat_qdiscs, i); - const NMPObject *k; - - /* look up known qdisc with same parent */ - k = g_hash_table_lookup (known_qdiscs_idx, p); - - if (k) { - const NMPlatformQdisc *qdisc_k = NMP_OBJECT_CAST_QDISC (k); - const NMPlatformQdisc *qdisc_p = NMP_OBJECT_CAST_QDISC (p); - - /* check other fields */ - if ( nm_platform_qdisc_cmp_full (qdisc_k, qdisc_p, FALSE) != 0 - || ( qdisc_k->handle != qdisc_p->handle - && qdisc_k != 0)) { - k = NULL; - } - } - - if (k) { - g_hash_table_remove (known_qdiscs_idx, k); - } else { - /* can't delete qdisc with zero handle */ - if (TC_H_MAJ (p->qdisc.handle) != 0) { - success &= nm_platform_object_delete (self, p); - } - } - } - } - - if (known_qdiscs) { - for (i = 0; i < known_qdiscs->len; i++) { - const NMPObject *q = g_ptr_array_index (known_qdiscs, i); - - if (g_hash_table_contains (known_qdiscs_idx, q)) { - success &= (nm_platform_qdisc_add (self, NMP_NLM_FLAG_ADD, - NMP_OBJECT_CAST_QDISC (q)) >= 0); - } - } - } - - return success; +nm_platform_qdisc_sync(NMPlatform *self, int ifindex, GPtrArray *known_qdiscs) +{ + gs_unref_ptrarray GPtrArray *plat_qdiscs = NULL; + NMPLookup lookup; + guint i; + gboolean success = TRUE; + gs_unref_hashtable GHashTable *known_qdiscs_idx = NULL; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(ifindex > 0); + + known_qdiscs_idx = + g_hash_table_new((GHashFunc) nmp_object_id_hash, (GEqualFunc) nmp_object_id_equal); + if (known_qdiscs) { + for (i = 0; i < known_qdiscs->len; i++) { + const NMPObject *q = g_ptr_array_index(known_qdiscs, i); + + if (!g_hash_table_insert(known_qdiscs_idx, (gpointer) q, (gpointer) q)) { + _LOGW("duplicate qdisc %s", nm_platform_qdisc_to_string(&q->qdisc, NULL, 0)); + return FALSE; + } + } + } + + plat_qdiscs = + nm_platform_lookup_clone(self, + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_QDISC, ifindex), + NULL, + NULL); + if (plat_qdiscs) { + for (i = 0; i < plat_qdiscs->len; i++) { + const NMPObject *p = g_ptr_array_index(plat_qdiscs, i); + const NMPObject *k; + + /* look up known qdisc with same parent */ + k = g_hash_table_lookup(known_qdiscs_idx, p); + + if (k) { + const NMPlatformQdisc *qdisc_k = NMP_OBJECT_CAST_QDISC(k); + const NMPlatformQdisc *qdisc_p = NMP_OBJECT_CAST_QDISC(p); + + /* check other fields */ + if (nm_platform_qdisc_cmp_full(qdisc_k, qdisc_p, FALSE) != 0 + || (qdisc_k->handle != qdisc_p->handle && qdisc_k != 0)) { + k = NULL; + } + } + + if (k) { + g_hash_table_remove(known_qdiscs_idx, k); + } else { + /* can't delete qdisc with zero handle */ + if (TC_H_MAJ(p->qdisc.handle) != 0) { + success &= nm_platform_object_delete(self, p); + } + } + } + } + + if (known_qdiscs) { + for (i = 0; i < known_qdiscs->len; i++) { + const NMPObject *q = g_ptr_array_index(known_qdiscs, i); + + if (g_hash_table_contains(known_qdiscs_idx, q)) { + success &= + (nm_platform_qdisc_add(self, NMP_NLM_FLAG_ADD, NMP_OBJECT_CAST_QDISC(q)) >= 0); + } + } + } + + return success; } /*****************************************************************************/ int -nm_platform_tfilter_add (NMPlatform *self, - NMPNlmFlags flags, - const NMPlatformTfilter *tfilter) +nm_platform_tfilter_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformTfilter *tfilter) { - int ifindex = tfilter->ifindex; - _CHECK_SELF (self, klass, -NME_BUG); + int ifindex = tfilter->ifindex; + _CHECK_SELF(self, klass, -NME_BUG); - /* Note: @tfilter must not be copied or kept alive because the lifetime of tfilter.kind - * and tfilter.action.kind is undefined. */ + /* Note: @tfilter must not be copied or kept alive because the lifetime of tfilter.kind + * and tfilter.action.kind is undefined. */ - _LOG3D ("adding or updating a tfilter: %s", nm_platform_tfilter_to_string (tfilter, NULL, 0)); - return klass->tfilter_add (self, flags, tfilter); + _LOG3D("adding or updating a tfilter: %s", nm_platform_tfilter_to_string(tfilter, NULL, 0)); + return klass->tfilter_add(self, flags, tfilter); } /** @@ -5156,110 +5342,120 @@ nm_platform_tfilter_add (NMPlatform *self, * Returns: %TRUE on success. */ gboolean -nm_platform_tfilter_sync (NMPlatform *self, - int ifindex, - GPtrArray *known_tfilters) +nm_platform_tfilter_sync(NMPlatform *self, int ifindex, GPtrArray *known_tfilters) { - gs_unref_ptrarray GPtrArray *plat_tfilters = NULL; - NMPLookup lookup; - guint i; - gboolean success = TRUE; - gs_unref_hashtable GHashTable *known_tfilters_idx = NULL; + gs_unref_ptrarray GPtrArray *plat_tfilters = NULL; + NMPLookup lookup; + guint i; + gboolean success = TRUE; + gs_unref_hashtable GHashTable *known_tfilters_idx = NULL; - nm_assert (NM_IS_PLATFORM (self)); - nm_assert (ifindex > 0); + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(ifindex > 0); - known_tfilters_idx = g_hash_table_new ((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal); + known_tfilters_idx = + g_hash_table_new((GHashFunc) nmp_object_id_hash, (GEqualFunc) nmp_object_id_equal); - if (known_tfilters) { - for (i = 0; i < known_tfilters->len; i++) { - const NMPObject *q = g_ptr_array_index (known_tfilters, i); + if (known_tfilters) { + for (i = 0; i < known_tfilters->len; i++) { + const NMPObject *q = g_ptr_array_index(known_tfilters, i); - g_hash_table_insert (known_tfilters_idx, (gpointer) q, (gpointer) q); - } - } + g_hash_table_insert(known_tfilters_idx, (gpointer) q, (gpointer) q); + } + } - plat_tfilters = nm_platform_lookup_clone (self, - nmp_lookup_init_object (&lookup, - NMP_OBJECT_TYPE_TFILTER, - ifindex), - NULL, NULL); + plat_tfilters = + nm_platform_lookup_clone(self, + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_TFILTER, ifindex), + NULL, + NULL); - if (plat_tfilters) { - for (i = 0; i < plat_tfilters->len; i++) { - const NMPObject *q = g_ptr_array_index (plat_tfilters, i); + if (plat_tfilters) { + for (i = 0; i < plat_tfilters->len; i++) { + const NMPObject *q = g_ptr_array_index(plat_tfilters, i); - if (!g_hash_table_lookup (known_tfilters_idx, q)) - success &= nm_platform_object_delete (self, q); - } - } + if (!g_hash_table_lookup(known_tfilters_idx, q)) + success &= nm_platform_object_delete(self, q); + } + } - if (known_tfilters) { - for (i = 0; i < known_tfilters->len; i++) { - const NMPObject *q = g_ptr_array_index (known_tfilters, i); + if (known_tfilters) { + for (i = 0; i < known_tfilters->len; i++) { + const NMPObject *q = g_ptr_array_index(known_tfilters, i); - success &= (nm_platform_tfilter_add (self, NMP_NLM_FLAG_ADD, - NMP_OBJECT_CAST_TFILTER (q)) >= 0); - } - } + success &= + (nm_platform_tfilter_add(self, NMP_NLM_FLAG_ADD, NMP_OBJECT_CAST_TFILTER(q)) >= 0); + } + } - return success; + return success; } /*****************************************************************************/ const char * -nm_platform_vlan_qos_mapping_to_string (const char *name, - const NMVlanQosMapping *map, - gsize n_map, - char *buf, - gsize len) +nm_platform_vlan_qos_mapping_to_string(const char * name, + const NMVlanQosMapping *map, + gsize n_map, + char * buf, + gsize len) { - gsize i; - char *b; + gsize i; + char *b; - nm_utils_to_string_buffer_init (&buf, &len); + nm_utils_to_string_buffer_init(&buf, &len); - if (!n_map) { - nm_utils_strbuf_append_str (&buf, &len, ""); - return buf; - } + if (!n_map) { + nm_utils_strbuf_append_str(&buf, &len, ""); + return buf; + } - if (!map) - g_return_val_if_reached (""); + if (!map) + g_return_val_if_reached(""); - b = buf; + b = buf; - if (name) { - nm_utils_strbuf_append_str (&b, &len, name); - nm_utils_strbuf_append_str (&b, &len, " {"); - } else - nm_utils_strbuf_append_c (&b, &len, '{'); + if (name) { + nm_utils_strbuf_append_str(&b, &len, name); + nm_utils_strbuf_append_str(&b, &len, " {"); + } else + nm_utils_strbuf_append_c(&b, &len, '{'); - for (i = 0; i < n_map; i++) - nm_utils_strbuf_append (&b, &len, " %u:%u", map[i].from, map[i].to); - nm_utils_strbuf_append_str (&b, &len, " }"); - return buf; + for (i = 0; i < n_map; i++) + nm_utils_strbuf_append(&b, &len, " %u:%u", map[i].from, map[i].to); + nm_utils_strbuf_append_str(&b, &len, " }"); + return buf; } static const char * -_lifetime_to_string (guint32 timestamp, guint32 lifetime, gint32 now, char *buf, size_t buf_size) +_lifetime_to_string(guint32 timestamp, guint32 lifetime, gint32 now, char *buf, size_t buf_size) { - if (lifetime == NM_PLATFORM_LIFETIME_PERMANENT) - return "forever"; + if (lifetime == NM_PLATFORM_LIFETIME_PERMANENT) + return "forever"; - g_snprintf (buf, buf_size, "%usec", - nm_utils_lifetime_rebase_relative_time_on_now (timestamp, lifetime, now)); - return buf; + g_snprintf(buf, + buf_size, + "%usec", + nm_utils_lifetime_rebase_relative_time_on_now(timestamp, lifetime, now)); + return buf; } static const char * -_lifetime_summary_to_string (gint32 now, guint32 timestamp, guint32 preferred, guint32 lifetime, char *buf, size_t buf_size) -{ - g_snprintf (buf, buf_size, " lifetime %d-%u[%u,%u]", - (signed) now, (unsigned) timestamp, (unsigned) preferred, (unsigned) lifetime); - return buf; +_lifetime_summary_to_string(gint32 now, + guint32 timestamp, + guint32 preferred, + guint32 lifetime, + char * buf, + size_t buf_size) +{ + g_snprintf(buf, + buf_size, + " lifetime %d-%u[%u,%u]", + (signed) now, + (unsigned) timestamp, + (unsigned) preferred, + (unsigned) lifetime); + return buf; } /** @@ -5273,575 +5469,720 @@ _lifetime_summary_to_string (gint32 now, guint32 timestamp, guint32 preferred, g * Returns: a string representation of the link. */ const char * -nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) -{ - char master[20]; - char parent[20]; - char str_flags[1 + NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN + 1]; - char str_highlighted_flags[50]; - char *s; - gsize l; - char str_addrmode[30]; - char str_address[NM_UTILS_HWADDR_LEN_MAX * 3]; - char str_broadcast[NM_UTILS_HWADDR_LEN_MAX * 3]; - char str_inet6_token[NM_UTILS_INET_ADDRSTRLEN]; - const char *str_link_type; - - if (!nm_utils_to_string_buffer_init_null (link, &buf, &len)) - return buf; - - s = str_highlighted_flags; - l = sizeof (str_highlighted_flags); - if (NM_FLAGS_HAS (link->n_ifi_flags, IFF_NOARP)) - nm_utils_strbuf_append_str (&s, &l, "NOARP,"); - if (NM_FLAGS_HAS (link->n_ifi_flags, IFF_UP)) - nm_utils_strbuf_append_str (&s, &l, "UP"); - else - nm_utils_strbuf_append_str (&s, &l, "DOWN"); - if (link->connected) - nm_utils_strbuf_append_str (&s, &l, ",LOWER_UP"); - nm_assert (s > str_highlighted_flags && l > 0); - - if (link->n_ifi_flags) { - str_flags[0] = ';'; - nm_platform_link_flags2str (link->n_ifi_flags, &str_flags[1], sizeof (str_flags) - 1); - } else - str_flags[0] = '\0'; - - if (link->master) - g_snprintf (master, sizeof (master), " master %d", link->master); - else - master[0] = 0; - - if (link->parent > 0) - g_snprintf (parent, sizeof (parent), "@%d", link->parent); - else if (link->parent == NM_PLATFORM_LINK_OTHER_NETNS) - g_strlcpy (parent, "@other-netns", sizeof (parent)); - else - parent[0] = 0; - - _nmp_link_address_to_string (&link->l_address, str_address); - _nmp_link_address_to_string (&link->l_broadcast, str_broadcast); - - str_link_type = nm_link_type_to_string (link->type); - - g_snprintf (buf, len, - "%d: " /* ifindex */ - "%s" /* name */ - "%s" /* parent */ - " <%s%s>" /* flags */ - " mtu %d" - "%s" /* master */ - " arp %u" /* arptype */ - " %s" /* link->type */ - "%s%s" /* kind */ - "%s" /* is-in-udev */ - "%s%s" /* addr-gen-mode */ - "%s%s" /* l_address */ - "%s%s" /* l_broadcast */ - "%s%s" /* inet6_token */ - "%s%s" /* driver */ - " rx:%"G_GUINT64_FORMAT",%"G_GUINT64_FORMAT - " tx:%"G_GUINT64_FORMAT",%"G_GUINT64_FORMAT - , - link->ifindex, - link->name, - parent, - str_highlighted_flags, - str_flags, - link->mtu, master, - link->arptype, - str_link_type ?: "???", - link->kind ? (g_strcmp0 (str_link_type, link->kind) ? "/" : "*") : "?", - link->kind && g_strcmp0 (str_link_type, link->kind) ? link->kind : "", - link->initialized ? " init" : " not-init", - link->inet6_addr_gen_mode_inv ? " addrgenmode " : "", - link->inet6_addr_gen_mode_inv ? nm_platform_link_inet6_addrgenmode2str (_nm_platform_uint8_inv (link->inet6_addr_gen_mode_inv), str_addrmode, sizeof (str_addrmode)) : "", - str_address[0] ? " addr " : "", - str_address[0] ? str_address : "", - str_broadcast[0] ? " brd " : "", - str_broadcast[0] ? str_broadcast : "", - link->inet6_token.id ? " inet6token " : "", - link->inet6_token.id ? nm_utils_inet6_interface_identifier_to_token (link->inet6_token, str_inet6_token) : "", - link->driver ? " driver " : "", - link->driver ?: "", - link->rx_packets, link->rx_bytes, - link->tx_packets, link->tx_bytes); - return buf; +nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) +{ + char master[20]; + char parent[20]; + char str_flags[1 + NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN + 1]; + char str_highlighted_flags[50]; + char * s; + gsize l; + char str_addrmode[30]; + char str_address[NM_UTILS_HWADDR_LEN_MAX * 3]; + char str_broadcast[NM_UTILS_HWADDR_LEN_MAX * 3]; + char str_inet6_token[NM_UTILS_INET_ADDRSTRLEN]; + const char *str_link_type; + + if (!nm_utils_to_string_buffer_init_null(link, &buf, &len)) + return buf; + + s = str_highlighted_flags; + l = sizeof(str_highlighted_flags); + if (NM_FLAGS_HAS(link->n_ifi_flags, IFF_NOARP)) + nm_utils_strbuf_append_str(&s, &l, "NOARP,"); + if (NM_FLAGS_HAS(link->n_ifi_flags, IFF_UP)) + nm_utils_strbuf_append_str(&s, &l, "UP"); + else + nm_utils_strbuf_append_str(&s, &l, "DOWN"); + if (link->connected) + nm_utils_strbuf_append_str(&s, &l, ",LOWER_UP"); + nm_assert(s > str_highlighted_flags && l > 0); + + if (link->n_ifi_flags) { + str_flags[0] = ';'; + nm_platform_link_flags2str(link->n_ifi_flags, &str_flags[1], sizeof(str_flags) - 1); + } else + str_flags[0] = '\0'; + + if (link->master) + g_snprintf(master, sizeof(master), " master %d", link->master); + else + master[0] = 0; + + if (link->parent > 0) + g_snprintf(parent, sizeof(parent), "@%d", link->parent); + else if (link->parent == NM_PLATFORM_LINK_OTHER_NETNS) + g_strlcpy(parent, "@other-netns", sizeof(parent)); + else + parent[0] = 0; + + _nmp_link_address_to_string(&link->l_address, str_address); + _nmp_link_address_to_string(&link->l_broadcast, str_broadcast); + + str_link_type = nm_link_type_to_string(link->type); + + g_snprintf( + buf, + len, + "%d: " /* ifindex */ + "%s" /* name */ + "%s" /* parent */ + " <%s%s>" /* flags */ + " mtu %d" + "%s" /* master */ + " arp %u" /* arptype */ + " %s" /* link->type */ + "%s%s" /* kind */ + "%s" /* is-in-udev */ + "%s%s" /* addr-gen-mode */ + "%s%s" /* l_address */ + "%s%s" /* l_broadcast */ + "%s%s" /* inet6_token */ + "%s%s" /* driver */ + " rx:%" G_GUINT64_FORMAT ",%" G_GUINT64_FORMAT " tx:%" G_GUINT64_FORMAT + ",%" G_GUINT64_FORMAT, + link->ifindex, + link->name, + parent, + str_highlighted_flags, + str_flags, + link->mtu, + master, + link->arptype, + str_link_type ?: "???", + link->kind ? (g_strcmp0(str_link_type, link->kind) ? "/" : "*") : "?", + link->kind && g_strcmp0(str_link_type, link->kind) ? link->kind : "", + link->initialized ? " init" : " not-init", + link->inet6_addr_gen_mode_inv ? " addrgenmode " : "", + link->inet6_addr_gen_mode_inv ? nm_platform_link_inet6_addrgenmode2str( + _nm_platform_uint8_inv(link->inet6_addr_gen_mode_inv), + str_addrmode, + sizeof(str_addrmode)) + : "", + str_address[0] ? " addr " : "", + str_address[0] ? str_address : "", + str_broadcast[0] ? " brd " : "", + str_broadcast[0] ? str_broadcast : "", + link->inet6_token.id ? " inet6token " : "", + link->inet6_token.id + ? nm_utils_inet6_interface_identifier_to_token(link->inet6_token, str_inet6_token) + : "", + link->driver ? " driver " : "", + link->driver ?: "", + link->rx_packets, + link->rx_bytes, + link->tx_packets, + link->tx_bytes); + return buf; +} + +const NMPlatformLnkBridge nm_platform_lnk_bridge_default = { + .forward_delay = NM_BRIDGE_FORWARD_DELAY_DEF_SYS, + .hello_time = NM_BRIDGE_HELLO_TIME_DEF_SYS, + .max_age = NM_BRIDGE_MAX_AGE_DEF_SYS, + .ageing_time = NM_BRIDGE_AGEING_TIME_DEF_SYS, + .stp_state = FALSE, + .priority = NM_BRIDGE_PRIORITY_DEF, + .vlan_protocol = 0x8100, + .vlan_stats_enabled = NM_BRIDGE_VLAN_STATS_ENABLED_DEF, + .group_fwd_mask = 0, + .group_addr = NM_ETHER_ADDR_INIT(NM_BRIDGE_GROUP_ADDRESS_DEF_BIN), + .mcast_snooping = NM_BRIDGE_MULTICAST_SNOOPING_DEF, + .mcast_router = 1, + .mcast_query_use_ifaddr = NM_BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEF, + .mcast_querier = NM_BRIDGE_MULTICAST_QUERIER_DEF, + .mcast_hash_max = NM_BRIDGE_MULTICAST_HASH_MAX_DEF, + .mcast_last_member_count = NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF, + .mcast_startup_query_count = NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF, + .mcast_last_member_interval = NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF, + .mcast_membership_interval = NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF, + .mcast_querier_interval = NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF, + .mcast_query_interval = NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF, + .mcast_query_response_interval = NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF, + .mcast_startup_query_interval = NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF, +}; + +const char * +nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsize len) +{ + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf(buf, + len, + "forward_delay %u" + " hello_time %u" + " max_age %u" + " ageing_time %u" + " stp_state %d" + " priority %u" + " vlan_protocol %u" + " vlan_stats_enabled %d" + " group_fwd_mask %#x" + " group_address " NM_ETHER_ADDR_FORMAT_STR " mcast_snooping %d" + " mcast_router %u" + " mcast_query_use_ifaddr %d" + " mcast_querier %d" + " mcast_hash_max %u" + " mcast_last_member_count %u" + " mcast_startup_query_count %u" + " mcast_last_member_interval %" G_GUINT64_FORMAT + " mcast_membership_interval %" G_GUINT64_FORMAT + " mcast_querier_interval %" G_GUINT64_FORMAT + " mcast_query_interval %" G_GUINT64_FORMAT + " mcast_query_response_interval %" G_GUINT64_FORMAT + " mcast_startup_query_interval %" G_GUINT64_FORMAT "", + lnk->forward_delay, + lnk->hello_time, + lnk->max_age, + lnk->ageing_time, + (int) lnk->stp_state, + lnk->priority, + lnk->vlan_protocol, + (int) lnk->vlan_stats_enabled, + lnk->group_fwd_mask, + NM_ETHER_ADDR_FORMAT_VAL(lnk->group_addr), + (int) lnk->mcast_snooping, + lnk->mcast_router, + (int) lnk->mcast_query_use_ifaddr, + (int) lnk->mcast_querier, + lnk->mcast_hash_max, + lnk->mcast_last_member_count, + lnk->mcast_startup_query_count, + lnk->mcast_last_member_interval, + lnk->mcast_membership_interval, + lnk->mcast_querier_interval, + lnk->mcast_query_interval, + lnk->mcast_query_response_interval, + lnk->mcast_startup_query_interval); + return buf; } const char * -nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len) -{ - char str_local[30]; - char str_local1[NM_UTILS_INET_ADDRSTRLEN]; - char str_remote[30]; - char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; - char str_ttl[30]; - char str_tos[30]; - char str_parent_ifindex[30]; - char str_input_flags[30]; - char str_output_flags[30]; - char str_input_key[30]; - char str_input_key1[NM_UTILS_INET_ADDRSTRLEN]; - char str_output_key[30]; - char str_output_key1[NM_UTILS_INET_ADDRSTRLEN]; - - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; - - g_snprintf (buf, len, - "gre%s" /* is_tap */ - "%s" /* remote */ - "%s" /* local */ - "%s" /* parent_ifindex */ - "%s" /* ttl */ - "%s" /* tos */ - "%s" /* path_mtu_discovery */ - "%s" /* iflags */ - "%s" /* oflags */ - "%s" /* ikey */ - "%s" /* okey */ - "", - lnk->is_tap ? "tap" : "", - lnk->remote ? nm_sprintf_buf (str_remote, " remote %s", _nm_utils_inet4_ntop (lnk->remote, str_remote1)) : "", - lnk->local ? nm_sprintf_buf (str_local, " local %s", _nm_utils_inet4_ntop (lnk->local, str_local1)) : "", - lnk->parent_ifindex ? nm_sprintf_buf (str_parent_ifindex, " dev %d", lnk->parent_ifindex) : "", - lnk->ttl ? nm_sprintf_buf (str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", - lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf (str_tos, " tos 0x%x", lnk->tos)) : "", - lnk->path_mtu_discovery ? "" : " nopmtudisc", - lnk->input_flags ? nm_sprintf_buf (str_input_flags, " iflags 0x%x", lnk->input_flags) : "", - lnk->output_flags ? nm_sprintf_buf (str_output_flags, " oflags 0x%x", lnk->output_flags) : "", - NM_FLAGS_HAS (lnk->input_flags, GRE_KEY) || lnk->input_key ? nm_sprintf_buf (str_input_key, " ikey %s", _nm_utils_inet4_ntop (lnk->input_key, str_input_key1)) : "", - NM_FLAGS_HAS (lnk->output_flags, GRE_KEY) || lnk->output_key ? nm_sprintf_buf (str_output_key, " okey %s", _nm_utils_inet4_ntop (lnk->output_key, str_output_key1)) : ""); - return buf; +nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len) +{ + char str_local[30]; + char str_local1[NM_UTILS_INET_ADDRSTRLEN]; + char str_remote[30]; + char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tos[30]; + char str_parent_ifindex[30]; + char str_input_flags[30]; + char str_output_flags[30]; + char str_input_key[30]; + char str_input_key1[NM_UTILS_INET_ADDRSTRLEN]; + char str_output_key[30]; + char str_output_key1[NM_UTILS_INET_ADDRSTRLEN]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf( + buf, + len, + "gre%s" /* is_tap */ + "%s" /* remote */ + "%s" /* local */ + "%s" /* parent_ifindex */ + "%s" /* ttl */ + "%s" /* tos */ + "%s" /* path_mtu_discovery */ + "%s" /* iflags */ + "%s" /* oflags */ + "%s" /* ikey */ + "%s" /* okey */ + "", + lnk->is_tap ? "tap" : "", + lnk->remote ? nm_sprintf_buf(str_remote, + " remote %s", + _nm_utils_inet4_ntop(lnk->remote, str_remote1)) + : "", + lnk->local + ? nm_sprintf_buf(str_local, " local %s", _nm_utils_inet4_ntop(lnk->local, str_local1)) + : "", + lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex) + : "", + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", + lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos)) + : "", + lnk->path_mtu_discovery ? "" : " nopmtudisc", + lnk->input_flags ? nm_sprintf_buf(str_input_flags, " iflags 0x%x", lnk->input_flags) : "", + lnk->output_flags ? nm_sprintf_buf(str_output_flags, " oflags 0x%x", lnk->output_flags) + : "", + NM_FLAGS_HAS(lnk->input_flags, GRE_KEY) || lnk->input_key + ? nm_sprintf_buf(str_input_key, + " ikey %s", + _nm_utils_inet4_ntop(lnk->input_key, str_input_key1)) + : "", + NM_FLAGS_HAS(lnk->output_flags, GRE_KEY) || lnk->output_key + ? nm_sprintf_buf(str_output_key, + " okey %s", + _nm_utils_inet4_ntop(lnk->output_key, str_output_key1)) + : ""); + return buf; } const char * -nm_platform_lnk_infiniband_to_string (const NMPlatformLnkInfiniband *lnk, char *buf, gsize len) +nm_platform_lnk_infiniband_to_string(const NMPlatformLnkInfiniband *lnk, char *buf, gsize len) { - char str_p_key[64]; + char str_p_key[64]; - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; - g_snprintf (buf, len, - "infiniband" - "%s" /* p_key */ - "%s%s" /* mode */ - "", - lnk->p_key ? nm_sprintf_buf (str_p_key, " pkey %d", lnk->p_key) : "", - lnk->mode ? " mode " : "", - lnk->mode ?: ""); - return buf; + g_snprintf(buf, + len, + "infiniband" + "%s" /* p_key */ + "%s%s" /* mode */ + "", + lnk->p_key ? nm_sprintf_buf(str_p_key, " pkey %d", lnk->p_key) : "", + lnk->mode ? " mode " : "", + lnk->mode ?: ""); + return buf; } const char * -nm_platform_lnk_ip6tnl_to_string (const NMPlatformLnkIp6Tnl *lnk, char *buf, gsize len) -{ - char str_local[30]; - char str_local1[NM_UTILS_INET_ADDRSTRLEN]; - char str_remote[30]; - char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; - char str_ttl[30]; - char str_tclass[30]; - char str_flow[30]; - char str_encap[30]; - char str_proto[30]; - char str_parent_ifindex[30]; - char *str_type; - - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; - - if (lnk->is_gre) - str_type = lnk->is_tap ? "ip6gretap" : "ip6gre"; - else - str_type = "ip6tnl"; - - g_snprintf (buf, len, - "%s" /* type */ - "%s" /* remote */ - "%s" /* local */ - "%s" /* parent_ifindex */ - "%s" /* ttl */ - "%s" /* tclass */ - "%s" /* encap limit */ - "%s" /* flow label */ - "%s" /* proto */ - " flags 0x%x" - "", - str_type, - nm_sprintf_buf (str_remote, " remote %s", _nm_utils_inet6_ntop (&lnk->remote, str_remote1)), - nm_sprintf_buf (str_local, " local %s", _nm_utils_inet6_ntop (&lnk->local, str_local1)), - lnk->parent_ifindex ? nm_sprintf_buf (str_parent_ifindex, " dev %d", lnk->parent_ifindex) : "", - lnk->ttl ? nm_sprintf_buf (str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", - lnk->tclass == 1 ? " tclass inherit" : nm_sprintf_buf (str_tclass, " tclass 0x%x", lnk->tclass), - nm_sprintf_buf (str_encap, " encap-limit %u", lnk->encap_limit), - nm_sprintf_buf (str_flow, " flow-label 0x05%x", lnk->flow_label), - nm_sprintf_buf (str_proto, " proto %u", lnk->proto), - (guint) lnk->flags); - return buf; +nm_platform_lnk_ip6tnl_to_string(const NMPlatformLnkIp6Tnl *lnk, char *buf, gsize len) +{ + char str_local[30]; + char str_local1[NM_UTILS_INET_ADDRSTRLEN]; + char str_remote[30]; + char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tclass[30]; + char str_flow[30]; + char str_encap[30]; + char str_proto[30]; + char str_parent_ifindex[30]; + char *str_type; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + if (lnk->is_gre) + str_type = lnk->is_tap ? "ip6gretap" : "ip6gre"; + else + str_type = "ip6tnl"; + + g_snprintf( + buf, + len, + "%s" /* type */ + "%s" /* remote */ + "%s" /* local */ + "%s" /* parent_ifindex */ + "%s" /* ttl */ + "%s" /* tclass */ + "%s" /* encap limit */ + "%s" /* flow label */ + "%s" /* proto */ + " flags 0x%x" + "", + str_type, + nm_sprintf_buf(str_remote, " remote %s", _nm_utils_inet6_ntop(&lnk->remote, str_remote1)), + nm_sprintf_buf(str_local, " local %s", _nm_utils_inet6_ntop(&lnk->local, str_local1)), + lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex) + : "", + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", + lnk->tclass == 1 ? " tclass inherit" + : nm_sprintf_buf(str_tclass, " tclass 0x%x", lnk->tclass), + nm_sprintf_buf(str_encap, " encap-limit %u", lnk->encap_limit), + nm_sprintf_buf(str_flow, " flow-label 0x05%x", lnk->flow_label), + nm_sprintf_buf(str_proto, " proto %u", lnk->proto), + (guint) lnk->flags); + return buf; } const char * -nm_platform_lnk_ipip_to_string (const NMPlatformLnkIpIp *lnk, char *buf, gsize len) -{ - char str_local[30]; - char str_local1[NM_UTILS_INET_ADDRSTRLEN]; - char str_remote[30]; - char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; - char str_ttl[30]; - char str_tos[30]; - char str_parent_ifindex[30]; - - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; - - g_snprintf (buf, len, - "ipip" - "%s" /* remote */ - "%s" /* local */ - "%s" /* parent_ifindex */ - "%s" /* ttl */ - "%s" /* tos */ - "%s" /* path_mtu_discovery */ - "", - lnk->remote ? nm_sprintf_buf (str_remote, " remote %s", _nm_utils_inet4_ntop (lnk->remote, str_remote1)) : "", - lnk->local ? nm_sprintf_buf (str_local, " local %s", _nm_utils_inet4_ntop (lnk->local, str_local1)) : "", - lnk->parent_ifindex ? nm_sprintf_buf (str_parent_ifindex, " dev %d", lnk->parent_ifindex) : "", - lnk->ttl ? nm_sprintf_buf (str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", - lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf (str_tos, " tos 0x%x", lnk->tos)) : "", - lnk->path_mtu_discovery ? "" : " nopmtudisc"); - return buf; +nm_platform_lnk_ipip_to_string(const NMPlatformLnkIpIp *lnk, char *buf, gsize len) +{ + char str_local[30]; + char str_local1[NM_UTILS_INET_ADDRSTRLEN]; + char str_remote[30]; + char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tos[30]; + char str_parent_ifindex[30]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf( + buf, + len, + "ipip" + "%s" /* remote */ + "%s" /* local */ + "%s" /* parent_ifindex */ + "%s" /* ttl */ + "%s" /* tos */ + "%s" /* path_mtu_discovery */ + "", + lnk->remote ? nm_sprintf_buf(str_remote, + " remote %s", + _nm_utils_inet4_ntop(lnk->remote, str_remote1)) + : "", + lnk->local + ? nm_sprintf_buf(str_local, " local %s", _nm_utils_inet4_ntop(lnk->local, str_local1)) + : "", + lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex) + : "", + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", + lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos)) + : "", + lnk->path_mtu_discovery ? "" : " nopmtudisc"); + return buf; } const char * -nm_platform_lnk_macsec_to_string (const NMPlatformLnkMacsec *lnk, char *buf, gsize len) -{ - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; - - g_snprintf (buf, len, - "macsec " - "sci %016llx " - "protect %s " - "cipher %016llx " - "icvlen %u " - "encodingsa %u " - "validate %u " - "encrypt %s " - "send_sci %s " - "end_station %s " - "scb %s " - "replay %s", - (unsigned long long) lnk->sci, - lnk->protect ? "on" : "off", - (unsigned long long) lnk->cipher_suite, - lnk->icv_length, - lnk->encoding_sa, - lnk->validation, - lnk->encrypt ? "on" : "off", - lnk->include_sci ? "on" : "off", - lnk->es ? "on" : "off", - lnk->scb ? "on" : "off", - lnk->replay_protect ? "on" : "off"); - return buf; +nm_platform_lnk_macsec_to_string(const NMPlatformLnkMacsec *lnk, char *buf, gsize len) +{ + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf(buf, + len, + "macsec " + "sci %016llx " + "protect %s " + "cipher %016llx " + "icvlen %u " + "encodingsa %u " + "validate %u " + "encrypt %s " + "send_sci %s " + "end_station %s " + "scb %s " + "replay %s", + (unsigned long long) lnk->sci, + lnk->protect ? "on" : "off", + (unsigned long long) lnk->cipher_suite, + lnk->icv_length, + lnk->encoding_sa, + lnk->validation, + lnk->encrypt ? "on" : "off", + lnk->include_sci ? "on" : "off", + lnk->es ? "on" : "off", + lnk->scb ? "on" : "off", + lnk->replay_protect ? "on" : "off"); + return buf; } const char * -nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, gsize len) +nm_platform_lnk_macvlan_to_string(const NMPlatformLnkMacvlan *lnk, char *buf, gsize len) { - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; - g_snprintf (buf, len, - "%s mode %u %s", - lnk->tap ? "macvtap" : "macvlan", - lnk->mode, - lnk->no_promisc ? "not-promisc" : "promisc"); - return buf; + g_snprintf(buf, + len, + "%s mode %u %s", + lnk->tap ? "macvtap" : "macvlan", + lnk->mode, + lnk->no_promisc ? "not-promisc" : "promisc"); + return buf; } const char * -nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len) -{ - char str_local[30]; - char str_local1[NM_UTILS_INET_ADDRSTRLEN]; - char str_remote[30]; - char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; - char str_ttl[30]; - char str_tos[30]; - char str_flags[30]; - char str_proto[30]; - char str_parent_ifindex[30]; - - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; - - g_snprintf (buf, len, - "sit" - "%s" /* remote */ - "%s" /* local */ - "%s" /* parent_ifindex */ - "%s" /* ttl */ - "%s" /* tos */ - "%s" /* path_mtu_discovery */ - "%s" /* flags */ - "%s" /* proto */ - "", - lnk->remote ? nm_sprintf_buf (str_remote, " remote %s", _nm_utils_inet4_ntop (lnk->remote, str_remote1)) : "", - lnk->local ? nm_sprintf_buf (str_local, " local %s", _nm_utils_inet4_ntop (lnk->local, str_local1)) : "", - lnk->parent_ifindex ? nm_sprintf_buf (str_parent_ifindex, " dev %d", lnk->parent_ifindex) : "", - lnk->ttl ? nm_sprintf_buf (str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", - lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf (str_tos, " tos 0x%x", lnk->tos)) : "", - lnk->path_mtu_discovery ? "" : " nopmtudisc", - lnk->flags ? nm_sprintf_buf (str_flags, " flags 0x%x", lnk->flags) : "", - lnk->proto ? nm_sprintf_buf (str_proto, " proto 0x%x", lnk->proto) : ""); - return buf; +nm_platform_lnk_sit_to_string(const NMPlatformLnkSit *lnk, char *buf, gsize len) +{ + char str_local[30]; + char str_local1[NM_UTILS_INET_ADDRSTRLEN]; + char str_remote[30]; + char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tos[30]; + char str_flags[30]; + char str_proto[30]; + char str_parent_ifindex[30]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf( + buf, + len, + "sit" + "%s" /* remote */ + "%s" /* local */ + "%s" /* parent_ifindex */ + "%s" /* ttl */ + "%s" /* tos */ + "%s" /* path_mtu_discovery */ + "%s" /* flags */ + "%s" /* proto */ + "", + lnk->remote ? nm_sprintf_buf(str_remote, + " remote %s", + _nm_utils_inet4_ntop(lnk->remote, str_remote1)) + : "", + lnk->local + ? nm_sprintf_buf(str_local, " local %s", _nm_utils_inet4_ntop(lnk->local, str_local1)) + : "", + lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex) + : "", + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", + lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos)) + : "", + lnk->path_mtu_discovery ? "" : " nopmtudisc", + lnk->flags ? nm_sprintf_buf(str_flags, " flags 0x%x", lnk->flags) : "", + lnk->proto ? nm_sprintf_buf(str_proto, " proto 0x%x", lnk->proto) : ""); + return buf; } const char * -nm_platform_lnk_tun_to_string (const NMPlatformLnkTun *lnk, char *buf, gsize len) -{ - char str_owner[50]; - char str_group[50]; - char str_type[50]; - const char *type; - - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; - - if (lnk->type == IFF_TUN) - type = "tun"; - else if (lnk->type == IFF_TAP) - type = "tap"; - else - type = nm_sprintf_buf (str_type, "tun type %u", (guint) lnk->type); - - g_snprintf (buf, len, - "%s" /* type */ - "%s" /* pi */ - "%s" /* vnet_hdr */ - "%s" /* multi_queue */ - "%s" /* persist */ - "%s" /* owner */ - "%s" /* group */ - "", - type, - lnk->pi ? " pi" : "", - lnk->vnet_hdr ? " vnet_hdr" : "", - lnk->multi_queue ? " multi_queue" : "", - lnk->persist ? " persist" : "", - lnk->owner_valid ? nm_sprintf_buf (str_owner, " owner %u", (guint) lnk->owner) : "", - lnk->group_valid ? nm_sprintf_buf (str_group, " group %u", (guint) lnk->group) : ""); - return buf; +nm_platform_lnk_tun_to_string(const NMPlatformLnkTun *lnk, char *buf, gsize len) +{ + char str_owner[50]; + char str_group[50]; + char str_type[50]; + const char *type; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + if (lnk->type == IFF_TUN) + type = "tun"; + else if (lnk->type == IFF_TAP) + type = "tap"; + else + type = nm_sprintf_buf(str_type, "tun type %u", (guint) lnk->type); + + g_snprintf(buf, + len, + "%s" /* type */ + "%s" /* pi */ + "%s" /* vnet_hdr */ + "%s" /* multi_queue */ + "%s" /* persist */ + "%s" /* owner */ + "%s" /* group */ + "", + type, + lnk->pi ? " pi" : "", + lnk->vnet_hdr ? " vnet_hdr" : "", + lnk->multi_queue ? " multi_queue" : "", + lnk->persist ? " persist" : "", + lnk->owner_valid ? nm_sprintf_buf(str_owner, " owner %u", (guint) lnk->owner) : "", + lnk->group_valid ? nm_sprintf_buf(str_group, " group %u", (guint) lnk->group) : ""); + return buf; } const char * -nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len) +nm_platform_lnk_vlan_to_string(const NMPlatformLnkVlan *lnk, char *buf, gsize len) { - char *b; + char *b; - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; - b = buf; + b = buf; - nm_utils_strbuf_append (&b, &len, "vlan %u", lnk->id); - if (lnk->flags) - nm_utils_strbuf_append (&b, &len, " flags 0x%x", lnk->flags); - return buf; + nm_utils_strbuf_append(&b, &len, "vlan %u", lnk->id); + if (lnk->flags) + nm_utils_strbuf_append(&b, &len, " flags 0x%x", lnk->flags); + return buf; } const char * -nm_platform_lnk_vrf_to_string (const NMPlatformLnkVrf *lnk, char *buf, gsize len) +nm_platform_lnk_vrf_to_string(const NMPlatformLnkVrf *lnk, char *buf, gsize len) { - char *b; + char *b; - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; - b = buf; + b = buf; - nm_utils_strbuf_append (&b, &len, "table %u", lnk->table); - return buf; + nm_utils_strbuf_append(&b, &len, "table %u", lnk->table); + return buf; } const char * -nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize len) -{ - char str_group[100]; - char str_group6[100]; - char str_local[100]; - char str_local6[100]; - char str_dev[25]; - char str_limit[25]; - char str_src_port[35]; - char str_dst_port[25]; - char str_tos[25]; - char str_ttl[25]; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; - - if (lnk->group == 0) - str_group[0] = '\0'; - else { - g_snprintf (str_group, sizeof (str_group), - " %s %s", - IN_MULTICAST (ntohl (lnk->group)) ? "group" : "remote", - _nm_utils_inet4_ntop (lnk->group, sbuf)); - } - if (IN6_IS_ADDR_UNSPECIFIED (&lnk->group6)) - str_group6[0] = '\0'; - else { - g_snprintf (str_group6, sizeof (str_group6), - " %s%s %s", - IN6_IS_ADDR_MULTICAST (&lnk->group6) ? "group" : "remote", - str_group[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */ - _nm_utils_inet6_ntop (&lnk->group6, sbuf)); - } - - if (lnk->local == 0) - str_local[0] = '\0'; - else { - g_snprintf (str_local, sizeof (str_local), - " local %s", - _nm_utils_inet4_ntop (lnk->local, sbuf)); - } - if (IN6_IS_ADDR_UNSPECIFIED (&lnk->local6)) - str_local6[0] = '\0'; - else { - g_snprintf (str_local6, sizeof (str_local6), - " local%s %s", - str_local[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */ - _nm_utils_inet6_ntop (&lnk->local6, sbuf)); - } - - g_snprintf (buf, len, - "vxlan" - " id %u" /* id */ - "%s%s" /* group/group6 */ - "%s%s" /* local/local6 */ - "%s" /* dev */ - "%s" /* src_port_min/src_port_max */ - "%s" /* dst_port */ - "%s" /* learning */ - "%s" /* proxy */ - "%s" /* rsc */ - "%s" /* l2miss */ - "%s" /* l3miss */ - "%s" /* tos */ - "%s" /* ttl */ - " ageing %u" /* ageing */ - "%s" /* limit */ - "", - (guint) lnk->id, - str_group, str_group6, - str_local, str_local6, - lnk->parent_ifindex ? nm_sprintf_buf (str_dev, " dev %d", lnk->parent_ifindex) : "", - lnk->src_port_min || lnk->src_port_max ? nm_sprintf_buf (str_src_port, " srcport %u %u", lnk->src_port_min, lnk->src_port_max) : "", - lnk->dst_port ? nm_sprintf_buf (str_dst_port, " dstport %u", lnk->dst_port) : "", - !lnk->learning ? " nolearning" : "", - lnk->proxy ? " proxy" : "", - lnk->rsc ? " rsc" : "", - lnk->l2miss ? " l2miss" : "", - lnk->l3miss ? " l3miss" : "", - lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf (str_tos, " tos %#x", lnk->tos), - lnk->ttl ? nm_sprintf_buf (str_ttl, " ttl %u", lnk->ttl) : "", - lnk->ageing, - lnk->limit ? nm_sprintf_buf (str_limit, " maxaddr %u", lnk->limit) : ""); - return buf; +nm_platform_lnk_vxlan_to_string(const NMPlatformLnkVxlan *lnk, char *buf, gsize len) +{ + char str_group[100]; + char str_group6[100]; + char str_local[100]; + char str_local6[100]; + char str_dev[25]; + char str_limit[25]; + char str_src_port[35]; + char str_dst_port[25]; + char str_tos[25]; + char str_ttl[25]; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + if (lnk->group == 0) + str_group[0] = '\0'; + else { + g_snprintf(str_group, + sizeof(str_group), + " %s %s", + IN_MULTICAST(ntohl(lnk->group)) ? "group" : "remote", + _nm_utils_inet4_ntop(lnk->group, sbuf)); + } + if (IN6_IS_ADDR_UNSPECIFIED(&lnk->group6)) + str_group6[0] = '\0'; + else { + g_snprintf(str_group6, + sizeof(str_group6), + " %s%s %s", + IN6_IS_ADDR_MULTICAST(&lnk->group6) ? "group" : "remote", + str_group[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */ + _nm_utils_inet6_ntop(&lnk->group6, sbuf)); + } + + if (lnk->local == 0) + str_local[0] = '\0'; + else { + g_snprintf(str_local, + sizeof(str_local), + " local %s", + _nm_utils_inet4_ntop(lnk->local, sbuf)); + } + if (IN6_IS_ADDR_UNSPECIFIED(&lnk->local6)) + str_local6[0] = '\0'; + else { + g_snprintf(str_local6, + sizeof(str_local6), + " local%s %s", + str_local[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */ + _nm_utils_inet6_ntop(&lnk->local6, sbuf)); + } + + g_snprintf( + buf, + len, + "vxlan" + " id %u" /* id */ + "%s%s" /* group/group6 */ + "%s%s" /* local/local6 */ + "%s" /* dev */ + "%s" /* src_port_min/src_port_max */ + "%s" /* dst_port */ + "%s" /* learning */ + "%s" /* proxy */ + "%s" /* rsc */ + "%s" /* l2miss */ + "%s" /* l3miss */ + "%s" /* tos */ + "%s" /* ttl */ + " ageing %u" /* ageing */ + "%s" /* limit */ + "", + (guint) lnk->id, + str_group, + str_group6, + str_local, + str_local6, + lnk->parent_ifindex ? nm_sprintf_buf(str_dev, " dev %d", lnk->parent_ifindex) : "", + lnk->src_port_min || lnk->src_port_max + ? nm_sprintf_buf(str_src_port, " srcport %u %u", lnk->src_port_min, lnk->src_port_max) + : "", + lnk->dst_port ? nm_sprintf_buf(str_dst_port, " dstport %u", lnk->dst_port) : "", + !lnk->learning ? " nolearning" : "", + lnk->proxy ? " proxy" : "", + lnk->rsc ? " rsc" : "", + lnk->l2miss ? " l2miss" : "", + lnk->l3miss ? " l3miss" : "", + lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos %#x", lnk->tos), + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : "", + lnk->ageing, + lnk->limit ? nm_sprintf_buf(str_limit, " maxaddr %u", lnk->limit) : ""); + return buf; } const char * -nm_platform_wireguard_peer_to_string (const NMPWireGuardPeer *peer, char *buf, gsize len) -{ - char *buf0 = buf; - gs_free char *public_key_b64 = NULL; - char s_sockaddr[NM_UTILS_INET_ADDRSTRLEN + 100]; - char s_endpoint[20 + sizeof (s_sockaddr)]; - char s_addr[NM_UTILS_INET_ADDRSTRLEN]; - char s_keepalive[100]; - guint i; - - nm_utils_to_string_buffer_init (&buf, &len); - - public_key_b64 = g_base64_encode (peer->public_key, sizeof (peer->public_key)); - - if (peer->endpoint.sa.sa_family != AF_UNSPEC) { - nm_sprintf_buf (s_endpoint, - " endpoint %s", - nm_sock_addr_union_to_string (&peer->endpoint, - s_sockaddr, - sizeof (s_sockaddr))); - } else - s_endpoint[0] = '\0'; - - nm_utils_strbuf_append (&buf, &len, - "public-key %s" - "%s" /* preshared-key */ - "%s" /* endpoint */ - " rx %"G_GUINT64_FORMAT - " tx %"G_GUINT64_FORMAT - "%s" /* persistent-keepalive */ - "%s", /* allowed-ips */ - public_key_b64, - nm_utils_memeqzero_secret (peer->preshared_key, sizeof (peer->preshared_key)) - ? "" - : " preshared-key (hidden)", - s_endpoint, - peer->rx_bytes, - peer->tx_bytes, - peer->persistent_keepalive_interval > 0 - ? nm_sprintf_buf (s_keepalive, " keepalive %u", (guint) peer->persistent_keepalive_interval) - : "", - peer->allowed_ips_len > 0 - ? " allowed-ips" - : ""); - - for (i = 0; i < peer->allowed_ips_len; i++) { - const NMPWireGuardAllowedIP *allowed_ip = &peer->allowed_ips[i]; - - nm_utils_strbuf_append (&buf, &len, - " %s/%u", - nm_utils_inet_ntop (allowed_ip->family, &allowed_ip->addr, s_addr), - allowed_ip->mask); - } - - return buf0; +nm_platform_wireguard_peer_to_string(const NMPWireGuardPeer *peer, char *buf, gsize len) +{ + char * buf0 = buf; + gs_free char *public_key_b64 = NULL; + char s_sockaddr[NM_UTILS_INET_ADDRSTRLEN + 100]; + char s_endpoint[20 + sizeof(s_sockaddr)]; + char s_addr[NM_UTILS_INET_ADDRSTRLEN]; + char s_keepalive[100]; + guint i; + + nm_utils_to_string_buffer_init(&buf, &len); + + public_key_b64 = g_base64_encode(peer->public_key, sizeof(peer->public_key)); + + if (peer->endpoint.sa.sa_family != AF_UNSPEC) { + nm_sprintf_buf( + s_endpoint, + " endpoint %s", + nm_sock_addr_union_to_string(&peer->endpoint, s_sockaddr, sizeof(s_sockaddr))); + } else + s_endpoint[0] = '\0'; + + nm_utils_strbuf_append( + &buf, + &len, + "public-key %s" + "%s" /* preshared-key */ + "%s" /* endpoint */ + " rx %" G_GUINT64_FORMAT " tx %" G_GUINT64_FORMAT "%s" /* persistent-keepalive */ + "%s", /* allowed-ips */ + public_key_b64, + nm_utils_memeqzero_secret(peer->preshared_key, sizeof(peer->preshared_key)) + ? "" + : " preshared-key (hidden)", + s_endpoint, + peer->rx_bytes, + peer->tx_bytes, + peer->persistent_keepalive_interval > 0 + ? nm_sprintf_buf(s_keepalive, + " keepalive %u", + (guint) peer->persistent_keepalive_interval) + : "", + peer->allowed_ips_len > 0 ? " allowed-ips" : ""); + + for (i = 0; i < peer->allowed_ips_len; i++) { + const NMPWireGuardAllowedIP *allowed_ip = &peer->allowed_ips[i]; + + nm_utils_strbuf_append(&buf, + &len, + " %s/%u", + nm_utils_inet_ntop(allowed_ip->family, &allowed_ip->addr, s_addr), + allowed_ip->mask); + } + + return buf0; } const char * -nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireGuard *lnk, char *buf, gsize len) +nm_platform_lnk_wireguard_to_string(const NMPlatformLnkWireGuard *lnk, char *buf, gsize len) { - gs_free char *public_b64 = NULL; + gs_free char *public_b64 = NULL; - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; - if (!nm_utils_memeqzero (lnk->public_key, sizeof (lnk->public_key))) - public_b64 = g_base64_encode (lnk->public_key, sizeof (lnk->public_key)); + if (!nm_utils_memeqzero(lnk->public_key, sizeof(lnk->public_key))) + public_b64 = g_base64_encode(lnk->public_key, sizeof(lnk->public_key)); - g_snprintf (buf, len, - "wireguard" - "%s%s" /* public-key */ - "%s" /* private-key */ - " listen-port %u" - " fwmark 0x%x", - public_b64 - ? " public-key " - : "", - public_b64 ?: "", - nm_utils_memeqzero_secret (lnk->private_key, sizeof (lnk->private_key)) - ? "" - : " private-key (hidden)", - lnk->listen_port, - lnk->fwmark); + g_snprintf(buf, + len, + "wireguard" + "%s%s" /* public-key */ + "%s" /* private-key */ + " listen-port %u" + " fwmark 0x%x", + public_b64 ? " public-key " : "", + public_b64 ?: "", + nm_utils_memeqzero_secret(lnk->private_key, sizeof(lnk->private_key)) + ? "" + : " private-key (hidden)", + lnk->listen_port, + lnk->fwmark); - return buf; + return buf; } /** @@ -5857,126 +6198,140 @@ nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireGuard *lnk, char *bu * Returns: a string representation of the address. */ const char * -nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *buf, gsize len) -{ - char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE]; - char s_address[INET_ADDRSTRLEN]; - char s_peer[INET_ADDRSTRLEN]; - char str_dev[TO_STRING_DEV_BUF_SIZE]; - char str_label[32]; - char str_lft[30], str_pref[30], str_time[50], s_source[50]; - char *str_peer = NULL; - const char *str_lft_p, *str_pref_p, *str_time_p; - gint32 now = nm_utils_get_monotonic_timestamp_sec (); - in_addr_t broadcast_address; - char str_broadcast[INET_ADDRSTRLEN]; - - if (!nm_utils_to_string_buffer_init_null (address, &buf, &len)) - return buf; - - inet_ntop (AF_INET, &address->address, s_address, sizeof (s_address)); - - if (address->peer_address != address->address) { - inet_ntop (AF_INET, &address->peer_address, s_peer, sizeof (s_peer)); - str_peer = g_strconcat (" ptp ", s_peer, NULL); - } - - _to_string_dev (NULL, address->ifindex, str_dev, sizeof (str_dev)); - - if (*address->label) - g_snprintf (str_label, sizeof (str_label), " label %s", address->label); - else - str_label[0] = 0; - - str_lft_p = _lifetime_to_string (address->timestamp, - address->lifetime ?: NM_PLATFORM_LIFETIME_PERMANENT, - now, str_lft, sizeof (str_lft)), - str_pref_p = (address->lifetime == address->preferred) - ? str_lft_p - : ( _lifetime_to_string (address->timestamp, - address->lifetime ? MIN (address->preferred, address->lifetime) : NM_PLATFORM_LIFETIME_PERMANENT, - now, str_pref, sizeof (str_pref)) ); - str_time_p = _lifetime_summary_to_string (now, address->timestamp, address->preferred, address->lifetime, str_time, sizeof (str_time)); - - broadcast_address = nm_platform_ip4_broadcast_address_from_addr (address); - - g_snprintf (buf, len, - "%s/%d" - "%s%s" /* broadcast */ - " lft %s" - " pref %s" - "%s" /* time */ - "%s" /* peer */ - "%s" /* dev */ - "%s" /* flags */ - "%s" /* label */ - " src %s" - "%s" /* external */ - "", - s_address, address->plen, - broadcast_address ? " brd " : "", - broadcast_address ? nm_utils_inet4_ntop (broadcast_address, str_broadcast) : "", - str_lft_p, - str_pref_p, - str_time_p, - str_peer ?: "", - str_dev, - _to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)), - str_label, - nmp_utils_ip_config_source_to_string (address->addr_source, s_source, sizeof (s_source)), - address->external ? " ext" : ""); - g_free (str_peer); - return buf; -} - -NM_UTILS_FLAGS2STR_DEFINE (nm_platform_link_flags2str, unsigned, - NM_UTILS_FLAGS2STR (IFF_LOOPBACK, "loopback"), - NM_UTILS_FLAGS2STR (IFF_BROADCAST, "broadcast"), - NM_UTILS_FLAGS2STR (IFF_POINTOPOINT, "pointopoint"), - NM_UTILS_FLAGS2STR (IFF_MULTICAST, "multicast"), - NM_UTILS_FLAGS2STR (IFF_NOARP, "noarp"), - NM_UTILS_FLAGS2STR (IFF_ALLMULTI, "allmulti"), - NM_UTILS_FLAGS2STR (IFF_PROMISC, "promisc"), - NM_UTILS_FLAGS2STR (IFF_MASTER, "master"), - NM_UTILS_FLAGS2STR (IFF_SLAVE, "slave"), - NM_UTILS_FLAGS2STR (IFF_DEBUG, "debug"), - NM_UTILS_FLAGS2STR (IFF_DYNAMIC, "dynamic"), - NM_UTILS_FLAGS2STR (IFF_AUTOMEDIA, "automedia"), - NM_UTILS_FLAGS2STR (IFF_PORTSEL, "portsel"), - NM_UTILS_FLAGS2STR (IFF_NOTRAILERS, "notrailers"), - NM_UTILS_FLAGS2STR (IFF_UP, "up"), - NM_UTILS_FLAGS2STR (IFF_RUNNING, "running"), - NM_UTILS_FLAGS2STR (IFF_LOWER_UP, "lowerup"), - NM_UTILS_FLAGS2STR (IFF_DORMANT, "dormant"), - NM_UTILS_FLAGS2STR (IFF_ECHO, "echo"), -); - -NM_UTILS_ENUM2STR_DEFINE (nm_platform_link_inet6_addrgenmode2str, guint8, - NM_UTILS_ENUM2STR (NM_IN6_ADDR_GEN_MODE_NONE, "none"), - NM_UTILS_ENUM2STR (NM_IN6_ADDR_GEN_MODE_EUI64, "eui64"), - NM_UTILS_ENUM2STR (NM_IN6_ADDR_GEN_MODE_STABLE_PRIVACY, "stable-privacy"), - NM_UTILS_ENUM2STR (NM_IN6_ADDR_GEN_MODE_RANDOM, "random"), -); - -NM_UTILS_FLAGS2STR_DEFINE (nm_platform_addr_flags2str, unsigned, - NM_UTILS_FLAGS2STR (IFA_F_SECONDARY, "secondary"), - NM_UTILS_FLAGS2STR (IFA_F_NODAD, "nodad"), - NM_UTILS_FLAGS2STR (IFA_F_OPTIMISTIC, "optimistic"), - NM_UTILS_FLAGS2STR (IFA_F_HOMEADDRESS, "homeaddress"), - NM_UTILS_FLAGS2STR (IFA_F_DEPRECATED, "deprecated"), - NM_UTILS_FLAGS2STR (IFA_F_PERMANENT, "permanent"), - NM_UTILS_FLAGS2STR (IFA_F_MANAGETEMPADDR, "mngtmpaddr"), - NM_UTILS_FLAGS2STR (IFA_F_NOPREFIXROUTE, "noprefixroute"), - NM_UTILS_FLAGS2STR (IFA_F_TENTATIVE, "tentative"), -); - -NM_UTILS_ENUM2STR_DEFINE (nm_platform_route_scope2str, int, - NM_UTILS_ENUM2STR (RT_SCOPE_NOWHERE, "nowhere"), - NM_UTILS_ENUM2STR (RT_SCOPE_HOST, "host"), - NM_UTILS_ENUM2STR (RT_SCOPE_LINK, "link"), - NM_UTILS_ENUM2STR (RT_SCOPE_SITE, "site"), - NM_UTILS_ENUM2STR (RT_SCOPE_UNIVERSE, "global"), -); +nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf, gsize len) +{ + char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE]; + char s_address[INET_ADDRSTRLEN]; + char s_peer[INET_ADDRSTRLEN]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_label[32]; + char str_lft[30], str_pref[30], str_time[50], s_source[50]; + char * str_peer = NULL; + const char *str_lft_p, *str_pref_p, *str_time_p; + gint32 now = nm_utils_get_monotonic_timestamp_sec(); + in_addr_t broadcast_address; + char str_broadcast[INET_ADDRSTRLEN]; + + if (!nm_utils_to_string_buffer_init_null(address, &buf, &len)) + return buf; + + inet_ntop(AF_INET, &address->address, s_address, sizeof(s_address)); + + if (address->peer_address != address->address) { + inet_ntop(AF_INET, &address->peer_address, s_peer, sizeof(s_peer)); + str_peer = g_strconcat(" ptp ", s_peer, NULL); + } + + _to_string_dev(NULL, address->ifindex, str_dev, sizeof(str_dev)); + + if (*address->label) + g_snprintf(str_label, sizeof(str_label), " label %s", address->label); + else + str_label[0] = 0; + + str_lft_p = _lifetime_to_string(address->timestamp, + address->lifetime ?: NM_PLATFORM_LIFETIME_PERMANENT, + now, + str_lft, + sizeof(str_lft)), + str_pref_p = + (address->lifetime == address->preferred) + ? str_lft_p + : (_lifetime_to_string(address->timestamp, + address->lifetime ? MIN(address->preferred, address->lifetime) + : NM_PLATFORM_LIFETIME_PERMANENT, + now, + str_pref, + sizeof(str_pref))); + str_time_p = _lifetime_summary_to_string(now, + address->timestamp, + address->preferred, + address->lifetime, + str_time, + sizeof(str_time)); + + broadcast_address = nm_platform_ip4_broadcast_address_from_addr(address); + + g_snprintf( + buf, + len, + "%s/%d" + "%s%s" /* broadcast */ + " lft %s" + " pref %s" + "%s" /* time */ + "%s" /* peer */ + "%s" /* dev */ + "%s" /* flags */ + "%s" /* label */ + " src %s" + "%s" /* external */ + "", + s_address, + address->plen, + broadcast_address ? " brd " : "", + broadcast_address ? _nm_utils_inet4_ntop(broadcast_address, str_broadcast) : "", + str_lft_p, + str_pref_p, + str_time_p, + str_peer ?: "", + str_dev, + _to_string_ifa_flags(address->n_ifa_flags, s_flags, sizeof(s_flags)), + str_label, + nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)), + address->external ? " ext" : ""); + g_free(str_peer); + return buf; +} + +NM_UTILS_FLAGS2STR_DEFINE(nm_platform_link_flags2str, + unsigned, + NM_UTILS_FLAGS2STR(IFF_LOOPBACK, "loopback"), + NM_UTILS_FLAGS2STR(IFF_BROADCAST, "broadcast"), + NM_UTILS_FLAGS2STR(IFF_POINTOPOINT, "pointopoint"), + NM_UTILS_FLAGS2STR(IFF_MULTICAST, "multicast"), + NM_UTILS_FLAGS2STR(IFF_NOARP, "noarp"), + NM_UTILS_FLAGS2STR(IFF_ALLMULTI, "allmulti"), + NM_UTILS_FLAGS2STR(IFF_PROMISC, "promisc"), + NM_UTILS_FLAGS2STR(IFF_MASTER, "master"), + NM_UTILS_FLAGS2STR(IFF_SLAVE, "slave"), + NM_UTILS_FLAGS2STR(IFF_DEBUG, "debug"), + NM_UTILS_FLAGS2STR(IFF_DYNAMIC, "dynamic"), + NM_UTILS_FLAGS2STR(IFF_AUTOMEDIA, "automedia"), + NM_UTILS_FLAGS2STR(IFF_PORTSEL, "portsel"), + NM_UTILS_FLAGS2STR(IFF_NOTRAILERS, "notrailers"), + NM_UTILS_FLAGS2STR(IFF_UP, "up"), + NM_UTILS_FLAGS2STR(IFF_RUNNING, "running"), + NM_UTILS_FLAGS2STR(IFF_LOWER_UP, "lowerup"), + NM_UTILS_FLAGS2STR(IFF_DORMANT, "dormant"), + NM_UTILS_FLAGS2STR(IFF_ECHO, "echo"), ); + +NM_UTILS_ENUM2STR_DEFINE(nm_platform_link_inet6_addrgenmode2str, + guint8, + NM_UTILS_ENUM2STR(NM_IN6_ADDR_GEN_MODE_NONE, "none"), + NM_UTILS_ENUM2STR(NM_IN6_ADDR_GEN_MODE_EUI64, "eui64"), + NM_UTILS_ENUM2STR(NM_IN6_ADDR_GEN_MODE_STABLE_PRIVACY, "stable-privacy"), + NM_UTILS_ENUM2STR(NM_IN6_ADDR_GEN_MODE_RANDOM, "random"), ); + +NM_UTILS_FLAGS2STR_DEFINE(nm_platform_addr_flags2str, + unsigned, + NM_UTILS_FLAGS2STR(IFA_F_SECONDARY, "secondary"), + NM_UTILS_FLAGS2STR(IFA_F_NODAD, "nodad"), + NM_UTILS_FLAGS2STR(IFA_F_OPTIMISTIC, "optimistic"), + NM_UTILS_FLAGS2STR(IFA_F_HOMEADDRESS, "homeaddress"), + NM_UTILS_FLAGS2STR(IFA_F_DEPRECATED, "deprecated"), + NM_UTILS_FLAGS2STR(IFA_F_PERMANENT, "permanent"), + NM_UTILS_FLAGS2STR(IFA_F_MANAGETEMPADDR, "mngtmpaddr"), + NM_UTILS_FLAGS2STR(IFA_F_NOPREFIXROUTE, "noprefixroute"), + NM_UTILS_FLAGS2STR(IFA_F_TENTATIVE, "tentative"), ); + +NM_UTILS_ENUM2STR_DEFINE(nm_platform_route_scope2str, + int, + NM_UTILS_ENUM2STR(RT_SCOPE_NOWHERE, "nowhere"), + NM_UTILS_ENUM2STR(RT_SCOPE_HOST, "host"), + NM_UTILS_ENUM2STR(RT_SCOPE_LINK, "link"), + NM_UTILS_ENUM2STR(RT_SCOPE_SITE, "site"), + NM_UTILS_ENUM2STR(RT_SCOPE_UNIVERSE, "global"), ); /** * nm_platform_ip6_address_to_string: @@ -5991,84 +6346,100 @@ NM_UTILS_ENUM2STR_DEFINE (nm_platform_route_scope2str, int, * Returns: a string representation of the address. */ const char * -nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *buf, gsize len) -{ - char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE]; - char s_address[INET6_ADDRSTRLEN]; - char s_peer[INET6_ADDRSTRLEN]; - char str_lft[30], str_pref[30], str_time[50], s_source[50]; - char str_dev[TO_STRING_DEV_BUF_SIZE]; - char *str_peer = NULL; - const char *str_lft_p, *str_pref_p, *str_time_p; - gint32 now = nm_utils_get_monotonic_timestamp_sec (); - - if (!nm_utils_to_string_buffer_init_null (address, &buf, &len)) - return buf; - - inet_ntop (AF_INET6, &address->address, s_address, sizeof (s_address)); - - if (!IN6_IS_ADDR_UNSPECIFIED (&address->peer_address)) { - inet_ntop (AF_INET6, &address->peer_address, s_peer, sizeof (s_peer)); - str_peer = g_strconcat (" ptp ", s_peer, NULL); - } - - _to_string_dev (NULL, address->ifindex, str_dev, sizeof (str_dev)); - - str_lft_p = _lifetime_to_string (address->timestamp, - address->lifetime ?: NM_PLATFORM_LIFETIME_PERMANENT, - now, str_lft, sizeof (str_lft)), - str_pref_p = (address->lifetime == address->preferred) - ? str_lft_p - : ( _lifetime_to_string (address->timestamp, - address->lifetime ? MIN (address->preferred, address->lifetime) : NM_PLATFORM_LIFETIME_PERMANENT, - now, str_pref, sizeof (str_pref)) ); - str_time_p = _lifetime_summary_to_string (now, address->timestamp, address->preferred, address->lifetime, str_time, sizeof (str_time)); - - g_snprintf (buf, len, - "%s/%d lft %s pref %s%s%s%s%s src %s%s", - s_address, address->plen, str_lft_p, str_pref_p, str_time_p, - str_peer ?: "", - str_dev, - _to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)), - nmp_utils_ip_config_source_to_string (address->addr_source, s_source, sizeof (s_source)), - address->external ? " ext" : ""); - g_free (str_peer); - return buf; -} - -static -NM_UTILS_FLAGS2STR_DEFINE (_rtm_flags_to_string, unsigned, - NM_UTILS_FLAGS2STR (RTNH_F_DEAD, "dead"), - NM_UTILS_FLAGS2STR (RTNH_F_PERVASIVE, "pervasive"), - NM_UTILS_FLAGS2STR (RTNH_F_ONLINK, "onlink"), - NM_UTILS_FLAGS2STR (8 /*RTNH_F_OFFLOAD*/, "offload"), - NM_UTILS_FLAGS2STR (16 /*RTNH_F_LINKDOWN*/, "linkdown"), - NM_UTILS_FLAGS2STR (32 /*RTNH_F_UNRESOLVED*/, "unresolved"), - - NM_UTILS_FLAGS2STR (RTM_F_NOTIFY, "notify"), - NM_UTILS_FLAGS2STR (RTM_F_CLONED, "cloned"), - NM_UTILS_FLAGS2STR (RTM_F_EQUALIZE, "equalize"), - NM_UTILS_FLAGS2STR (RTM_F_PREFIX, "prefix"), - NM_UTILS_FLAGS2STR (0x1000 /*RTM_F_LOOKUP_TABLE*/, "lookup-table"), - NM_UTILS_FLAGS2STR (0x2000 /*RTM_F_FIB_MATCH*/, "fib-match"), -); +nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf, gsize len) +{ + char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE]; + char s_address[INET6_ADDRSTRLEN]; + char s_peer[INET6_ADDRSTRLEN]; + char str_lft[30], str_pref[30], str_time[50], s_source[50]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char * str_peer = NULL; + const char *str_lft_p, *str_pref_p, *str_time_p; + gint32 now = nm_utils_get_monotonic_timestamp_sec(); + + if (!nm_utils_to_string_buffer_init_null(address, &buf, &len)) + return buf; + + inet_ntop(AF_INET6, &address->address, s_address, sizeof(s_address)); + + if (!IN6_IS_ADDR_UNSPECIFIED(&address->peer_address)) { + inet_ntop(AF_INET6, &address->peer_address, s_peer, sizeof(s_peer)); + str_peer = g_strconcat(" ptp ", s_peer, NULL); + } + + _to_string_dev(NULL, address->ifindex, str_dev, sizeof(str_dev)); + + str_lft_p = _lifetime_to_string(address->timestamp, + address->lifetime ?: NM_PLATFORM_LIFETIME_PERMANENT, + now, + str_lft, + sizeof(str_lft)), + str_pref_p = + (address->lifetime == address->preferred) + ? str_lft_p + : (_lifetime_to_string(address->timestamp, + address->lifetime ? MIN(address->preferred, address->lifetime) + : NM_PLATFORM_LIFETIME_PERMANENT, + now, + str_pref, + sizeof(str_pref))); + str_time_p = _lifetime_summary_to_string(now, + address->timestamp, + address->preferred, + address->lifetime, + str_time, + sizeof(str_time)); + + g_snprintf( + buf, + len, + "%s/%d lft %s pref %s%s%s%s%s src %s%s", + s_address, + address->plen, + str_lft_p, + str_pref_p, + str_time_p, + str_peer ?: "", + str_dev, + _to_string_ifa_flags(address->n_ifa_flags, s_flags, sizeof(s_flags)), + nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)), + address->external ? " ext" : ""); + g_free(str_peer); + return buf; +} + +static NM_UTILS_FLAGS2STR_DEFINE(_rtm_flags_to_string, + unsigned, + NM_UTILS_FLAGS2STR(RTNH_F_DEAD, "dead"), + NM_UTILS_FLAGS2STR(RTNH_F_PERVASIVE, "pervasive"), + NM_UTILS_FLAGS2STR(RTNH_F_ONLINK, "onlink"), + NM_UTILS_FLAGS2STR(8 /*RTNH_F_OFFLOAD*/, "offload"), + NM_UTILS_FLAGS2STR(16 /*RTNH_F_LINKDOWN*/, "linkdown"), + NM_UTILS_FLAGS2STR(32 /*RTNH_F_UNRESOLVED*/, "unresolved"), + + NM_UTILS_FLAGS2STR(RTM_F_NOTIFY, "notify"), + NM_UTILS_FLAGS2STR(RTM_F_CLONED, "cloned"), + NM_UTILS_FLAGS2STR(RTM_F_EQUALIZE, "equalize"), + NM_UTILS_FLAGS2STR(RTM_F_PREFIX, "prefix"), + NM_UTILS_FLAGS2STR(0x1000 /*RTM_F_LOOKUP_TABLE*/, "lookup-table"), + NM_UTILS_FLAGS2STR(0x2000 /*RTM_F_FIB_MATCH*/, "fib-match"), ); #define _RTM_FLAGS_TO_STRING_MAXLEN 200 static const char * -_rtm_flags_to_string_full (char *buf, gsize buf_size, unsigned rtm_flags) +_rtm_flags_to_string_full(char *buf, gsize buf_size, unsigned rtm_flags) { - const char *buf0 = buf; + const char *buf0 = buf; - nm_assert (buf_size >= _RTM_FLAGS_TO_STRING_MAXLEN); + nm_assert(buf_size >= _RTM_FLAGS_TO_STRING_MAXLEN); - if (!rtm_flags) - return ""; + if (!rtm_flags) + return ""; - nm_utils_strbuf_append_str (&buf, &buf_size, " rtm_flags "); - _rtm_flags_to_string (rtm_flags, buf, buf_size); - nm_assert (strlen (buf) < buf_size); - return buf0; + nm_utils_strbuf_append_str(&buf, &buf_size, " rtm_flags "); + _rtm_flags_to_string(rtm_flags, buf, buf_size); + nm_assert(strlen(buf) < buf_size); + return buf0; } /** @@ -6084,65 +6455,101 @@ _rtm_flags_to_string_full (char *buf, gsize buf_size, unsigned rtm_flags) * Returns: a string representation of the route. */ const char * -nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsize len) -{ - char s_network[INET_ADDRSTRLEN], s_gateway[INET_ADDRSTRLEN]; - char s_pref_src[INET_ADDRSTRLEN]; - char str_dev[TO_STRING_DEV_BUF_SIZE]; - char str_table[30]; - char str_scope[30], s_source[50]; - char str_tos[32], str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32]; - char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; - char str_type[30]; - - if (!nm_utils_to_string_buffer_init_null (route, &buf, &len)) - return buf; - - inet_ntop (AF_INET, &route->network, s_network, sizeof(s_network)); - inet_ntop (AF_INET, &route->gateway, s_gateway, sizeof(s_gateway)); - - _to_string_dev (NULL, route->ifindex, str_dev, sizeof (str_dev)); - - g_snprintf (buf, len, - "type %s " /* type */ - "%s" /* table */ - "%s/%d" - " via %s" - "%s" - " metric %"G_GUINT32_FORMAT - " mss %"G_GUINT32_FORMAT - " rt-src %s" /* protocol */ - "%s" /* rtm_flags */ - "%s%s" /* scope */ - "%s%s" /* pref-src */ - "%s" /* tos */ - "%s" /* window */ - "%s" /* cwnd */ - "%s" /* initcwnd */ - "%s" /* initrwnd */ - "%s" /* mtu */ - "", - nm_utils_route_type2str (nm_platform_route_type_uncoerce (route->type_coerced), str_type, sizeof (str_type)), - route->table_coerced ? nm_sprintf_buf (str_table, "table %u ", nm_platform_route_table_uncoerce (route->table_coerced, FALSE)) : "", - s_network, - route->plen, - s_gateway, - str_dev, - route->metric, - route->mss, - nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)), - _rtm_flags_to_string_full (str_rtm_flags, sizeof (str_rtm_flags), route->r_rtm_flags), - route->scope_inv ? " scope " : "", - route->scope_inv ? (nm_platform_route_scope2str (nm_platform_route_scope_inv (route->scope_inv), str_scope, sizeof (str_scope))) : "", - route->pref_src ? " pref-src " : "", - route->pref_src ? inet_ntop (AF_INET, &route->pref_src, s_pref_src, sizeof(s_pref_src)) : "", - route->tos ? nm_sprintf_buf (str_tos, " tos 0x%x", (unsigned) route->tos) : "", - route->window || route->lock_window ? nm_sprintf_buf (str_window, " window %s%"G_GUINT32_FORMAT, route->lock_window ? "lock " : "", route->window) : "", - route->cwnd || route->lock_cwnd ? nm_sprintf_buf (str_cwnd, " cwnd %s%"G_GUINT32_FORMAT, route->lock_cwnd ? "lock " : "", route->cwnd) : "", - route->initcwnd || route->lock_initcwnd ? nm_sprintf_buf (str_initcwnd, " initcwnd %s%"G_GUINT32_FORMAT, route->lock_initcwnd ? "lock " : "", route->initcwnd) : "", - route->initrwnd || route->lock_initrwnd ? nm_sprintf_buf (str_initrwnd, " initrwnd %s%"G_GUINT32_FORMAT, route->lock_initrwnd ? "lock " : "", route->initrwnd) : "", - route->mtu || route->lock_mtu ? nm_sprintf_buf (str_mtu, " mtu %s%"G_GUINT32_FORMAT, route->lock_mtu ? "lock " : "", route->mtu) : ""); - return buf; +nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsize len) +{ + char s_network[INET_ADDRSTRLEN], s_gateway[INET_ADDRSTRLEN]; + char s_pref_src[INET_ADDRSTRLEN]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_table[30]; + char str_scope[30], s_source[50]; + char str_tos[32], str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32]; + char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; + char str_type[30]; + char str_metric[30]; + + if (!nm_utils_to_string_buffer_init_null(route, &buf, &len)) + return buf; + + inet_ntop(AF_INET, &route->network, s_network, sizeof(s_network)); + inet_ntop(AF_INET, &route->gateway, s_gateway, sizeof(s_gateway)); + + _to_string_dev(NULL, route->ifindex, str_dev, sizeof(str_dev)); + + g_snprintf( + buf, + len, + "type %s " /* type */ + "%s" /* table */ + "%s/%d" + " via %s" + "%s" + " metric %s" + " mss %" G_GUINT32_FORMAT " rt-src %s" /* protocol */ + "%s" /* rtm_flags */ + "%s%s" /* scope */ + "%s%s" /* pref-src */ + "%s" /* tos */ + "%s" /* window */ + "%s" /* cwnd */ + "%s" /* initcwnd */ + "%s" /* initrwnd */ + "%s" /* mtu */ + "", + nm_utils_route_type2str(nm_platform_route_type_uncoerce(route->type_coerced), + str_type, + sizeof(str_type)), + route->table_any + ? "table ?? " + : (route->table_coerced + ? nm_sprintf_buf(str_table, + "table %u ", + nm_platform_route_table_uncoerce(route->table_coerced, FALSE)) + : ""), + s_network, + route->plen, + s_gateway, + str_dev, + route->metric_any ? "??" : nm_sprintf_buf(str_metric, "%u", route->metric), + route->mss, + nmp_utils_ip_config_source_to_string(route->rt_source, s_source, sizeof(s_source)), + _rtm_flags_to_string_full(str_rtm_flags, sizeof(str_rtm_flags), route->r_rtm_flags), + route->scope_inv ? " scope " : "", + route->scope_inv + ? (nm_platform_route_scope2str(nm_platform_route_scope_inv(route->scope_inv), + str_scope, + sizeof(str_scope))) + : "", + route->pref_src ? " pref-src " : "", + route->pref_src ? inet_ntop(AF_INET, &route->pref_src, s_pref_src, sizeof(s_pref_src)) : "", + route->tos ? nm_sprintf_buf(str_tos, " tos 0x%x", (unsigned) route->tos) : "", + route->window || route->lock_window ? nm_sprintf_buf(str_window, + " window %s%" G_GUINT32_FORMAT, + route->lock_window ? "lock " : "", + route->window) + : "", + route->cwnd || route->lock_cwnd ? nm_sprintf_buf(str_cwnd, + " cwnd %s%" G_GUINT32_FORMAT, + route->lock_cwnd ? "lock " : "", + route->cwnd) + : "", + route->initcwnd || route->lock_initcwnd + ? nm_sprintf_buf(str_initcwnd, + " initcwnd %s%" G_GUINT32_FORMAT, + route->lock_initcwnd ? "lock " : "", + route->initcwnd) + : "", + route->initrwnd || route->lock_initrwnd + ? nm_sprintf_buf(str_initrwnd, + " initrwnd %s%" G_GUINT32_FORMAT, + route->lock_initrwnd ? "lock " : "", + route->initrwnd) + : "", + route->mtu || route->lock_mtu ? nm_sprintf_buf(str_mtu, + " mtu %s%" G_GUINT32_FORMAT, + route->lock_mtu ? "lock " : "", + route->mtu) + : ""); + return buf; } /** @@ -6158,1673 +6565,1914 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi * Returns: a string representation of the route. */ const char * -nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsize len) -{ - char s_network[INET6_ADDRSTRLEN]; - char s_gateway[INET6_ADDRSTRLEN]; - char s_pref_src[INET6_ADDRSTRLEN]; - char s_src_all[INET6_ADDRSTRLEN + 40]; - char s_src[INET6_ADDRSTRLEN]; - char str_type[30]; - char str_table[30]; - char str_pref[40]; - char str_pref2[30]; - char str_dev[TO_STRING_DEV_BUF_SIZE]; - char s_source[50]; - char str_window[32]; - char str_cwnd[32]; - char str_initcwnd[32]; - char str_initrwnd[32]; - char str_mtu[32]; - char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; - - if (!nm_utils_to_string_buffer_init_null (route, &buf, &len)) - return buf; - - inet_ntop (AF_INET6, &route->network, s_network, sizeof (s_network)); - inet_ntop (AF_INET6, &route->gateway, s_gateway, sizeof (s_gateway)); - - if (IN6_IS_ADDR_UNSPECIFIED (&route->pref_src)) - s_pref_src[0] = 0; - else - inet_ntop (AF_INET6, &route->pref_src, s_pref_src, sizeof (s_pref_src)); - - _to_string_dev (NULL, route->ifindex, str_dev, sizeof (str_dev)); - - g_snprintf (buf, len, - "type %s " /* type */ - "%s" /* table */ - "%s/%d" - " via %s" - "%s" - " metric %"G_GUINT32_FORMAT - " mss %"G_GUINT32_FORMAT - " rt-src %s" /* protocol */ - "%s" /* source */ - "%s" /* rtm_flags */ - "%s%s" /* pref-src */ - "%s" /* window */ - "%s" /* cwnd */ - "%s" /* initcwnd */ - "%s" /* initrwnd */ - "%s" /* mtu */ - "%s" /* pref */ - "", - nm_utils_route_type2str (nm_platform_route_type_uncoerce (route->type_coerced), str_type, sizeof (str_type)), - route->table_coerced ? nm_sprintf_buf (str_table, "table %u ", nm_platform_route_table_uncoerce (route->table_coerced, FALSE)) : "", - s_network, - route->plen, - s_gateway, - str_dev, - route->metric, - route->mss, - nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)), - route->src_plen || !IN6_IS_ADDR_UNSPECIFIED (&route->src) - ? nm_sprintf_buf (s_src_all, " src %s/%u", _nm_utils_inet6_ntop (&route->src, s_src), (unsigned) route->src_plen) - : "", - _rtm_flags_to_string_full (str_rtm_flags, sizeof (str_rtm_flags), route->r_rtm_flags), - s_pref_src[0] ? " pref-src " : "", - s_pref_src[0] ? s_pref_src : "", - route->window || route->lock_window ? nm_sprintf_buf (str_window, " window %s%"G_GUINT32_FORMAT, route->lock_window ? "lock " : "", route->window) : "", - route->cwnd || route->lock_cwnd ? nm_sprintf_buf (str_cwnd, " cwnd %s%"G_GUINT32_FORMAT, route->lock_cwnd ? "lock " : "", route->cwnd) : "", - route->initcwnd || route->lock_initcwnd ? nm_sprintf_buf (str_initcwnd, " initcwnd %s%"G_GUINT32_FORMAT, route->lock_initcwnd ? "lock " : "", route->initcwnd) : "", - route->initrwnd || route->lock_initrwnd ? nm_sprintf_buf (str_initrwnd, " initrwnd %s%"G_GUINT32_FORMAT, route->lock_initrwnd ? "lock " : "", route->initrwnd) : "", - route->mtu || route->lock_mtu ? nm_sprintf_buf (str_mtu, " mtu %s%"G_GUINT32_FORMAT, route->lock_mtu ? "lock " : "", route->mtu) : "", - route->rt_pref ? nm_sprintf_buf (str_pref, " pref %s", nm_icmpv6_router_pref_to_string (route->rt_pref, str_pref2, sizeof (str_pref2))) : ""); - - return buf; +nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsize len) +{ + char s_network[INET6_ADDRSTRLEN]; + char s_gateway[INET6_ADDRSTRLEN]; + char s_pref_src[INET6_ADDRSTRLEN]; + char s_src_all[INET6_ADDRSTRLEN + 40]; + char s_src[INET6_ADDRSTRLEN]; + char str_type[30]; + char str_table[30]; + char str_pref[40]; + char str_pref2[30]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char s_source[50]; + char str_window[32]; + char str_cwnd[32]; + char str_initcwnd[32]; + char str_initrwnd[32]; + char str_mtu[32]; + char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; + char str_metric[30]; + + if (!nm_utils_to_string_buffer_init_null(route, &buf, &len)) + return buf; + + inet_ntop(AF_INET6, &route->network, s_network, sizeof(s_network)); + inet_ntop(AF_INET6, &route->gateway, s_gateway, sizeof(s_gateway)); + + if (IN6_IS_ADDR_UNSPECIFIED(&route->pref_src)) + s_pref_src[0] = 0; + else + inet_ntop(AF_INET6, &route->pref_src, s_pref_src, sizeof(s_pref_src)); + + _to_string_dev(NULL, route->ifindex, str_dev, sizeof(str_dev)); + + g_snprintf( + buf, + len, + "type %s " /* type */ + "%s" /* table */ + "%s/%d" + " via %s" + "%s" + " metric %s" + " mss %" G_GUINT32_FORMAT " rt-src %s" /* protocol */ + "%s" /* source */ + "%s" /* rtm_flags */ + "%s%s" /* pref-src */ + "%s" /* window */ + "%s" /* cwnd */ + "%s" /* initcwnd */ + "%s" /* initrwnd */ + "%s" /* mtu */ + "%s" /* pref */ + "", + nm_utils_route_type2str(nm_platform_route_type_uncoerce(route->type_coerced), + str_type, + sizeof(str_type)), + route->table_any + ? "table ?? " + : (route->table_coerced + ? nm_sprintf_buf(str_table, + "table %u ", + nm_platform_route_table_uncoerce(route->table_coerced, FALSE)) + : ""), + s_network, + route->plen, + s_gateway, + str_dev, + route->metric_any ? "??" : nm_sprintf_buf(str_metric, "%u", route->metric), + route->mss, + nmp_utils_ip_config_source_to_string(route->rt_source, s_source, sizeof(s_source)), + route->src_plen || !IN6_IS_ADDR_UNSPECIFIED(&route->src) + ? nm_sprintf_buf(s_src_all, + " src %s/%u", + _nm_utils_inet6_ntop(&route->src, s_src), + (unsigned) route->src_plen) + : "", + _rtm_flags_to_string_full(str_rtm_flags, sizeof(str_rtm_flags), route->r_rtm_flags), + s_pref_src[0] ? " pref-src " : "", + s_pref_src[0] ? s_pref_src : "", + route->window || route->lock_window ? nm_sprintf_buf(str_window, + " window %s%" G_GUINT32_FORMAT, + route->lock_window ? "lock " : "", + route->window) + : "", + route->cwnd || route->lock_cwnd ? nm_sprintf_buf(str_cwnd, + " cwnd %s%" G_GUINT32_FORMAT, + route->lock_cwnd ? "lock " : "", + route->cwnd) + : "", + route->initcwnd || route->lock_initcwnd + ? nm_sprintf_buf(str_initcwnd, + " initcwnd %s%" G_GUINT32_FORMAT, + route->lock_initcwnd ? "lock " : "", + route->initcwnd) + : "", + route->initrwnd || route->lock_initrwnd + ? nm_sprintf_buf(str_initrwnd, + " initrwnd %s%" G_GUINT32_FORMAT, + route->lock_initrwnd ? "lock " : "", + route->initrwnd) + : "", + route->mtu || route->lock_mtu ? nm_sprintf_buf(str_mtu, + " mtu %s%" G_GUINT32_FORMAT, + route->lock_mtu ? "lock " : "", + route->mtu) + : "", + route->rt_pref ? nm_sprintf_buf( + str_pref, + " pref %s", + nm_icmpv6_router_pref_to_string(route->rt_pref, str_pref2, sizeof(str_pref2))) + : ""); + + return buf; } static void -_routing_rule_addr_to_string (char **buf, - gsize *len, - int addr_family, - const NMIPAddr *addr, - guint8 plen, - gboolean is_src) +_routing_rule_addr_to_string(char ** buf, + gsize * len, + int addr_family, + const NMIPAddr *addr, + guint8 plen, + gboolean is_src) { - char s_addr[NM_UTILS_INET_ADDRSTRLEN]; - gboolean is_zero; - gsize addr_size; + char s_addr[NM_UTILS_INET_ADDRSTRLEN]; + gboolean is_zero; + gsize addr_size; - nm_assert_addr_family (addr_family); - nm_assert (addr); + nm_assert_addr_family(addr_family); + nm_assert(addr); - addr_size = nm_utils_addr_family_to_size (addr_family); + addr_size = nm_utils_addr_family_to_size(addr_family); - is_zero = nm_utils_memeqzero (addr, addr_size); + is_zero = nm_utils_memeqzero(addr, addr_size); - if ( plen == 0 - && is_zero) { - if (is_src) - nm_utils_strbuf_append_str (buf, len, " from all"); - else - nm_utils_strbuf_append_str (buf, len, ""); - return; - } + if (plen == 0 && is_zero) { + if (is_src) + nm_utils_strbuf_append_str(buf, len, " from all"); + else + nm_utils_strbuf_append_str(buf, len, ""); + return; + } - nm_utils_strbuf_append_str (buf, len, is_src ? " from " : " to "); + nm_utils_strbuf_append_str(buf, len, is_src ? " from " : " to "); - nm_utils_strbuf_append_str (buf, len, nm_utils_inet_ntop (addr_family, addr, s_addr)); + nm_utils_strbuf_append_str(buf, len, nm_utils_inet_ntop(addr_family, addr, s_addr)); - if (plen != (addr_size * 8)) - nm_utils_strbuf_append (buf, len, "/%u", plen); + if (plen != (addr_size * 8)) + nm_utils_strbuf_append(buf, len, "/%u", plen); } static void -_routing_rule_port_range_to_string (char **buf, - gsize *len, - const NMFibRulePortRange *port_range, - const char *name) +_routing_rule_port_range_to_string(char ** buf, + gsize * len, + const NMFibRulePortRange *port_range, + const char * name) { - if ( port_range->start == 0 - && port_range->end == 0) - nm_utils_strbuf_append_str (buf, len, ""); - else { - nm_utils_strbuf_append (buf, len, " %s %u", name, port_range->start); - if (port_range->start != port_range->end) - nm_utils_strbuf_append (buf, len, "-%u", port_range->end); - } + if (port_range->start == 0 && port_range->end == 0) + nm_utils_strbuf_append_str(buf, len, ""); + else { + nm_utils_strbuf_append(buf, len, " %s %u", name, port_range->start); + if (port_range->start != port_range->end) + nm_utils_strbuf_append(buf, len, "-%u", port_range->end); + } } const char * -nm_platform_routing_rule_to_string (const NMPlatformRoutingRule *routing_rule, char *buf, gsize len) -{ - const char *buf0; - guint32 rr_flags; - - if (!nm_utils_to_string_buffer_init_null (routing_rule, &buf, &len)) - return buf; - - if (!NM_IN_SET (routing_rule->addr_family, AF_INET, AF_INET6)) { - /* invalid addr-family. The other fields are undefined. */ - if (routing_rule->addr_family == AF_UNSPEC) - g_snprintf (buf, len, "[routing-rule]"); - else - g_snprintf (buf, len, "[routing-rule family:%u]", routing_rule->addr_family); - return buf; - } - - buf0 = buf; - - rr_flags = routing_rule->flags; - - rr_flags = NM_FLAGS_UNSET (rr_flags, FIB_RULE_INVERT); - nm_utils_strbuf_append (&buf, &len, - "[%c] " /* addr-family */ - "%u:" /* priority */ - "%s", /* not/FIB_RULE_INVERT */ - nm_utils_addr_family_to_char (routing_rule->addr_family), - routing_rule->priority, - ( NM_FLAGS_HAS (routing_rule->flags, FIB_RULE_INVERT) - ? " not" - : "")); - - _routing_rule_addr_to_string (&buf, &len, - routing_rule->addr_family, - &routing_rule->src, - routing_rule->src_len, - TRUE); - - _routing_rule_addr_to_string (&buf, &len, - routing_rule->addr_family, - &routing_rule->dst, - routing_rule->dst_len, - FALSE); - - if (routing_rule->tos) - nm_utils_strbuf_append (&buf, &len, " tos 0x%02x", routing_rule->tos); - - if ( routing_rule->fwmark != 0 - || routing_rule->fwmask != 0) { - nm_utils_strbuf_append (&buf, &len, " fwmark %#x", (unsigned) routing_rule->fwmark); - if (routing_rule->fwmark != 0xFFFFFFFFu) - nm_utils_strbuf_append (&buf, &len, "/%#x", (unsigned) routing_rule->fwmask); - } - - if (routing_rule->iifname[0]) { - nm_utils_strbuf_append (&buf, &len, " iif %s", routing_rule->iifname); - rr_flags = NM_FLAGS_UNSET (rr_flags, FIB_RULE_IIF_DETACHED); - if (NM_FLAGS_HAS (routing_rule->flags, FIB_RULE_IIF_DETACHED)) - nm_utils_strbuf_append_str (&buf, &len, " [detached]"); - } - - if (routing_rule->oifname[0]) { - nm_utils_strbuf_append (&buf, &len, " oif %s", routing_rule->oifname); - rr_flags = NM_FLAGS_UNSET (rr_flags, FIB_RULE_OIF_DETACHED); - if (NM_FLAGS_HAS (routing_rule->flags, FIB_RULE_OIF_DETACHED)) - nm_utils_strbuf_append_str (&buf, &len, " [detached]"); - } - - if (routing_rule->l3mdev != 0) { - if (routing_rule->l3mdev == 1) - nm_utils_strbuf_append_str (&buf, &len, " lookup [l3mdev-table]"); - else { - nm_utils_strbuf_append (&buf, &len, " lookup [l3mdev-table/%u]", (unsigned) routing_rule->l3mdev); - } - } - - if ( routing_rule->uid_range_has - || routing_rule->uid_range.start - || routing_rule->uid_range.end) { - nm_utils_strbuf_append (&buf, &len, - " uidrange %u-%u%s", - routing_rule->uid_range.start, - routing_rule->uid_range.end, - routing_rule->uid_range_has ? "" : "(?)"); - } - - if (routing_rule->ip_proto != 0) { - /* we don't call getprotobynumber(), just print the numeric value. - * This differs from what ip-rule prints. */ - nm_utils_strbuf_append (&buf, &len, - " ipproto %u", - routing_rule->ip_proto); - } - - _routing_rule_port_range_to_string (&buf, &len, - &routing_rule->sport_range, - "sport"); - - _routing_rule_port_range_to_string (&buf, &len, - &routing_rule->dport_range, - "dport"); - - if (routing_rule->tun_id != 0) { - nm_utils_strbuf_append (&buf, &len, - " tun_id %"G_GUINT64_FORMAT, - routing_rule->tun_id); - } - - if (routing_rule->table != 0) { - nm_utils_strbuf_append (&buf, &len, - " lookup %u", - routing_rule->table); - } - - if (routing_rule->suppress_prefixlen_inverse != 0) { - nm_utils_strbuf_append (&buf, &len, - " suppress_prefixlen %d", - (int) (~routing_rule->suppress_prefixlen_inverse)); - } - - if (routing_rule->suppress_ifgroup_inverse != 0) { - nm_utils_strbuf_append (&buf, &len, - " suppress_ifgroup %d", - (int) (~routing_rule->suppress_ifgroup_inverse)); - } - - if (routing_rule->flow) { - /* FRA_FLOW is only for IPv4, but we want to print the value for all address-families, - * to see when it is set. In practice, this should not be set except for IPv4. - * - * We don't follow the style how ip-rule prints flow/realms. It's confusing. Just - * print the value hex. */ - nm_utils_strbuf_append (&buf, &len, - " realms 0x%08x", - routing_rule->flow); - } - - if (routing_rule->action == RTN_NAT) { - G_STATIC_ASSERT_EXPR (RTN_NAT == 10); - - /* NAT is deprecated for many years. We don't support RTA_GATEWAY/FRA_UNUSED2 - * for the gateway, and so do recent kernels ignore that parameter. */ - nm_utils_strbuf_append_str (&buf, &len, " masquerade"); - } else if (routing_rule->action == FR_ACT_GOTO) { - if (routing_rule->goto_target != 0) - nm_utils_strbuf_append (&buf, &len, " goto %u", routing_rule->goto_target); - else - nm_utils_strbuf_append_str (&buf, &len, " goto none"); - rr_flags = NM_FLAGS_UNSET (rr_flags, FIB_RULE_UNRESOLVED); - if (NM_FLAGS_HAS (routing_rule->flags, FIB_RULE_UNRESOLVED)) - nm_utils_strbuf_append_str (&buf, &len, " unresolved"); - } else if (routing_rule->action != FR_ACT_TO_TBL) { - const char *ss; - char ss_buf[60]; - -#define _V(v1, v2) ((sizeof (char[(((int) (v1)) == ((int) (v2))) ? 1 : -1]) * 0) + (v1)) - switch (routing_rule->action) { - case _V (FR_ACT_UNSPEC, RTN_UNSPEC) : ss = "none"; break; - case _V (FR_ACT_TO_TBL, RTN_UNICAST) : ss = "unicast"; break; - case _V (FR_ACT_GOTO, RTN_LOCAL) : ss = "local"; break; - case _V (FR_ACT_NOP, RTN_BROADCAST) : ss = "nop"; break; - case _V (FR_ACT_RES3, RTN_ANYCAST) : ss = "anycast"; break; - case _V (FR_ACT_RES4, RTN_MULTICAST) : ss = "multicast"; break; - case _V (FR_ACT_BLACKHOLE, RTN_BLACKHOLE) : ss = "blackhole"; break; - case _V (FR_ACT_UNREACHABLE, RTN_UNREACHABLE) : ss = "unreachable"; break; - case _V (FR_ACT_PROHIBIT, RTN_PROHIBIT) : ss = "prohibit"; break; - case RTN_THROW : ss = "throw"; break; - case RTN_NAT : ss = "nat"; break; - case RTN_XRESOLVE : ss = "xresolve"; break; - default: - ss = nm_sprintf_buf (ss_buf, "action-%u", routing_rule->action); - break; - } +nm_platform_routing_rule_to_string(const NMPlatformRoutingRule *routing_rule, char *buf, gsize len) +{ + const char *buf0; + guint32 rr_flags; + + if (!nm_utils_to_string_buffer_init_null(routing_rule, &buf, &len)) + return buf; + + if (!NM_IN_SET(routing_rule->addr_family, AF_INET, AF_INET6)) { + /* invalid addr-family. The other fields are undefined. */ + if (routing_rule->addr_family == AF_UNSPEC) + g_snprintf(buf, len, "[routing-rule]"); + else + g_snprintf(buf, len, "[routing-rule family:%u]", routing_rule->addr_family); + return buf; + } + + buf0 = buf; + + rr_flags = routing_rule->flags; + + rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_INVERT); + nm_utils_strbuf_append(&buf, + &len, + "[%c] " /* addr-family */ + "%u:" /* priority */ + "%s", /* not/FIB_RULE_INVERT */ + nm_utils_addr_family_to_char(routing_rule->addr_family), + routing_rule->priority, + (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_INVERT) ? " not" : "")); + + _routing_rule_addr_to_string(&buf, + &len, + routing_rule->addr_family, + &routing_rule->src, + routing_rule->src_len, + TRUE); + + _routing_rule_addr_to_string(&buf, + &len, + routing_rule->addr_family, + &routing_rule->dst, + routing_rule->dst_len, + FALSE); + + if (routing_rule->tos) + nm_utils_strbuf_append(&buf, &len, " tos 0x%02x", routing_rule->tos); + + if (routing_rule->fwmark != 0 || routing_rule->fwmask != 0) { + nm_utils_strbuf_append(&buf, &len, " fwmark %#x", (unsigned) routing_rule->fwmark); + if (routing_rule->fwmark != 0xFFFFFFFFu) + nm_utils_strbuf_append(&buf, &len, "/%#x", (unsigned) routing_rule->fwmask); + } + + if (routing_rule->iifname[0]) { + nm_utils_strbuf_append(&buf, &len, " iif %s", routing_rule->iifname); + rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_IIF_DETACHED); + if (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_IIF_DETACHED)) + nm_utils_strbuf_append_str(&buf, &len, " [detached]"); + } + + if (routing_rule->oifname[0]) { + nm_utils_strbuf_append(&buf, &len, " oif %s", routing_rule->oifname); + rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_OIF_DETACHED); + if (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_OIF_DETACHED)) + nm_utils_strbuf_append_str(&buf, &len, " [detached]"); + } + + if (routing_rule->l3mdev != 0) { + if (routing_rule->l3mdev == 1) + nm_utils_strbuf_append_str(&buf, &len, " lookup [l3mdev-table]"); + else { + nm_utils_strbuf_append(&buf, + &len, + " lookup [l3mdev-table/%u]", + (unsigned) routing_rule->l3mdev); + } + } + + if (routing_rule->uid_range_has || routing_rule->uid_range.start + || routing_rule->uid_range.end) { + nm_utils_strbuf_append(&buf, + &len, + " uidrange %u-%u%s", + routing_rule->uid_range.start, + routing_rule->uid_range.end, + routing_rule->uid_range_has ? "" : "(?)"); + } + + if (routing_rule->ip_proto != 0) { + /* we don't call getprotobynumber(), just print the numeric value. + * This differs from what ip-rule prints. */ + nm_utils_strbuf_append(&buf, &len, " ipproto %u", routing_rule->ip_proto); + } + + _routing_rule_port_range_to_string(&buf, &len, &routing_rule->sport_range, "sport"); + + _routing_rule_port_range_to_string(&buf, &len, &routing_rule->dport_range, "dport"); + + if (routing_rule->tun_id != 0) { + nm_utils_strbuf_append(&buf, &len, " tun_id %" G_GUINT64_FORMAT, routing_rule->tun_id); + } + + if (routing_rule->table != 0) { + nm_utils_strbuf_append(&buf, &len, " lookup %u", routing_rule->table); + } + + if (routing_rule->suppress_prefixlen_inverse != 0) { + nm_utils_strbuf_append(&buf, + &len, + " suppress_prefixlen %d", + (int) (~routing_rule->suppress_prefixlen_inverse)); + } + + if (routing_rule->suppress_ifgroup_inverse != 0) { + nm_utils_strbuf_append(&buf, + &len, + " suppress_ifgroup %d", + (int) (~routing_rule->suppress_ifgroup_inverse)); + } + + if (routing_rule->flow) { + /* FRA_FLOW is only for IPv4, but we want to print the value for all address-families, + * to see when it is set. In practice, this should not be set except for IPv4. + * + * We don't follow the style how ip-rule prints flow/realms. It's confusing. Just + * print the value hex. */ + nm_utils_strbuf_append(&buf, &len, " realms 0x%08x", routing_rule->flow); + } + + if (routing_rule->action == RTN_NAT) { + G_STATIC_ASSERT_EXPR(RTN_NAT == 10); + + /* NAT is deprecated for many years. We don't support RTA_GATEWAY/FRA_UNUSED2 + * for the gateway, and so do recent kernels ignore that parameter. */ + nm_utils_strbuf_append_str(&buf, &len, " masquerade"); + } else if (routing_rule->action == FR_ACT_GOTO) { + if (routing_rule->goto_target != 0) + nm_utils_strbuf_append(&buf, &len, " goto %u", routing_rule->goto_target); + else + nm_utils_strbuf_append_str(&buf, &len, " goto none"); + rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_UNRESOLVED); + if (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_UNRESOLVED)) + nm_utils_strbuf_append_str(&buf, &len, " unresolved"); + } else if (routing_rule->action != FR_ACT_TO_TBL) { + const char *ss; + char ss_buf[60]; + +#define _V(v1, v2) ((sizeof(char[(((int) (v1)) == ((int) (v2))) ? 1 : -1]) * 0) + (v1)) + switch (routing_rule->action) { + case _V(FR_ACT_UNSPEC, RTN_UNSPEC): + ss = "none"; + break; + case _V(FR_ACT_TO_TBL, RTN_UNICAST): + ss = "unicast"; + break; + case _V(FR_ACT_GOTO, RTN_LOCAL): + ss = "local"; + break; + case _V(FR_ACT_NOP, RTN_BROADCAST): + ss = "nop"; + break; + case _V(FR_ACT_RES3, RTN_ANYCAST): + ss = "anycast"; + break; + case _V(FR_ACT_RES4, RTN_MULTICAST): + ss = "multicast"; + break; + case _V(FR_ACT_BLACKHOLE, RTN_BLACKHOLE): + ss = "blackhole"; + break; + case _V(FR_ACT_UNREACHABLE, RTN_UNREACHABLE): + ss = "unreachable"; + break; + case _V(FR_ACT_PROHIBIT, RTN_PROHIBIT): + ss = "prohibit"; + break; + case RTN_THROW: + ss = "throw"; + break; + case RTN_NAT: + ss = "nat"; + break; + case RTN_XRESOLVE: + ss = "xresolve"; + break; + default: + ss = nm_sprintf_buf(ss_buf, "action-%u", routing_rule->action); + break; + } #undef _V - nm_utils_strbuf_append (&buf, &len, " %s", ss); - } + nm_utils_strbuf_append(&buf, &len, " %s", ss); + } - if (routing_rule->protocol != RTPROT_UNSPEC) - nm_utils_strbuf_append (&buf, &len, " protocol %u", routing_rule->protocol); + if (routing_rule->protocol != RTPROT_UNSPEC) + nm_utils_strbuf_append(&buf, &len, " protocol %u", routing_rule->protocol); - if ( routing_rule->goto_target != 0 - && routing_rule->action != FR_ACT_GOTO) { - /* a trailing target is set for an unexpected action. Print it. */ - nm_utils_strbuf_append (&buf, &len, " goto-target %u", routing_rule->goto_target); - } + if (routing_rule->goto_target != 0 && routing_rule->action != FR_ACT_GOTO) { + /* a trailing target is set for an unexpected action. Print it. */ + nm_utils_strbuf_append(&buf, &len, " goto-target %u", routing_rule->goto_target); + } - if (rr_flags != 0) { - /* we have some flags we didn't print about yet. */ - nm_utils_strbuf_append (&buf, &len, " remaining-flags %x", rr_flags); - } + if (rr_flags != 0) { + /* we have some flags we didn't print about yet. */ + nm_utils_strbuf_append(&buf, &len, " remaining-flags %x", rr_flags); + } - return buf0; + return buf0; } const char * -nm_platform_qdisc_to_string (const NMPlatformQdisc *qdisc, char *buf, gsize len) -{ - char str_dev[TO_STRING_DEV_BUF_SIZE]; - const char *buf0; - - if (!nm_utils_to_string_buffer_init_null (qdisc, &buf, &len)) - return buf; - - buf0 = buf; - - nm_utils_strbuf_append (&buf, &len, "%s%s family %u handle %x parent %x info %x", - qdisc->kind, - _to_string_dev (NULL, qdisc->ifindex, str_dev, sizeof (str_dev)), - qdisc->addr_family, - qdisc->handle, - qdisc->parent, - qdisc->info); - - if (nm_streq0 (qdisc->kind, "fq_codel")) { - if (qdisc->fq_codel.limit) - nm_utils_strbuf_append (&buf, &len, " limit %u", qdisc->fq_codel.limit); - if (qdisc->fq_codel.flows) - nm_utils_strbuf_append (&buf, &len, " flows %u", qdisc->fq_codel.flows); - if (qdisc->fq_codel.target) - nm_utils_strbuf_append (&buf, &len, " target %u", qdisc->fq_codel.target); - if (qdisc->fq_codel.interval) - nm_utils_strbuf_append (&buf, &len, " interval %u", qdisc->fq_codel.interval); - if (qdisc->fq_codel.quantum) - nm_utils_strbuf_append (&buf, &len, " quantum %u", qdisc->fq_codel.quantum); - if (qdisc->fq_codel.ce_threshold != NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED) - nm_utils_strbuf_append (&buf, &len, " ce_threshold %u", qdisc->fq_codel.ce_threshold); - if (qdisc->fq_codel.memory_limit != NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET) - nm_utils_strbuf_append (&buf, &len, " memory_limit %u", qdisc->fq_codel.memory_limit); - if (qdisc->fq_codel.ecn) - nm_utils_strbuf_append (&buf, &len, " ecn"); - } else if (nm_streq0 (qdisc->kind, "sfq")) { - if (qdisc->sfq.quantum) - nm_utils_strbuf_append (&buf, &len, " quantum %u", qdisc->sfq.quantum); - if (qdisc->sfq.perturb_period) - nm_utils_strbuf_append (&buf, &len, " perturb %d", qdisc->sfq.perturb_period); - if (qdisc->sfq.limit) - nm_utils_strbuf_append (&buf, &len, " limit %u", (guint) qdisc->sfq.limit); - if (qdisc->sfq.divisor) - nm_utils_strbuf_append (&buf, &len, " divisor %u", qdisc->sfq.divisor); - if (qdisc->sfq.flows) - nm_utils_strbuf_append (&buf, &len, " flows %u", qdisc->sfq.flows); - if (qdisc->sfq.depth) - nm_utils_strbuf_append (&buf, &len, " depth %u", qdisc->sfq.depth); - } else if (nm_streq0 (qdisc->kind, "tbf")) { - nm_utils_strbuf_append (&buf, &len, " rate %"G_GUINT64_FORMAT, qdisc->tbf.rate); - nm_utils_strbuf_append (&buf, &len, " burst %u", qdisc->tbf.burst); - if (qdisc->tbf.limit) - nm_utils_strbuf_append (&buf, &len, " limit %u", qdisc->tbf.limit); - if (qdisc->tbf.latency) - nm_utils_strbuf_append (&buf, &len, " latency %uns", qdisc->tbf.latency); - } - - return buf0; +nm_platform_qdisc_to_string(const NMPlatformQdisc *qdisc, char *buf, gsize len) +{ + char str_dev[TO_STRING_DEV_BUF_SIZE]; + const char *buf0; + + if (!nm_utils_to_string_buffer_init_null(qdisc, &buf, &len)) + return buf; + + buf0 = buf; + + nm_utils_strbuf_append(&buf, + &len, + "%s%s family %u handle %x parent %x info %x", + qdisc->kind, + _to_string_dev(NULL, qdisc->ifindex, str_dev, sizeof(str_dev)), + qdisc->addr_family, + qdisc->handle, + qdisc->parent, + qdisc->info); + + if (nm_streq0(qdisc->kind, "fq_codel")) { + if (qdisc->fq_codel.limit) + nm_utils_strbuf_append(&buf, &len, " limit %u", qdisc->fq_codel.limit); + if (qdisc->fq_codel.flows) + nm_utils_strbuf_append(&buf, &len, " flows %u", qdisc->fq_codel.flows); + if (qdisc->fq_codel.target) + nm_utils_strbuf_append(&buf, &len, " target %u", qdisc->fq_codel.target); + if (qdisc->fq_codel.interval) + nm_utils_strbuf_append(&buf, &len, " interval %u", qdisc->fq_codel.interval); + if (qdisc->fq_codel.quantum) + nm_utils_strbuf_append(&buf, &len, " quantum %u", qdisc->fq_codel.quantum); + if (qdisc->fq_codel.ce_threshold != NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED) + nm_utils_strbuf_append(&buf, &len, " ce_threshold %u", qdisc->fq_codel.ce_threshold); + if (qdisc->fq_codel.memory_limit != NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET) + nm_utils_strbuf_append(&buf, &len, " memory_limit %u", qdisc->fq_codel.memory_limit); + if (qdisc->fq_codel.ecn) + nm_utils_strbuf_append(&buf, &len, " ecn"); + } else if (nm_streq0(qdisc->kind, "sfq")) { + if (qdisc->sfq.quantum) + nm_utils_strbuf_append(&buf, &len, " quantum %u", qdisc->sfq.quantum); + if (qdisc->sfq.perturb_period) + nm_utils_strbuf_append(&buf, &len, " perturb %d", qdisc->sfq.perturb_period); + if (qdisc->sfq.limit) + nm_utils_strbuf_append(&buf, &len, " limit %u", (guint) qdisc->sfq.limit); + if (qdisc->sfq.divisor) + nm_utils_strbuf_append(&buf, &len, " divisor %u", qdisc->sfq.divisor); + if (qdisc->sfq.flows) + nm_utils_strbuf_append(&buf, &len, " flows %u", qdisc->sfq.flows); + if (qdisc->sfq.depth) + nm_utils_strbuf_append(&buf, &len, " depth %u", qdisc->sfq.depth); + } else if (nm_streq0(qdisc->kind, "tbf")) { + nm_utils_strbuf_append(&buf, &len, " rate %" G_GUINT64_FORMAT, qdisc->tbf.rate); + nm_utils_strbuf_append(&buf, &len, " burst %u", qdisc->tbf.burst); + if (qdisc->tbf.limit) + nm_utils_strbuf_append(&buf, &len, " limit %u", qdisc->tbf.limit); + if (qdisc->tbf.latency) + nm_utils_strbuf_append(&buf, &len, " latency %uns", qdisc->tbf.latency); + } + + return buf0; } void -nm_platform_qdisc_hash_update (const NMPlatformQdisc *obj, NMHashState *h) -{ - nm_hash_update_str0 (h, obj->kind); - nm_hash_update_vals (h, - obj->ifindex, - obj->addr_family, - obj->handle, - obj->parent, - obj->info); - if (nm_streq0 (obj->kind, "fq_codel")) { - nm_hash_update_vals (h, - obj->fq_codel.limit, - obj->fq_codel.flows, - obj->fq_codel.target, - obj->fq_codel.interval, - obj->fq_codel.quantum, - obj->fq_codel.ce_threshold, - obj->fq_codel.memory_limit, - NM_HASH_COMBINE_BOOLS (guint8, - obj->fq_codel.ecn)); - } else if (nm_streq0 (obj->kind, "sfq")) { - nm_hash_update_vals (h, - obj->sfq.quantum, - obj->sfq.perturb_period, - obj->sfq.limit, - obj->sfq.divisor, - obj->sfq.flows, - obj->sfq.depth); - } else if (nm_streq0 (obj->kind, "tbf")) { - nm_hash_update_vals (h, - obj->tbf.rate, - obj->tbf.burst, - obj->tbf.limit, - obj->tbf.latency); - } +nm_platform_qdisc_hash_update(const NMPlatformQdisc *obj, NMHashState *h) +{ + nm_hash_update_str0(h, obj->kind); + nm_hash_update_vals(h, obj->ifindex, obj->addr_family, obj->handle, obj->parent, obj->info); + if (nm_streq0(obj->kind, "fq_codel")) { + nm_hash_update_vals(h, + obj->fq_codel.limit, + obj->fq_codel.flows, + obj->fq_codel.target, + obj->fq_codel.interval, + obj->fq_codel.quantum, + obj->fq_codel.ce_threshold, + obj->fq_codel.memory_limit, + NM_HASH_COMBINE_BOOLS(guint8, obj->fq_codel.ecn)); + } else if (nm_streq0(obj->kind, "sfq")) { + nm_hash_update_vals(h, + obj->sfq.quantum, + obj->sfq.perturb_period, + obj->sfq.limit, + obj->sfq.divisor, + obj->sfq.flows, + obj->sfq.depth); + } else if (nm_streq0(obj->kind, "tbf")) { + nm_hash_update_vals(h, obj->tbf.rate, obj->tbf.burst, obj->tbf.limit, obj->tbf.latency); + } } int -nm_platform_qdisc_cmp_full (const NMPlatformQdisc *a, - const NMPlatformQdisc *b, - gboolean compare_handle) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, ifindex); - NM_CMP_FIELD (a, b, parent); - NM_CMP_FIELD_STR_INTERNED (a, b, kind); - NM_CMP_FIELD (a, b, addr_family); - if (compare_handle) - NM_CMP_FIELD (a, b, handle); - NM_CMP_FIELD (a, b, info); - - if (nm_streq0 (a->kind, "fq_codel")) { - NM_CMP_FIELD (a, b, fq_codel.limit); - NM_CMP_FIELD (a, b, fq_codel.flows); - NM_CMP_FIELD (a, b, fq_codel.target); - NM_CMP_FIELD (a, b, fq_codel.interval); - NM_CMP_FIELD (a, b, fq_codel.quantum); - NM_CMP_FIELD (a, b, fq_codel.ce_threshold); - NM_CMP_FIELD (a, b, fq_codel.memory_limit); - NM_CMP_FIELD_UNSAFE (a, b, fq_codel.ecn); - } else if (nm_streq0 (a->kind, "sfq")) { - NM_CMP_FIELD (a, b, sfq.quantum); - NM_CMP_FIELD (a, b, sfq.perturb_period); - NM_CMP_FIELD (a, b, sfq.limit); - NM_CMP_FIELD (a, b, sfq.flows); - NM_CMP_FIELD (a, b, sfq.divisor); - NM_CMP_FIELD (a, b, sfq.depth); - } else if (nm_streq0 (a->kind, "tbf")) { - NM_CMP_FIELD (a, b, tbf.rate); - NM_CMP_FIELD (a, b, tbf.burst); - NM_CMP_FIELD (a, b, tbf.limit); - NM_CMP_FIELD (a, b, tbf.latency); - } - - return 0; +nm_platform_qdisc_cmp_full(const NMPlatformQdisc *a, + const NMPlatformQdisc *b, + gboolean compare_handle) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, parent); + NM_CMP_FIELD_STR_INTERNED(a, b, kind); + NM_CMP_FIELD(a, b, addr_family); + if (compare_handle) + NM_CMP_FIELD(a, b, handle); + NM_CMP_FIELD(a, b, info); + + if (nm_streq0(a->kind, "fq_codel")) { + NM_CMP_FIELD(a, b, fq_codel.limit); + NM_CMP_FIELD(a, b, fq_codel.flows); + NM_CMP_FIELD(a, b, fq_codel.target); + NM_CMP_FIELD(a, b, fq_codel.interval); + NM_CMP_FIELD(a, b, fq_codel.quantum); + NM_CMP_FIELD(a, b, fq_codel.ce_threshold); + NM_CMP_FIELD(a, b, fq_codel.memory_limit); + NM_CMP_FIELD_UNSAFE(a, b, fq_codel.ecn); + } else if (nm_streq0(a->kind, "sfq")) { + NM_CMP_FIELD(a, b, sfq.quantum); + NM_CMP_FIELD(a, b, sfq.perturb_period); + NM_CMP_FIELD(a, b, sfq.limit); + NM_CMP_FIELD(a, b, sfq.flows); + NM_CMP_FIELD(a, b, sfq.divisor); + NM_CMP_FIELD(a, b, sfq.depth); + } else if (nm_streq0(a->kind, "tbf")) { + NM_CMP_FIELD(a, b, tbf.rate); + NM_CMP_FIELD(a, b, tbf.burst); + NM_CMP_FIELD(a, b, tbf.limit); + NM_CMP_FIELD(a, b, tbf.latency); + } + + return 0; } int -nm_platform_qdisc_cmp (const NMPlatformQdisc *a, const NMPlatformQdisc *b) +nm_platform_qdisc_cmp(const NMPlatformQdisc *a, const NMPlatformQdisc *b) { - return nm_platform_qdisc_cmp_full (a, b, TRUE); + return nm_platform_qdisc_cmp_full(a, b, TRUE); } const char * -nm_platform_tfilter_to_string (const NMPlatformTfilter *tfilter, char *buf, gsize len) -{ - char str_dev[TO_STRING_DEV_BUF_SIZE]; - char act_buf[300]; - char *p; - gsize l; - - if (!nm_utils_to_string_buffer_init_null (tfilter, &buf, &len)) - return buf; - - if (tfilter->action.kind) { - p = act_buf; - l = sizeof (act_buf); - - nm_utils_strbuf_append (&p, &l, " \"%s\"", tfilter->action.kind); - if (nm_streq (tfilter->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { - gs_free char *t = NULL; - - nm_utils_strbuf_append (&p, &l, - " (\"%s\")", - nm_utils_str_utf8safe_escape (tfilter->action.kind, - NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL - | NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII, - &t)); - } else if (nm_streq (tfilter->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { - nm_utils_strbuf_append (&p, &l, "%s%s%s%s dev %d", - tfilter->action.mirred.ingress ? " ingress" : "", - tfilter->action.mirred.egress ? " egress" : "", - tfilter->action.mirred.mirror ? " mirror" : "", - tfilter->action.mirred.redirect ? " redirect" : "", - tfilter->action.mirred.ifindex); - } - } else - act_buf[0] = '\0'; - - g_snprintf (buf, len, "%s%s family %u handle %x parent %x info %x%s", - tfilter->kind, - _to_string_dev (NULL, tfilter->ifindex, str_dev, sizeof (str_dev)), - tfilter->addr_family, - tfilter->handle, - tfilter->parent, - tfilter->info, - act_buf); - - return buf; +nm_platform_tfilter_to_string(const NMPlatformTfilter *tfilter, char *buf, gsize len) +{ + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char act_buf[300]; + char *p; + gsize l; + + if (!nm_utils_to_string_buffer_init_null(tfilter, &buf, &len)) + return buf; + + if (tfilter->action.kind) { + p = act_buf; + l = sizeof(act_buf); + + nm_utils_strbuf_append(&p, &l, " \"%s\"", tfilter->action.kind); + if (nm_streq(tfilter->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { + gs_free char *t = NULL; + + nm_utils_strbuf_append( + &p, + &l, + " (\"%s\")", + nm_utils_str_utf8safe_escape(tfilter->action.kind, + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL + | NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII, + &t)); + } else if (nm_streq(tfilter->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { + nm_utils_strbuf_append(&p, + &l, + "%s%s%s%s dev %d", + tfilter->action.mirred.ingress ? " ingress" : "", + tfilter->action.mirred.egress ? " egress" : "", + tfilter->action.mirred.mirror ? " mirror" : "", + tfilter->action.mirred.redirect ? " redirect" : "", + tfilter->action.mirred.ifindex); + } + } else + act_buf[0] = '\0'; + + g_snprintf(buf, + len, + "%s%s family %u handle %x parent %x info %x%s", + tfilter->kind, + _to_string_dev(NULL, tfilter->ifindex, str_dev, sizeof(str_dev)), + tfilter->addr_family, + tfilter->handle, + tfilter->parent, + tfilter->info, + act_buf); + + return buf; } void -nm_platform_tfilter_hash_update (const NMPlatformTfilter *obj, NMHashState *h) -{ - nm_hash_update_str0 (h, obj->kind); - nm_hash_update_vals (h, - obj->ifindex, - obj->addr_family, - obj->handle, - obj->parent, - obj->info); - if (obj->action.kind) { - nm_hash_update_str (h, obj->action.kind); - if (nm_streq (obj->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { - nm_hash_update_strarr (h, obj->action.simple.sdata); - } else if (nm_streq (obj->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { - nm_hash_update_vals (h, - obj->action.mirred.ifindex, - NM_HASH_COMBINE_BOOLS (guint8, - obj->action.mirred.ingress, - obj->action.mirred.egress, - obj->action.mirred.mirror, - obj->action.mirred.redirect)); - } - } +nm_platform_tfilter_hash_update(const NMPlatformTfilter *obj, NMHashState *h) +{ + nm_hash_update_str0(h, obj->kind); + nm_hash_update_vals(h, obj->ifindex, obj->addr_family, obj->handle, obj->parent, obj->info); + if (obj->action.kind) { + nm_hash_update_str(h, obj->action.kind); + if (nm_streq(obj->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { + nm_hash_update_strarr(h, obj->action.simple.sdata); + } else if (nm_streq(obj->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { + nm_hash_update_vals(h, + obj->action.mirred.ifindex, + NM_HASH_COMBINE_BOOLS(guint8, + obj->action.mirred.ingress, + obj->action.mirred.egress, + obj->action.mirred.mirror, + obj->action.mirred.redirect)); + } + } } int -nm_platform_tfilter_cmp (const NMPlatformTfilter *a, const NMPlatformTfilter *b) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, ifindex); - NM_CMP_FIELD (a, b, parent); - NM_CMP_FIELD_STR_INTERNED (a, b, kind); - NM_CMP_FIELD (a, b, addr_family); - NM_CMP_FIELD (a, b, handle); - NM_CMP_FIELD (a, b, info); - - NM_CMP_FIELD_STR_INTERNED (a, b, action.kind); - if (a->action.kind) { - if (nm_streq (a->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { - NM_CMP_FIELD_STR (a, b, action.simple.sdata); - } else if (nm_streq (a->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { - NM_CMP_FIELD (a, b, action.mirred.ifindex); - NM_CMP_FIELD_UNSAFE (a, b, action.mirred.ingress); - NM_CMP_FIELD_UNSAFE (a, b, action.mirred.egress); - NM_CMP_FIELD_UNSAFE (a, b, action.mirred.mirror); - NM_CMP_FIELD_UNSAFE (a, b, action.mirred.redirect); - } - } - - return 0; +nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, parent); + NM_CMP_FIELD_STR_INTERNED(a, b, kind); + NM_CMP_FIELD(a, b, addr_family); + NM_CMP_FIELD(a, b, handle); + NM_CMP_FIELD(a, b, info); + + NM_CMP_FIELD_STR_INTERNED(a, b, action.kind); + if (a->action.kind) { + if (nm_streq(a->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { + NM_CMP_FIELD_STR(a, b, action.simple.sdata); + } else if (nm_streq(a->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { + NM_CMP_FIELD(a, b, action.mirred.ifindex); + NM_CMP_FIELD_UNSAFE(a, b, action.mirred.ingress); + NM_CMP_FIELD_UNSAFE(a, b, action.mirred.egress); + NM_CMP_FIELD_UNSAFE(a, b, action.mirred.mirror); + NM_CMP_FIELD_UNSAFE(a, b, action.mirred.redirect); + } + } + + return 0; } const char * -nm_platform_vf_to_string (const NMPlatformVF *vf, char *buf, gsize len) -{ - char str_mac[128], mac[128]; - char str_spoof_check[64]; - char str_trust[64]; - char str_min_tx_rate[64]; - char str_max_tx_rate[64]; - nm_auto_free_gstring GString *gstr_vlans = NULL; - guint i; - - if (!nm_utils_to_string_buffer_init_null (vf, &buf, &len)) - return buf; - - if (vf->mac.len) { - nm_utils_hwaddr_ntoa_buf (vf->mac.data, vf->mac.len, TRUE, mac, sizeof (mac)); - nm_sprintf_buf (str_mac, " mac %s", mac); - } else - str_mac[0] = '\0'; - - if (vf->num_vlans) { - gstr_vlans = g_string_new (""); - for (i = 0; i < vf->num_vlans; i++) { - g_string_append_printf (gstr_vlans, " vlan %u", (unsigned) vf->vlans[i].id); - if (vf->vlans[i].qos) - g_string_append_printf (gstr_vlans, " qos %u", (unsigned) vf->vlans[i].qos); - if (vf->vlans[i].proto_ad) - g_string_append (gstr_vlans, " proto 802.1ad"); - } - } - - g_snprintf (buf, len, - "%u" /* index */ - "%s" /* MAC */ - "%s" /* spoof check */ - "%s" /* trust */ - "%s" /* min tx rate */ - "%s" /* max tx rate */ - "%s", /* VLANs */ - vf->index, - str_mac, - vf->spoofchk >= 0 ? nm_sprintf_buf (str_spoof_check, " spoofchk %d", vf->spoofchk) : "", - vf->trust >= 0 ? nm_sprintf_buf (str_trust, " trust %d", vf->trust) : "", - vf->min_tx_rate ? nm_sprintf_buf (str_min_tx_rate, " min_tx_rate %u", (unsigned) vf->min_tx_rate) : "", - vf->max_tx_rate ? nm_sprintf_buf (str_max_tx_rate, " max_tx_rate %u", (unsigned) vf->max_tx_rate) : "", - gstr_vlans ? gstr_vlans->str : ""); - - return buf; +nm_platform_vf_to_string(const NMPlatformVF *vf, char *buf, gsize len) +{ + char str_mac[128], mac[128]; + char str_spoof_check[64]; + char str_trust[64]; + char str_min_tx_rate[64]; + char str_max_tx_rate[64]; + nm_auto_free_gstring GString *gstr_vlans = NULL; + guint i; + + if (!nm_utils_to_string_buffer_init_null(vf, &buf, &len)) + return buf; + + if (vf->mac.len) { + _nm_utils_hwaddr_ntoa(vf->mac.data, vf->mac.len, TRUE, mac, sizeof(mac)); + nm_sprintf_buf(str_mac, " mac %s", mac); + } else + str_mac[0] = '\0'; + + if (vf->num_vlans) { + gstr_vlans = g_string_new(""); + for (i = 0; i < vf->num_vlans; i++) { + g_string_append_printf(gstr_vlans, " vlan %u", (unsigned) vf->vlans[i].id); + if (vf->vlans[i].qos) + g_string_append_printf(gstr_vlans, " qos %u", (unsigned) vf->vlans[i].qos); + if (vf->vlans[i].proto_ad) + g_string_append(gstr_vlans, " proto 802.1ad"); + } + } + + g_snprintf(buf, + len, + "%u" /* index */ + "%s" /* MAC */ + "%s" /* spoof check */ + "%s" /* trust */ + "%s" /* min tx rate */ + "%s" /* max tx rate */ + "%s", /* VLANs */ + vf->index, + str_mac, + vf->spoofchk >= 0 ? nm_sprintf_buf(str_spoof_check, " spoofchk %d", vf->spoofchk) + : "", + vf->trust >= 0 ? nm_sprintf_buf(str_trust, " trust %d", vf->trust) : "", + vf->min_tx_rate + ? nm_sprintf_buf(str_min_tx_rate, " min_tx_rate %u", (unsigned) vf->min_tx_rate) + : "", + vf->max_tx_rate + ? nm_sprintf_buf(str_max_tx_rate, " max_tx_rate %u", (unsigned) vf->max_tx_rate) + : "", + gstr_vlans ? gstr_vlans->str : ""); + + return buf; } - const char * -nm_platform_bridge_vlan_to_string (const NMPlatformBridgeVlan *vlan, char *buf, gsize len) +nm_platform_bridge_vlan_to_string(const NMPlatformBridgeVlan *vlan, char *buf, gsize len) { - char str_vid_end[64]; + char str_vid_end[64]; - if (!nm_utils_to_string_buffer_init_null (vlan, &buf, &len)) - return buf; + if (!nm_utils_to_string_buffer_init_null(vlan, &buf, &len)) + return buf; - g_snprintf (buf, len, - "%u" - "%s" - "%s" - "%s", - vlan->vid_start, - vlan->vid_start != vlan->vid_end ? nm_sprintf_buf (str_vid_end, "-%u", vlan->vid_end) : "", - vlan->pvid ? " PVID" : "", - vlan->untagged ? " untagged" : ""); + g_snprintf(buf, + len, + "%u" + "%s" + "%s" + "%s", + vlan->vid_start, + vlan->vid_start != vlan->vid_end ? nm_sprintf_buf(str_vid_end, "-%u", vlan->vid_end) + : "", + vlan->pvid ? " PVID" : "", + vlan->untagged ? " untagged" : ""); - return buf; + return buf; } void -nm_platform_link_hash_update (const NMPlatformLink *obj, NMHashState *h) -{ - nm_hash_update_vals (h, - obj->ifindex, - obj->master, - obj->parent, - obj->n_ifi_flags, - obj->mtu, - obj->type, - obj->arptype, - obj->inet6_addr_gen_mode_inv, - obj->inet6_token, - obj->rx_packets, - obj->rx_bytes, - obj->tx_packets, - obj->tx_bytes, - NM_HASH_COMBINE_BOOLS (guint8, - obj->connected, - obj->initialized)); - nm_hash_update_strarr (h, obj->name); - nm_hash_update_str0 (h, obj->kind); - nm_hash_update_str0 (h, obj->driver); - /* nm_hash_update_mem() also hashes the length obj->addr.len */ - nm_hash_update_mem (h, obj->l_address.data, NM_MIN (obj->l_address.len, sizeof (obj->l_address.data))); - nm_hash_update_mem (h, obj->l_broadcast.data, NM_MIN (obj->l_broadcast.len, sizeof (obj->l_broadcast.data))); +nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->ifindex, + obj->master, + obj->parent, + obj->n_ifi_flags, + obj->mtu, + obj->type, + obj->arptype, + obj->inet6_addr_gen_mode_inv, + obj->inet6_token, + obj->rx_packets, + obj->rx_bytes, + obj->tx_packets, + obj->tx_bytes, + NM_HASH_COMBINE_BOOLS(guint8, obj->connected, obj->initialized)); + nm_hash_update_strarr(h, obj->name); + nm_hash_update_str0(h, obj->kind); + nm_hash_update_str0(h, obj->driver); + /* nm_hash_update_mem() also hashes the length obj->addr.len */ + nm_hash_update_mem(h, + obj->l_address.data, + NM_MIN(obj->l_address.len, sizeof(obj->l_address.data))); + nm_hash_update_mem(h, + obj->l_broadcast.data, + NM_MIN(obj->l_broadcast.len, sizeof(obj->l_broadcast.data))); } int -nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, ifindex); - NM_CMP_FIELD (a, b, type); - NM_CMP_FIELD_STR (a, b, name); - NM_CMP_FIELD (a, b, master); - NM_CMP_FIELD (a, b, parent); - NM_CMP_FIELD (a, b, n_ifi_flags); - NM_CMP_FIELD_UNSAFE (a, b, connected); - NM_CMP_FIELD (a, b, mtu); - NM_CMP_FIELD_BOOL (a, b, initialized); - NM_CMP_FIELD (a, b, arptype); - NM_CMP_FIELD (a, b, l_address.len); - NM_CMP_FIELD (a, b, l_broadcast.len); - NM_CMP_FIELD (a, b, inet6_addr_gen_mode_inv); - NM_CMP_FIELD_STR_INTERNED (a, b, kind); - NM_CMP_FIELD_STR_INTERNED (a, b, driver); - if (a->l_address.len) - NM_CMP_FIELD_MEMCMP_LEN (a, b, l_address.data, a->l_address.len); - if (a->l_broadcast.len) - NM_CMP_FIELD_MEMCMP_LEN (a, b, l_broadcast.data, a->l_broadcast.len); - NM_CMP_FIELD_MEMCMP (a, b, inet6_token); - NM_CMP_FIELD (a, b, rx_packets); - NM_CMP_FIELD (a, b, rx_bytes); - NM_CMP_FIELD (a, b, tx_packets); - NM_CMP_FIELD (a, b, tx_bytes); - return 0; +nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, type); + NM_CMP_FIELD_STR(a, b, name); + NM_CMP_FIELD(a, b, master); + NM_CMP_FIELD(a, b, parent); + NM_CMP_FIELD(a, b, n_ifi_flags); + NM_CMP_FIELD_UNSAFE(a, b, connected); + NM_CMP_FIELD(a, b, mtu); + NM_CMP_FIELD_BOOL(a, b, initialized); + NM_CMP_FIELD(a, b, arptype); + NM_CMP_FIELD(a, b, l_address.len); + NM_CMP_FIELD(a, b, l_broadcast.len); + NM_CMP_FIELD(a, b, inet6_addr_gen_mode_inv); + NM_CMP_FIELD_STR_INTERNED(a, b, kind); + NM_CMP_FIELD_STR_INTERNED(a, b, driver); + if (a->l_address.len) + NM_CMP_FIELD_MEMCMP_LEN(a, b, l_address.data, a->l_address.len); + if (a->l_broadcast.len) + NM_CMP_FIELD_MEMCMP_LEN(a, b, l_broadcast.data, a->l_broadcast.len); + NM_CMP_FIELD_MEMCMP(a, b, inet6_token); + NM_CMP_FIELD(a, b, rx_packets); + NM_CMP_FIELD(a, b, rx_bytes); + NM_CMP_FIELD(a, b, tx_packets); + NM_CMP_FIELD(a, b, tx_bytes); + return 0; } void -nm_platform_lnk_gre_hash_update (const NMPlatformLnkGre *obj, NMHashState *h) -{ - nm_hash_update_vals (h, - obj->local, - obj->remote, - obj->parent_ifindex, - obj->input_flags, - obj->output_flags, - obj->input_key, - obj->output_key, - obj->ttl, - obj->tos, - (bool) obj->path_mtu_discovery, - (bool) obj->is_tap); +nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->forward_delay, + obj->hello_time, + obj->max_age, + obj->ageing_time, + obj->priority, + obj->vlan_protocol, + obj->group_fwd_mask, + obj->group_addr, + obj->mcast_hash_max, + obj->mcast_last_member_count, + obj->mcast_startup_query_count, + obj->mcast_last_member_interval, + obj->mcast_membership_interval, + obj->mcast_querier_interval, + obj->mcast_query_interval, + obj->mcast_router, + obj->mcast_query_response_interval, + obj->mcast_startup_query_interval, + NM_HASH_COMBINE_BOOLS(guint8, + obj->stp_state, + obj->mcast_querier, + obj->mcast_query_use_ifaddr, + obj->mcast_snooping, + obj->vlan_stats_enabled)); } int -nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, parent_ifindex); - NM_CMP_FIELD (a, b, input_flags); - NM_CMP_FIELD (a, b, output_flags); - NM_CMP_FIELD (a, b, input_key); - NM_CMP_FIELD (a, b, output_key); - NM_CMP_FIELD (a, b, local); - NM_CMP_FIELD (a, b, remote); - NM_CMP_FIELD (a, b, ttl); - NM_CMP_FIELD (a, b, tos); - NM_CMP_FIELD_BOOL (a, b, path_mtu_discovery); - NM_CMP_FIELD_BOOL (a, b, is_tap); - return 0; +nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, forward_delay); + NM_CMP_FIELD(a, b, hello_time); + NM_CMP_FIELD(a, b, max_age); + NM_CMP_FIELD(a, b, ageing_time); + NM_CMP_FIELD_BOOL(a, b, stp_state); + NM_CMP_FIELD(a, b, priority); + NM_CMP_FIELD(a, b, vlan_protocol); + NM_CMP_FIELD_BOOL(a, b, vlan_stats_enabled); + NM_CMP_FIELD(a, b, group_fwd_mask); + NM_CMP_FIELD_MEMCMP(a, b, group_addr); + NM_CMP_FIELD_BOOL(a, b, mcast_snooping); + NM_CMP_FIELD(a, b, mcast_router); + NM_CMP_FIELD_BOOL(a, b, mcast_query_use_ifaddr); + NM_CMP_FIELD_BOOL(a, b, mcast_querier); + NM_CMP_FIELD(a, b, mcast_hash_max); + NM_CMP_FIELD(a, b, mcast_last_member_count); + NM_CMP_FIELD(a, b, mcast_startup_query_count); + NM_CMP_FIELD(a, b, mcast_last_member_interval); + NM_CMP_FIELD(a, b, mcast_membership_interval); + NM_CMP_FIELD(a, b, mcast_querier_interval); + NM_CMP_FIELD(a, b, mcast_query_interval); + NM_CMP_FIELD(a, b, mcast_query_response_interval); + NM_CMP_FIELD(a, b, mcast_startup_query_interval); + + return 0; } void -nm_platform_lnk_infiniband_hash_update (const NMPlatformLnkInfiniband *obj, NMHashState *h) +nm_platform_lnk_gre_hash_update(const NMPlatformLnkGre *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->input_flags, + obj->output_flags, + obj->input_key, + obj->output_key, + obj->ttl, + obj->tos, + (bool) obj->path_mtu_discovery, + (bool) obj->is_tap); +} + +int +nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, input_flags); + NM_CMP_FIELD(a, b, output_flags); + NM_CMP_FIELD(a, b, input_key); + NM_CMP_FIELD(a, b, output_key); + NM_CMP_FIELD(a, b, local); + NM_CMP_FIELD(a, b, remote); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD_BOOL(a, b, path_mtu_discovery); + NM_CMP_FIELD_BOOL(a, b, is_tap); + return 0; +} + +void +nm_platform_lnk_infiniband_hash_update(const NMPlatformLnkInfiniband *obj, NMHashState *h) { - nm_hash_update_val (h, obj->p_key); - nm_hash_update_str0 (h, obj->mode); + nm_hash_update_val(h, obj->p_key); + nm_hash_update_str0(h, obj->mode); } int -nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b) +nm_platform_lnk_infiniband_cmp(const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b) { - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, p_key); - NM_CMP_FIELD_STR_INTERNED (a, b, mode); - return 0; + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, p_key); + NM_CMP_FIELD_STR_INTERNED(a, b, mode); + return 0; } void -nm_platform_lnk_ip6tnl_hash_update (const NMPlatformLnkIp6Tnl *obj, NMHashState *h) -{ - nm_hash_update_vals (h, - obj->local, - obj->remote, - obj->parent_ifindex, - obj->ttl, - obj->tclass, - obj->encap_limit, - obj->proto, - obj->flow_label, - obj->flags, - obj->input_flags, - obj->output_flags, - obj->input_key, - obj->output_key, - (bool) obj->is_gre, - (bool) obj->is_tap); +nm_platform_lnk_ip6tnl_hash_update(const NMPlatformLnkIp6Tnl *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->ttl, + obj->tclass, + obj->encap_limit, + obj->proto, + obj->flow_label, + obj->flags, + obj->input_flags, + obj->output_flags, + obj->input_key, + obj->output_key, + (bool) obj->is_gre, + (bool) obj->is_tap); } int -nm_platform_lnk_ip6tnl_cmp (const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6Tnl *b) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, parent_ifindex); - NM_CMP_FIELD_MEMCMP (a, b, local); - NM_CMP_FIELD_MEMCMP (a, b, remote); - NM_CMP_FIELD (a, b, ttl); - NM_CMP_FIELD (a, b, tclass); - NM_CMP_FIELD (a, b, encap_limit); - NM_CMP_FIELD (a, b, flow_label); - NM_CMP_FIELD (a, b, proto); - NM_CMP_FIELD (a, b, flags); - NM_CMP_FIELD (a, b, input_flags); - NM_CMP_FIELD (a, b, output_flags); - NM_CMP_FIELD (a, b, input_key); - NM_CMP_FIELD (a, b, output_key); - NM_CMP_FIELD_BOOL (a, b, is_gre); - NM_CMP_FIELD_BOOL (a, b, is_tap); - return 0; +nm_platform_lnk_ip6tnl_cmp(const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6Tnl *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD_MEMCMP(a, b, local); + NM_CMP_FIELD_MEMCMP(a, b, remote); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD(a, b, tclass); + NM_CMP_FIELD(a, b, encap_limit); + NM_CMP_FIELD(a, b, flow_label); + NM_CMP_FIELD(a, b, proto); + NM_CMP_FIELD(a, b, flags); + NM_CMP_FIELD(a, b, input_flags); + NM_CMP_FIELD(a, b, output_flags); + NM_CMP_FIELD(a, b, input_key); + NM_CMP_FIELD(a, b, output_key); + NM_CMP_FIELD_BOOL(a, b, is_gre); + NM_CMP_FIELD_BOOL(a, b, is_tap); + return 0; } void -nm_platform_lnk_ipip_hash_update (const NMPlatformLnkIpIp *obj, NMHashState *h) +nm_platform_lnk_ipip_hash_update(const NMPlatformLnkIpIp *obj, NMHashState *h) { - nm_hash_update_vals (h, - obj->local, - obj->remote, - obj->parent_ifindex, - obj->ttl, - obj->tos, - (bool) obj->path_mtu_discovery); + nm_hash_update_vals(h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->ttl, + obj->tos, + (bool) obj->path_mtu_discovery); } int -nm_platform_lnk_ipip_cmp (const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b) +nm_platform_lnk_ipip_cmp(const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b) { - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, parent_ifindex); - NM_CMP_FIELD (a, b, local); - NM_CMP_FIELD (a, b, remote); - NM_CMP_FIELD (a, b, ttl); - NM_CMP_FIELD (a, b, tos); - NM_CMP_FIELD_BOOL (a, b, path_mtu_discovery); - return 0; + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, local); + NM_CMP_FIELD(a, b, remote); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD_BOOL(a, b, path_mtu_discovery); + return 0; } void -nm_platform_lnk_macsec_hash_update (const NMPlatformLnkMacsec *obj, NMHashState *h) -{ - nm_hash_update_vals (h, - obj->parent_ifindex, - obj->sci, - obj->cipher_suite, - obj->window, - obj->icv_length, - obj->encoding_sa, - obj->validation, - NM_HASH_COMBINE_BOOLS (guint8, - obj->encrypt, - obj->protect, - obj->include_sci, - obj->es, - obj->scb, - obj->replay_protect)); +nm_platform_lnk_macsec_hash_update(const NMPlatformLnkMacsec *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->parent_ifindex, + obj->sci, + obj->cipher_suite, + obj->window, + obj->icv_length, + obj->encoding_sa, + obj->validation, + NM_HASH_COMBINE_BOOLS(guint8, + obj->encrypt, + obj->protect, + obj->include_sci, + obj->es, + obj->scb, + obj->replay_protect)); } int -nm_platform_lnk_macsec_cmp (const NMPlatformLnkMacsec *a, const NMPlatformLnkMacsec *b) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, parent_ifindex); - NM_CMP_FIELD (a, b, sci); - NM_CMP_FIELD (a, b, icv_length); - NM_CMP_FIELD (a, b, cipher_suite); - NM_CMP_FIELD (a, b, window); - NM_CMP_FIELD (a, b, encoding_sa); - NM_CMP_FIELD (a, b, validation); - NM_CMP_FIELD_UNSAFE (a, b, encrypt); - NM_CMP_FIELD_UNSAFE (a, b, protect); - NM_CMP_FIELD_UNSAFE (a, b, include_sci); - NM_CMP_FIELD_UNSAFE (a, b, es); - NM_CMP_FIELD_UNSAFE (a, b, scb); - NM_CMP_FIELD_UNSAFE (a, b, replay_protect); - return 0; +nm_platform_lnk_macsec_cmp(const NMPlatformLnkMacsec *a, const NMPlatformLnkMacsec *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, sci); + NM_CMP_FIELD(a, b, icv_length); + NM_CMP_FIELD(a, b, cipher_suite); + NM_CMP_FIELD(a, b, window); + NM_CMP_FIELD(a, b, encoding_sa); + NM_CMP_FIELD(a, b, validation); + NM_CMP_FIELD_UNSAFE(a, b, encrypt); + NM_CMP_FIELD_UNSAFE(a, b, protect); + NM_CMP_FIELD_UNSAFE(a, b, include_sci); + NM_CMP_FIELD_UNSAFE(a, b, es); + NM_CMP_FIELD_UNSAFE(a, b, scb); + NM_CMP_FIELD_UNSAFE(a, b, replay_protect); + return 0; } void -nm_platform_lnk_macvlan_hash_update (const NMPlatformLnkMacvlan *obj, NMHashState *h ) +nm_platform_lnk_macvlan_hash_update(const NMPlatformLnkMacvlan *obj, NMHashState *h) { - nm_hash_update_vals (h, - obj->mode, - NM_HASH_COMBINE_BOOLS (guint8, - obj->no_promisc, - obj->tap)); + nm_hash_update_vals(h, obj->mode, NM_HASH_COMBINE_BOOLS(guint8, obj->no_promisc, obj->tap)); } int -nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b) +nm_platform_lnk_macvlan_cmp(const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b) { - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, mode); - NM_CMP_FIELD_UNSAFE (a, b, no_promisc); - NM_CMP_FIELD_UNSAFE (a, b, tap); - return 0; + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, mode); + NM_CMP_FIELD_UNSAFE(a, b, no_promisc); + NM_CMP_FIELD_UNSAFE(a, b, tap); + return 0; } void -nm_platform_lnk_sit_hash_update (const NMPlatformLnkSit *obj, NMHashState *h) +nm_platform_lnk_sit_hash_update(const NMPlatformLnkSit *obj, NMHashState *h) { - nm_hash_update_vals (h, - obj->local, - obj->remote, - obj->parent_ifindex, - obj->flags, - obj->ttl, - obj->tos, - obj->proto, - (bool) obj->path_mtu_discovery); + nm_hash_update_vals(h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->flags, + obj->ttl, + obj->tos, + obj->proto, + (bool) obj->path_mtu_discovery); } int -nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b) +nm_platform_lnk_sit_cmp(const NMPlatformLnkSit *a, const NMPlatformLnkSit *b) { - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, parent_ifindex); - NM_CMP_FIELD (a, b, local); - NM_CMP_FIELD (a, b, remote); - NM_CMP_FIELD (a, b, ttl); - NM_CMP_FIELD (a, b, tos); - NM_CMP_FIELD_BOOL (a, b, path_mtu_discovery); - NM_CMP_FIELD (a, b, flags); - NM_CMP_FIELD (a, b, proto); - return 0; + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, local); + NM_CMP_FIELD(a, b, remote); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD_BOOL(a, b, path_mtu_discovery); + NM_CMP_FIELD(a, b, flags); + NM_CMP_FIELD(a, b, proto); + return 0; } void -nm_platform_lnk_tun_hash_update (const NMPlatformLnkTun *obj, NMHashState *h) +nm_platform_lnk_tun_hash_update(const NMPlatformLnkTun *obj, NMHashState *h) { - nm_hash_update_vals (h, - obj->type, - obj->owner, - obj->group, - NM_HASH_COMBINE_BOOLS (guint8, - obj->owner_valid, - obj->group_valid, - obj->pi, - obj->vnet_hdr, - obj->multi_queue, - obj->persist)); + nm_hash_update_vals(h, + obj->type, + obj->owner, + obj->group, + NM_HASH_COMBINE_BOOLS(guint8, + obj->owner_valid, + obj->group_valid, + obj->pi, + obj->vnet_hdr, + obj->multi_queue, + obj->persist)); } int -nm_platform_lnk_tun_cmp (const NMPlatformLnkTun *a, const NMPlatformLnkTun *b) +nm_platform_lnk_tun_cmp(const NMPlatformLnkTun *a, const NMPlatformLnkTun *b) { - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, type); - NM_CMP_FIELD (a, b, owner); - NM_CMP_FIELD (a, b, group); - NM_CMP_FIELD_BOOL (a, b, owner_valid); - NM_CMP_FIELD_BOOL (a, b, group_valid); - NM_CMP_FIELD_BOOL (a, b, pi); - NM_CMP_FIELD_BOOL (a, b, vnet_hdr); - NM_CMP_FIELD_BOOL (a, b, multi_queue); - NM_CMP_FIELD_BOOL (a, b, persist); - return 0; + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, type); + NM_CMP_FIELD(a, b, owner); + NM_CMP_FIELD(a, b, group); + NM_CMP_FIELD_BOOL(a, b, owner_valid); + NM_CMP_FIELD_BOOL(a, b, group_valid); + NM_CMP_FIELD_BOOL(a, b, pi); + NM_CMP_FIELD_BOOL(a, b, vnet_hdr); + NM_CMP_FIELD_BOOL(a, b, multi_queue); + NM_CMP_FIELD_BOOL(a, b, persist); + return 0; } void -nm_platform_lnk_vlan_hash_update (const NMPlatformLnkVlan *obj, NMHashState *h) +nm_platform_lnk_vlan_hash_update(const NMPlatformLnkVlan *obj, NMHashState *h) { - nm_hash_update_vals (h, - obj->id, - obj->flags); + nm_hash_update_vals(h, obj->id, obj->flags); } int -nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b) +nm_platform_lnk_vlan_cmp(const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b) { - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, id); - NM_CMP_FIELD (a, b, flags); - return 0; + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, id); + NM_CMP_FIELD(a, b, flags); + return 0; } void -nm_platform_lnk_vrf_hash_update (const NMPlatformLnkVrf *obj, NMHashState *h) +nm_platform_lnk_vrf_hash_update(const NMPlatformLnkVrf *obj, NMHashState *h) { - nm_hash_update_vals (h, - obj->table); + nm_hash_update_vals(h, obj->table); } int -nm_platform_lnk_vrf_cmp (const NMPlatformLnkVrf *a, const NMPlatformLnkVrf *b) +nm_platform_lnk_vrf_cmp(const NMPlatformLnkVrf *a, const NMPlatformLnkVrf *b) { - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, table); - return 0; + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, table); + return 0; } void -nm_platform_lnk_vxlan_hash_update (const NMPlatformLnkVxlan *obj, NMHashState *h) -{ - nm_hash_update_vals (h, - obj->group6, - obj->local6, - obj->group, - obj->local, - obj->parent_ifindex, - obj->id, - obj->ageing, - obj->limit, - obj->dst_port, - obj->src_port_min, - obj->src_port_max, - obj->tos, - obj->ttl, - NM_HASH_COMBINE_BOOLS (guint8, - obj->learning, - obj->proxy, - obj->rsc, - obj->l2miss, - obj->l3miss)); +nm_platform_lnk_vxlan_hash_update(const NMPlatformLnkVxlan *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->group6, + obj->local6, + obj->group, + obj->local, + obj->parent_ifindex, + obj->id, + obj->ageing, + obj->limit, + obj->dst_port, + obj->src_port_min, + obj->src_port_max, + obj->tos, + obj->ttl, + NM_HASH_COMBINE_BOOLS(guint8, + obj->learning, + obj->proxy, + obj->rsc, + obj->l2miss, + obj->l3miss)); } int -nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, parent_ifindex); - NM_CMP_FIELD (a, b, id); - NM_CMP_FIELD (a, b, group); - NM_CMP_FIELD (a, b, local); - NM_CMP_FIELD_MEMCMP (a, b, group6); - NM_CMP_FIELD_MEMCMP (a, b, local6); - NM_CMP_FIELD (a, b, tos); - NM_CMP_FIELD (a, b, ttl); - NM_CMP_FIELD_BOOL (a, b, learning); - NM_CMP_FIELD (a, b, ageing); - NM_CMP_FIELD (a, b, limit); - NM_CMP_FIELD (a, b, dst_port); - NM_CMP_FIELD (a, b, src_port_min); - NM_CMP_FIELD (a, b, src_port_max); - NM_CMP_FIELD_BOOL (a, b, proxy); - NM_CMP_FIELD_BOOL (a, b, rsc); - NM_CMP_FIELD_BOOL (a, b, l2miss); - NM_CMP_FIELD_BOOL (a, b, l3miss); - return 0; +nm_platform_lnk_vxlan_cmp(const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, id); + NM_CMP_FIELD(a, b, group); + NM_CMP_FIELD(a, b, local); + NM_CMP_FIELD_MEMCMP(a, b, group6); + NM_CMP_FIELD_MEMCMP(a, b, local6); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD_BOOL(a, b, learning); + NM_CMP_FIELD(a, b, ageing); + NM_CMP_FIELD(a, b, limit); + NM_CMP_FIELD(a, b, dst_port); + NM_CMP_FIELD(a, b, src_port_min); + NM_CMP_FIELD(a, b, src_port_max); + NM_CMP_FIELD_BOOL(a, b, proxy); + NM_CMP_FIELD_BOOL(a, b, rsc); + NM_CMP_FIELD_BOOL(a, b, l2miss); + NM_CMP_FIELD_BOOL(a, b, l3miss); + return 0; } void -nm_platform_lnk_wireguard_hash_update (const NMPlatformLnkWireGuard *obj, NMHashState *h) +nm_platform_lnk_wireguard_hash_update(const NMPlatformLnkWireGuard *obj, NMHashState *h) { - nm_hash_update_vals (h, - obj->listen_port, - obj->fwmark); - nm_hash_update (h, obj->private_key, sizeof (obj->private_key)); - nm_hash_update (h, obj->public_key, sizeof (obj->public_key)); + nm_hash_update_vals(h, obj->listen_port, obj->fwmark); + nm_hash_update(h, obj->private_key, sizeof(obj->private_key)); + nm_hash_update(h, obj->public_key, sizeof(obj->public_key)); } int -nm_platform_lnk_wireguard_cmp (const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b) +nm_platform_lnk_wireguard_cmp(const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b) { - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, listen_port); - NM_CMP_FIELD (a, b, fwmark); - NM_CMP_FIELD_MEMCMP (a, b, private_key); - NM_CMP_FIELD_MEMCMP (a, b, public_key); - return 0; + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, listen_port); + NM_CMP_FIELD(a, b, fwmark); + NM_CMP_FIELD_MEMCMP(a, b, private_key); + NM_CMP_FIELD_MEMCMP(a, b, public_key); + return 0; +} + +static int +_address_pretty_sort_get_prio_4(in_addr_t addr) +{ + if (nm_utils_ip4_address_is_link_local(addr)) + return 0; + return 1; +} + +int +nm_platform_ip4_address_pretty_sort_cmp(const NMPlatformIP4Address *a1, + const NMPlatformIP4Address *a2) +{ + in_addr_t n1; + in_addr_t n2; + + nm_assert(a1); + nm_assert(a2); + + /* Sort by address type. For example link local will + * be sorted *after* a global address. */ + NM_CMP_DIRECT(_address_pretty_sort_get_prio_4(a2->address), + _address_pretty_sort_get_prio_4(a1->address)); + + /* Sort the addresses based on their source. */ + NM_CMP_DIRECT(a2->addr_source, a1->addr_source); + + NM_CMP_DIRECT((a2->label[0] == '\0'), (a1->label[0] == '\0')); + + /* Finally, sort addresses lexically. We compare only the + * network part so that the order of addresses in the same + * subnet (and thus also the primary/secondary role) is + * preserved. + */ + n1 = a1->address & _nm_utils_ip4_prefix_to_netmask(a1->plen); + n2 = a2->address & _nm_utils_ip4_prefix_to_netmask(a2->plen); + NM_CMP_DIRECT_MEMCMP(&n1, &n2, sizeof(guint32)); + return 0; +} + +static int +_address_pretty_sort_get_prio_6(const struct in6_addr *addr) +{ + if (IN6_IS_ADDR_V4MAPPED(addr)) + return 0; + if (IN6_IS_ADDR_V4COMPAT(addr)) + return 1; + if (IN6_IS_ADDR_UNSPECIFIED(addr)) + return 2; + if (IN6_IS_ADDR_LOOPBACK(addr)) + return 3; + if (IN6_IS_ADDR_LINKLOCAL(addr)) + return 4; + if (IN6_IS_ADDR_SITELOCAL(addr)) + return 5; + return 6; +} + +int +nm_platform_ip6_address_pretty_sort_cmp(const NMPlatformIP6Address *a1, + const NMPlatformIP6Address *a2, + gboolean prefer_temp) +{ + gboolean ipv6_privacy1; + gboolean ipv6_privacy2; + + nm_assert(a1); + nm_assert(a2); + + /* tentative addresses are always sorted back... */ + /* sort tentative addresses after non-tentative. */ + NM_CMP_DIRECT(NM_FLAGS_HAS(a1->n_ifa_flags, IFA_F_TENTATIVE), + NM_FLAGS_HAS(a2->n_ifa_flags, IFA_F_TENTATIVE)); + + /* Sort by address type. For example link local will + * be sorted *after* site local or global. */ + NM_CMP_DIRECT(_address_pretty_sort_get_prio_6(&a2->address), + _address_pretty_sort_get_prio_6(&a1->address)); + + ipv6_privacy1 = NM_FLAGS_ANY(a1->n_ifa_flags, IFA_F_MANAGETEMPADDR | IFA_F_TEMPORARY); + ipv6_privacy2 = NM_FLAGS_ANY(a2->n_ifa_flags, IFA_F_MANAGETEMPADDR | IFA_F_TEMPORARY); + if (ipv6_privacy1 || ipv6_privacy2) { + gboolean public1 = TRUE; + gboolean public2 = TRUE; + + if (ipv6_privacy1) { + if (a1->n_ifa_flags & IFA_F_TEMPORARY) + public1 = prefer_temp; + else + public1 = !prefer_temp; + } + if (ipv6_privacy2) { + if (a2->n_ifa_flags & IFA_F_TEMPORARY) + public2 = prefer_temp; + else + public2 = !prefer_temp; + } + + NM_CMP_DIRECT(public2, public1); + } + + /* Sort the addresses based on their source. */ + NM_CMP_DIRECT(a2->addr_source, a1->addr_source); + + /* sort permanent addresses before non-permanent. */ + NM_CMP_DIRECT(NM_FLAGS_HAS(a2->n_ifa_flags, IFA_F_PERMANENT), + NM_FLAGS_HAS(a1->n_ifa_flags, IFA_F_PERMANENT)); + + /* finally sort addresses lexically */ + NM_CMP_DIRECT_IN6ADDR(&a1->address, &a2->address); + NM_CMP_DIRECT_MEMCMP(a1, a2, sizeof(*a1)); + return 0; } void -nm_platform_ip4_address_hash_update (const NMPlatformIP4Address *obj, NMHashState *h) -{ - nm_hash_update_vals (h, - obj->ifindex, - obj->addr_source, - nm_platform_ip4_broadcast_address_from_addr (obj), - obj->timestamp, - obj->lifetime, - obj->preferred, - obj->n_ifa_flags, - obj->plen, - obj->address, - obj->peer_address, - NM_HASH_COMBINE_BOOLS (guint8, obj->external)); - nm_hash_update_strarr (h, obj->label); +nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->ifindex, + obj->addr_source, + nm_platform_ip4_broadcast_address_from_addr(obj), + obj->timestamp, + obj->lifetime, + obj->preferred, + obj->n_ifa_flags, + obj->plen, + obj->address, + obj->peer_address, + NM_HASH_COMBINE_BOOLS(guint8, obj->external)); + nm_hash_update_strarr(h, obj->label); } int -nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, ifindex); - NM_CMP_FIELD (a, b, address); - NM_CMP_FIELD (a, b, plen); - NM_CMP_FIELD (a, b, peer_address); - NM_CMP_DIRECT (nm_platform_ip4_broadcast_address_from_addr (a), nm_platform_ip4_broadcast_address_from_addr (b)); - NM_CMP_FIELD (a, b, addr_source); - NM_CMP_FIELD (a, b, timestamp); - NM_CMP_FIELD (a, b, lifetime); - NM_CMP_FIELD (a, b, preferred); - NM_CMP_FIELD (a, b, n_ifa_flags); - NM_CMP_FIELD_STR (a, b, label); - NM_CMP_FIELD_UNSAFE (a, b, external); - return 0; +nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a, const NMPlatformIP4Address *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, address); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD(a, b, peer_address); + NM_CMP_DIRECT(nm_platform_ip4_broadcast_address_from_addr(a), + nm_platform_ip4_broadcast_address_from_addr(b)); + NM_CMP_FIELD(a, b, addr_source); + NM_CMP_FIELD(a, b, timestamp); + NM_CMP_FIELD(a, b, lifetime); + NM_CMP_FIELD(a, b, preferred); + NM_CMP_FIELD(a, b, n_ifa_flags); + NM_CMP_FIELD_STR(a, b, label); + NM_CMP_FIELD_UNSAFE(a, b, external); + return 0; } void -nm_platform_ip6_address_hash_update (const NMPlatformIP6Address *obj, NMHashState *h) +nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h) { - nm_hash_update_vals (h, - obj->ifindex, - obj->addr_source, - obj->timestamp, - obj->lifetime, - obj->preferred, - obj->n_ifa_flags, - obj->plen, - obj->address, - obj->peer_address, - NM_HASH_COMBINE_BOOLS (guint8, obj->external)); + nm_hash_update_vals(h, + obj->ifindex, + obj->addr_source, + obj->timestamp, + obj->lifetime, + obj->preferred, + obj->n_ifa_flags, + obj->plen, + obj->address, + obj->peer_address, + NM_HASH_COMBINE_BOOLS(guint8, obj->external)); } int -nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b) -{ - const struct in6_addr *p_a, *p_b; - - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, ifindex); - NM_CMP_FIELD_MEMCMP (a, b, address); - NM_CMP_FIELD (a, b, plen); - p_a = nm_platform_ip6_address_get_peer (a); - p_b = nm_platform_ip6_address_get_peer (b); - NM_CMP_DIRECT_MEMCMP (p_a, p_b, sizeof (*p_a)); - NM_CMP_FIELD (a, b, addr_source); - NM_CMP_FIELD (a, b, timestamp); - NM_CMP_FIELD (a, b, lifetime); - NM_CMP_FIELD (a, b, preferred); - NM_CMP_FIELD (a, b, n_ifa_flags); - NM_CMP_FIELD_UNSAFE (a, b, external); - return 0; +nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a, const NMPlatformIP6Address *b) +{ + const struct in6_addr *p_a, *p_b; + + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD_MEMCMP(a, b, address); + NM_CMP_FIELD(a, b, plen); + p_a = nm_platform_ip6_address_get_peer(a); + p_b = nm_platform_ip6_address_get_peer(b); + NM_CMP_DIRECT_MEMCMP(p_a, p_b, sizeof(*p_a)); + NM_CMP_FIELD(a, b, addr_source); + NM_CMP_FIELD(a, b, timestamp); + NM_CMP_FIELD(a, b, lifetime); + NM_CMP_FIELD(a, b, preferred); + NM_CMP_FIELD(a, b, n_ifa_flags); + NM_CMP_FIELD_UNSAFE(a, b, external); + return 0; } void -nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h) -{ - switch (cmp_type) { - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: - nm_hash_update_vals (h, - nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), - nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), - obj->plen, - obj->metric, - obj->tos); - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - nm_hash_update_vals (h, - obj->type_coerced, - nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), - nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), - obj->plen, - obj->metric, - obj->tos, - /* on top of WEAK_ID: */ - obj->ifindex, - nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source), - _ip_route_scope_inv_get_normalized (obj), - obj->gateway, - obj->mss, - obj->pref_src, - obj->window, - obj->cwnd, - obj->initcwnd, - obj->initrwnd, - obj->mtu, - obj->r_rtm_flags & RTNH_F_ONLINK, - NM_HASH_COMBINE_BOOLS (guint8, - obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu)); - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: - nm_hash_update_vals (h, - obj->type_coerced, - nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), - obj->ifindex, - nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), - obj->plen, - obj->metric, - obj->gateway, - nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source), - _ip_route_scope_inv_get_normalized (obj), - obj->tos, - obj->mss, - obj->pref_src, - obj->window, - obj->cwnd, - obj->initcwnd, - obj->initrwnd, - obj->mtu, - obj->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK), - NM_HASH_COMBINE_BOOLS (guint8, - obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu)); - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: - nm_hash_update_vals (h, - obj->type_coerced, - obj->table_coerced, - obj->ifindex, - obj->network, - obj->plen, - obj->metric, - obj->gateway, - obj->rt_source, - obj->scope_inv, - obj->tos, - obj->mss, - obj->pref_src, - obj->window, - obj->cwnd, - obj->initcwnd, - obj->initrwnd, - obj->mtu, - obj->r_rtm_flags, - NM_HASH_COMBINE_BOOLS (guint8, - obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu)); - break; - } +nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, + NMPlatformIPRouteCmpType cmp_type, + NMHashState * h) +{ + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + nm_hash_update_vals( + h, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + nm_utils_ip4_address_clear_host_address(obj->network, obj->plen), + obj->plen, + nm_platform_ip4_route_get_effective_metric(obj), + obj->tos, + NM_HASH_COMBINE_BOOLS(guint8, obj->metric_any, obj->table_any)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + nm_hash_update_vals( + h, + obj->type_coerced, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + nm_utils_ip4_address_clear_host_address(obj->network, obj->plen), + obj->plen, + nm_platform_ip4_route_get_effective_metric(obj), + obj->tos, + /* on top of WEAK_ID: */ + obj->ifindex, + nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source), + _ip_route_scope_inv_get_normalized(obj), + obj->gateway, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + obj->r_rtm_flags & RTNH_F_ONLINK, + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + nm_hash_update_vals( + h, + obj->type_coerced, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + obj->ifindex, + nm_utils_ip4_address_clear_host_address(obj->network, obj->plen), + obj->plen, + nm_platform_ip4_route_get_effective_metric(obj), + obj->gateway, + nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source), + _ip_route_scope_inv_get_normalized(obj), + obj->tos, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + obj->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK), + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + nm_hash_update_vals(h, + obj->type_coerced, + obj->table_coerced, + obj->ifindex, + obj->network, + obj->plen, + nm_platform_ip4_route_get_effective_metric(obj), + obj->gateway, + obj->rt_source, + obj->scope_inv, + obj->tos, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + obj->r_rtm_flags, + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu)); + break; + } } int -nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, NMPlatformIPRouteCmpType cmp_type) -{ - NM_CMP_SELF (a, b); - switch (cmp_type) { - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - NM_CMP_DIRECT (nm_platform_route_table_uncoerce (a->table_coerced, TRUE), - nm_platform_route_table_uncoerce (b->table_coerced, TRUE)); - NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (a->network, b->network, MIN (a->plen, b->plen)); - NM_CMP_FIELD (a, b, plen); - NM_CMP_FIELD (a, b, metric); - NM_CMP_FIELD (a, b, tos); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - NM_CMP_FIELD (a, b, ifindex); - NM_CMP_FIELD (a, b, type_coerced); - NM_CMP_DIRECT (nmp_utils_ip_config_source_round_trip_rtprot (a->rt_source), - nmp_utils_ip_config_source_round_trip_rtprot (b->rt_source)); - NM_CMP_DIRECT (_ip_route_scope_inv_get_normalized (a), - _ip_route_scope_inv_get_normalized (b)); - NM_CMP_FIELD (a, b, gateway); - NM_CMP_FIELD (a, b, mss); - NM_CMP_FIELD (a, b, pref_src); - NM_CMP_FIELD (a, b, window); - NM_CMP_FIELD (a, b, cwnd); - NM_CMP_FIELD (a, b, initcwnd); - NM_CMP_FIELD (a, b, initrwnd); - NM_CMP_FIELD (a, b, mtu); - NM_CMP_DIRECT (a->r_rtm_flags & RTNH_F_ONLINK, - b->r_rtm_flags & RTNH_F_ONLINK); - NM_CMP_FIELD_UNSAFE (a, b, lock_window); - NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd); - NM_CMP_FIELD_UNSAFE (a, b, lock_initcwnd); - NM_CMP_FIELD_UNSAFE (a, b, lock_initrwnd); - NM_CMP_FIELD_UNSAFE (a, b, lock_mtu); - } - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: - NM_CMP_FIELD (a, b, type_coerced); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - NM_CMP_DIRECT (nm_platform_route_table_uncoerce (a->table_coerced, TRUE), - nm_platform_route_table_uncoerce (b->table_coerced, TRUE)); - } else - NM_CMP_FIELD (a, b, table_coerced); - NM_CMP_FIELD (a, b, ifindex); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (a->network, b->network, MIN (a->plen, b->plen)); - else - NM_CMP_FIELD (a, b, network); - NM_CMP_FIELD (a, b, plen); - NM_CMP_FIELD (a, b, metric); - NM_CMP_FIELD (a, b, gateway); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - NM_CMP_DIRECT (nmp_utils_ip_config_source_round_trip_rtprot (a->rt_source), - nmp_utils_ip_config_source_round_trip_rtprot (b->rt_source)); - NM_CMP_DIRECT (_ip_route_scope_inv_get_normalized (a), - _ip_route_scope_inv_get_normalized (b)); - } else { - NM_CMP_FIELD (a, b, rt_source); - NM_CMP_FIELD (a, b, scope_inv); - } - NM_CMP_FIELD (a, b, mss); - NM_CMP_FIELD (a, b, pref_src); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - NM_CMP_DIRECT (a->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK), - b->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK)); - } else - NM_CMP_FIELD (a, b, r_rtm_flags); - NM_CMP_FIELD (a, b, tos); - NM_CMP_FIELD_UNSAFE (a, b, lock_window); - NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd); - NM_CMP_FIELD_UNSAFE (a, b, lock_initcwnd); - NM_CMP_FIELD_UNSAFE (a, b, lock_initrwnd); - NM_CMP_FIELD_UNSAFE (a, b, lock_mtu); - NM_CMP_FIELD (a, b, window); - NM_CMP_FIELD (a, b, cwnd); - NM_CMP_FIELD (a, b, initcwnd); - NM_CMP_FIELD (a, b, initrwnd); - NM_CMP_FIELD (a, b, mtu); - break; - } - return 0; +nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a, + const NMPlatformIP4Route *b, + NMPlatformIPRouteCmpType cmp_type) +{ + NM_CMP_SELF(a, b); + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + NM_CMP_FIELD_UNSAFE(a, b, table_any); + NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)), + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b))); + NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(a->network, b->network, MIN(a->plen, b->plen)); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD_UNSAFE(a, b, metric_any); + if (!a->metric_any) + NM_CMP_FIELD(a, b, metric); + NM_CMP_FIELD(a, b, tos); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, type_coerced); + NM_CMP_DIRECT(nmp_utils_ip_config_source_round_trip_rtprot(a->rt_source), + nmp_utils_ip_config_source_round_trip_rtprot(b->rt_source)); + NM_CMP_DIRECT(_ip_route_scope_inv_get_normalized(a), + _ip_route_scope_inv_get_normalized(b)); + NM_CMP_FIELD(a, b, gateway); + NM_CMP_FIELD(a, b, mss); + NM_CMP_FIELD(a, b, pref_src); + NM_CMP_FIELD(a, b, window); + NM_CMP_FIELD(a, b, cwnd); + NM_CMP_FIELD(a, b, initcwnd); + NM_CMP_FIELD(a, b, initrwnd); + NM_CMP_FIELD(a, b, mtu); + NM_CMP_DIRECT(a->r_rtm_flags & RTNH_F_ONLINK, b->r_rtm_flags & RTNH_F_ONLINK); + NM_CMP_FIELD_UNSAFE(a, b, lock_window); + NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_mtu); + } + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + NM_CMP_FIELD(a, b, type_coerced); + NM_CMP_FIELD_UNSAFE(a, b, table_any); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)), + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b))); + } else + NM_CMP_FIELD(a, b, table_coerced); + NM_CMP_FIELD(a, b, ifindex); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(a->network, b->network, MIN(a->plen, b->plen)); + else + NM_CMP_FIELD(a, b, network); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD_UNSAFE(a, b, metric_any); + if (!a->metric_any) + NM_CMP_FIELD(a, b, metric); + NM_CMP_FIELD(a, b, gateway); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(nmp_utils_ip_config_source_round_trip_rtprot(a->rt_source), + nmp_utils_ip_config_source_round_trip_rtprot(b->rt_source)); + NM_CMP_DIRECT(_ip_route_scope_inv_get_normalized(a), + _ip_route_scope_inv_get_normalized(b)); + } else { + NM_CMP_FIELD(a, b, rt_source); + NM_CMP_FIELD(a, b, scope_inv); + } + NM_CMP_FIELD(a, b, mss); + NM_CMP_FIELD(a, b, pref_src); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(a->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK), + b->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK)); + } else + NM_CMP_FIELD(a, b, r_rtm_flags); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD_UNSAFE(a, b, lock_window); + NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_mtu); + NM_CMP_FIELD(a, b, window); + NM_CMP_FIELD(a, b, cwnd); + NM_CMP_FIELD(a, b, initcwnd); + NM_CMP_FIELD(a, b, initrwnd); + NM_CMP_FIELD(a, b, mtu); + break; + } + return 0; } void -nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h) -{ - struct in6_addr a1, a2; - - switch (cmp_type) { - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: - nm_hash_update_vals (h, - nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), - *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), - obj->plen, - obj->metric, - *nm_utils_ip6_address_clear_host_address (&a2, &obj->src, obj->src_plen), - obj->src_plen); - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - nm_hash_update_vals (h, - obj->type_coerced, - nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), - *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), - obj->plen, - obj->metric, - *nm_utils_ip6_address_clear_host_address (&a2, &obj->src, obj->src_plen), - obj->src_plen, - /* on top of WEAK_ID: */ - obj->ifindex, - obj->gateway); - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: - nm_hash_update_vals (h, - obj->type_coerced, - nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), - obj->ifindex, - *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), - obj->plen, - obj->metric, - obj->gateway, - obj->pref_src, - *nm_utils_ip6_address_clear_host_address (&a2, &obj->src, obj->src_plen), - obj->src_plen, - nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source), - obj->mss, - obj->r_rtm_flags & RTM_F_CLONED, - NM_HASH_COMBINE_BOOLS (guint8, - obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu), - obj->window, - obj->cwnd, - obj->initcwnd, - obj->initrwnd, - obj->mtu, - _route_pref_normalize (obj->rt_pref)); - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: - nm_hash_update_vals (h, - obj->type_coerced, - obj->table_coerced, - obj->ifindex, - obj->network, - obj->plen, - obj->metric, - obj->gateway, - obj->pref_src, - obj->src, - obj->src_plen, - obj->rt_source, - obj->mss, - obj->r_rtm_flags, - NM_HASH_COMBINE_BOOLS (guint8, - obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu), - obj->window, - obj->cwnd, - obj->initcwnd, - obj->initrwnd, - obj->mtu, - obj->rt_pref); - break; - } +nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj, + NMPlatformIPRouteCmpType cmp_type, + NMHashState * h) +{ + struct in6_addr a1, a2; + + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + nm_hash_update_vals( + h, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + *nm_utils_ip6_address_clear_host_address(&a1, &obj->network, obj->plen), + obj->plen, + nm_platform_ip6_route_get_effective_metric(obj), + *nm_utils_ip6_address_clear_host_address(&a2, &obj->src, obj->src_plen), + obj->src_plen, + NM_HASH_COMBINE_BOOLS(guint8, obj->metric_any, obj->table_any)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + nm_hash_update_vals( + h, + obj->type_coerced, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + *nm_utils_ip6_address_clear_host_address(&a1, &obj->network, obj->plen), + obj->plen, + nm_platform_ip6_route_get_effective_metric(obj), + *nm_utils_ip6_address_clear_host_address(&a2, &obj->src, obj->src_plen), + obj->src_plen, + NM_HASH_COMBINE_BOOLS(guint8, obj->metric_any, obj->table_any), + /* on top of WEAK_ID: */ + obj->ifindex, + obj->gateway); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + nm_hash_update_vals( + h, + obj->type_coerced, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + obj->ifindex, + *nm_utils_ip6_address_clear_host_address(&a1, &obj->network, obj->plen), + obj->plen, + nm_platform_ip6_route_get_effective_metric(obj), + obj->gateway, + obj->pref_src, + *nm_utils_ip6_address_clear_host_address(&a2, &obj->src, obj->src_plen), + obj->src_plen, + nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source), + obj->mss, + obj->r_rtm_flags & RTM_F_CLONED, + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu), + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + _route_pref_normalize(obj->rt_pref)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + nm_hash_update_vals(h, + obj->type_coerced, + obj->table_coerced, + obj->ifindex, + obj->network, + nm_platform_ip6_route_get_effective_metric(obj), + obj->gateway, + obj->pref_src, + obj->src, + obj->src_plen, + obj->rt_source, + obj->mss, + obj->r_rtm_flags, + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu), + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + obj->rt_pref); + break; + } } int -nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, NMPlatformIPRouteCmpType cmp_type) -{ - NM_CMP_SELF (a, b); - switch (cmp_type) { - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - NM_CMP_DIRECT (nm_platform_route_table_uncoerce (a->table_coerced, TRUE), - nm_platform_route_table_uncoerce (b->table_coerced, TRUE)); - NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->network, &b->network, MIN (a->plen, b->plen)); - NM_CMP_FIELD (a, b, plen); - NM_CMP_FIELD (a, b, metric); - NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->src, &b->src, MIN (a->src_plen, b->src_plen)); - NM_CMP_FIELD (a, b, src_plen); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - NM_CMP_FIELD (a, b, ifindex); - NM_CMP_FIELD (a, b, type_coerced); - NM_CMP_FIELD_IN6ADDR (a, b, gateway); - } - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: - NM_CMP_FIELD (a, b, type_coerced); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - NM_CMP_DIRECT (nm_platform_route_table_uncoerce (a->table_coerced, TRUE), - nm_platform_route_table_uncoerce (b->table_coerced, TRUE)); - } else - NM_CMP_FIELD (a, b, table_coerced); - NM_CMP_FIELD (a, b, ifindex); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->network, &b->network, MIN (a->plen, b->plen)); - else - NM_CMP_FIELD_IN6ADDR (a, b, network); - NM_CMP_FIELD (a, b, plen); - NM_CMP_FIELD (a, b, metric); - NM_CMP_FIELD_IN6ADDR (a, b, gateway); - NM_CMP_FIELD_IN6ADDR (a, b, pref_src); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->src, &b->src, MIN (a->src_plen, b->src_plen)); - NM_CMP_FIELD (a, b, src_plen); - NM_CMP_DIRECT (nmp_utils_ip_config_source_round_trip_rtprot (a->rt_source), - nmp_utils_ip_config_source_round_trip_rtprot (b->rt_source)); - } else { - NM_CMP_FIELD_IN6ADDR (a, b, src); - NM_CMP_FIELD (a, b, src_plen); - NM_CMP_FIELD (a, b, rt_source); - } - NM_CMP_FIELD (a, b, mss); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - NM_CMP_DIRECT (a->r_rtm_flags & RTM_F_CLONED, - b->r_rtm_flags & RTM_F_CLONED); - } else - NM_CMP_FIELD (a, b, r_rtm_flags); - NM_CMP_FIELD_UNSAFE (a, b, lock_window); - NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd); - NM_CMP_FIELD_UNSAFE (a, b, lock_initcwnd); - NM_CMP_FIELD_UNSAFE (a, b, lock_initrwnd); - NM_CMP_FIELD_UNSAFE (a, b, lock_mtu); - NM_CMP_FIELD (a, b, window); - NM_CMP_FIELD (a, b, cwnd); - NM_CMP_FIELD (a, b, initcwnd); - NM_CMP_FIELD (a, b, initrwnd); - NM_CMP_FIELD (a, b, mtu); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - NM_CMP_DIRECT (_route_pref_normalize (a->rt_pref), _route_pref_normalize (b->rt_pref)); - else - NM_CMP_FIELD (a, b, rt_pref); - break; - } - return 0; -} - -#define _ROUTING_RULE_FLAGS_IGNORE ( FIB_RULE_UNRESOLVED \ - | FIB_RULE_IIF_DETACHED \ - | FIB_RULE_OIF_DETACHED) +nm_platform_ip6_route_cmp(const NMPlatformIP6Route *a, + const NMPlatformIP6Route *b, + NMPlatformIPRouteCmpType cmp_type) +{ + NM_CMP_SELF(a, b); + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + NM_CMP_FIELD_UNSAFE(a, b, table_any); + NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)), + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b))); + NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(&a->network, &b->network, MIN(a->plen, b->plen)); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD_UNSAFE(a, b, metric_any); + if (!a->metric_any) + NM_CMP_FIELD(a, b, metric); + NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(&a->src, &b->src, MIN(a->src_plen, b->src_plen)); + NM_CMP_FIELD(a, b, src_plen); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, type_coerced); + NM_CMP_FIELD_IN6ADDR(a, b, gateway); + } + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + NM_CMP_FIELD(a, b, type_coerced); + NM_CMP_FIELD_UNSAFE(a, b, table_any); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)), + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b))); + } else + NM_CMP_FIELD(a, b, table_coerced); + NM_CMP_FIELD(a, b, ifindex); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(&a->network, &b->network, MIN(a->plen, b->plen)); + else + NM_CMP_FIELD_IN6ADDR(a, b, network); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD_UNSAFE(a, b, metric_any); + if (!a->metric_any) + NM_CMP_FIELD(a, b, metric); + NM_CMP_FIELD_IN6ADDR(a, b, gateway); + NM_CMP_FIELD_IN6ADDR(a, b, pref_src); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(&a->src, &b->src, MIN(a->src_plen, b->src_plen)); + NM_CMP_FIELD(a, b, src_plen); + NM_CMP_DIRECT(nmp_utils_ip_config_source_round_trip_rtprot(a->rt_source), + nmp_utils_ip_config_source_round_trip_rtprot(b->rt_source)); + } else { + NM_CMP_FIELD_IN6ADDR(a, b, src); + NM_CMP_FIELD(a, b, src_plen); + NM_CMP_FIELD(a, b, rt_source); + } + NM_CMP_FIELD(a, b, mss); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(a->r_rtm_flags & RTM_F_CLONED, b->r_rtm_flags & RTM_F_CLONED); + } else + NM_CMP_FIELD(a, b, r_rtm_flags); + NM_CMP_FIELD_UNSAFE(a, b, lock_window); + NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_mtu); + NM_CMP_FIELD(a, b, window); + NM_CMP_FIELD(a, b, cwnd); + NM_CMP_FIELD(a, b, initcwnd); + NM_CMP_FIELD(a, b, initrwnd); + NM_CMP_FIELD(a, b, mtu); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + NM_CMP_DIRECT(_route_pref_normalize(a->rt_pref), _route_pref_normalize(b->rt_pref)); + else + NM_CMP_FIELD(a, b, rt_pref); + break; + } + return 0; +} + +#define _ROUTING_RULE_FLAGS_IGNORE \ + (FIB_RULE_UNRESOLVED | FIB_RULE_IIF_DETACHED | FIB_RULE_OIF_DETACHED) #define _routing_rule_compare(cmp_type, kernel_support_type) \ - ( (cmp_type) == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL \ - || nm_platform_kernel_support_get (kernel_support_type)) + ((cmp_type) == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL \ + || nm_platform_kernel_support_get(kernel_support_type)) void -nm_platform_routing_rule_hash_update (const NMPlatformRoutingRule *obj, - NMPlatformRoutingRuleCmpType cmp_type, - NMHashState *h) -{ - gboolean cmp_full = TRUE; - gsize addr_size; - guint32 flags_mask = G_MAXUINT32; - - if (G_UNLIKELY (!NM_IN_SET (obj->addr_family, AF_INET, AF_INET6))) { - /* the address family is not one of the supported ones. That means, the - * instance will only compare equal to itself (pointer-equality). */ - nm_hash_update_val (h, (gconstpointer) obj); - return; - } - - switch (cmp_type) { - - case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID: - - flags_mask &= ~_ROUTING_RULE_FLAGS_IGNORE; - - /* fall-through */ - case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY: - - cmp_full = FALSE; - - /* fall-through */ - case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL: - - nm_hash_update_vals (h, - obj->addr_family, - obj->tun_id, - obj->table, - obj->flags & flags_mask, - obj->priority, - obj->fwmark, - obj->fwmask, - ( ( cmp_full - || ( cmp_type == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY - && obj->action == FR_ACT_GOTO)) - ? obj->goto_target - : (guint32) 0u), - ( ( cmp_full - || obj->addr_family == AF_INET) - ? obj->flow - : (guint32) 0u), - NM_HASH_COMBINE_BOOLS (guint8, - ( _routing_rule_compare (cmp_type, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE) - ? obj->uid_range_has - : FALSE)), - obj->suppress_prefixlen_inverse, - obj->suppress_ifgroup_inverse, - ( _routing_rule_compare (cmp_type, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV) - ? ( cmp_full - ? (guint16) obj->l3mdev - : (guint16) !!obj->l3mdev) - : G_MAXUINT16), - obj->action, - obj->tos, - obj->src_len, - obj->dst_len, - ( _routing_rule_compare (cmp_type, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL) - ? (guint16) obj->protocol - : G_MAXUINT16)); - addr_size = nm_utils_addr_family_to_size (obj->addr_family); - if (cmp_full || obj->src_len > 0) - nm_hash_update (h, &obj->src, addr_size); - if (cmp_full || obj->dst_len > 0) - nm_hash_update (h, &obj->dst, addr_size); - if (_routing_rule_compare (cmp_type, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)) { - if (cmp_full || obj->uid_range_has) - nm_hash_update_valp (h, &obj->uid_range); - } - if (_routing_rule_compare (cmp_type, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO)) { - nm_hash_update_val (h, obj->ip_proto); - nm_hash_update_valp (h, &obj->sport_range); - nm_hash_update_valp (h, &obj->dport_range); - } - nm_hash_update_str (h, obj->iifname); - nm_hash_update_str (h, obj->oifname); - return; - } - - nm_assert_not_reached (); +nm_platform_routing_rule_hash_update(const NMPlatformRoutingRule *obj, + NMPlatformRoutingRuleCmpType cmp_type, + NMHashState * h) +{ + gboolean cmp_full = TRUE; + gsize addr_size; + guint32 flags_mask = G_MAXUINT32; + + if (G_UNLIKELY(!NM_IN_SET(obj->addr_family, AF_INET, AF_INET6))) { + /* the address family is not one of the supported ones. That means, the + * instance will only compare equal to itself (pointer-equality). */ + nm_hash_update_val(h, (gconstpointer) obj); + return; + } + + switch (cmp_type) { + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID: + + flags_mask &= ~_ROUTING_RULE_FLAGS_IGNORE; + + /* fall-through */ + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY: + + cmp_full = FALSE; + + /* fall-through */ + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL: + + nm_hash_update_vals( + h, + obj->addr_family, + obj->tun_id, + obj->table, + obj->flags & flags_mask, + obj->priority, + obj->fwmark, + obj->fwmask, + ((cmp_full + || (cmp_type == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY + && obj->action == FR_ACT_GOTO)) + ? obj->goto_target + : (guint32) 0u), + ((cmp_full || obj->addr_family == AF_INET) ? obj->flow : (guint32) 0u), + NM_HASH_COMBINE_BOOLS( + guint8, + (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE) + ? obj->uid_range_has + : FALSE)), + obj->suppress_prefixlen_inverse, + obj->suppress_ifgroup_inverse, + (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV) + ? (cmp_full ? (guint16) obj->l3mdev : (guint16) !!obj->l3mdev) + : G_MAXUINT16), + obj->action, + obj->tos, + obj->src_len, + obj->dst_len, + (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL) + ? (guint16) obj->protocol + : G_MAXUINT16)); + addr_size = nm_utils_addr_family_to_size(obj->addr_family); + if (cmp_full || obj->src_len > 0) + nm_hash_update(h, &obj->src, addr_size); + if (cmp_full || obj->dst_len > 0) + nm_hash_update(h, &obj->dst, addr_size); + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)) { + if (cmp_full || obj->uid_range_has) + nm_hash_update_valp(h, &obj->uid_range); + } + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO)) { + nm_hash_update_val(h, obj->ip_proto); + nm_hash_update_valp(h, &obj->sport_range); + nm_hash_update_valp(h, &obj->dport_range); + } + nm_hash_update_str(h, obj->iifname); + nm_hash_update_str(h, obj->oifname); + return; + } + + nm_assert_not_reached(); } int -nm_platform_routing_rule_cmp (const NMPlatformRoutingRule *a, - const NMPlatformRoutingRule *b, - NMPlatformRoutingRuleCmpType cmp_type) -{ - gboolean cmp_full = TRUE; - gsize addr_size; - bool valid; - guint32 flags_mask = G_MAXUINT32; - - NM_CMP_SELF (a, b); +nm_platform_routing_rule_cmp(const NMPlatformRoutingRule *a, + const NMPlatformRoutingRule *b, + NMPlatformRoutingRuleCmpType cmp_type) +{ + gboolean cmp_full = TRUE; + gsize addr_size; + bool valid; + guint32 flags_mask = G_MAXUINT32; - valid = NM_IN_SET (a->addr_family, AF_INET, AF_INET6); - NM_CMP_DIRECT (valid, - (bool) NM_IN_SET (b->addr_family, AF_INET, AF_INET6)); + NM_CMP_SELF(a, b); - if (G_UNLIKELY (!valid)) { - /* the address family is not one of the supported ones. That means, the - * instance will only compare equal to itself. */ - NM_CMP_DIRECT ((uintptr_t) a, (uintptr_t) b); - nm_assert_not_reached (); - return 0; - } + valid = NM_IN_SET(a->addr_family, AF_INET, AF_INET6); + NM_CMP_DIRECT(valid, (bool) NM_IN_SET(b->addr_family, AF_INET, AF_INET6)); - switch (cmp_type) { + if (G_UNLIKELY(!valid)) { + /* the address family is not one of the supported ones. That means, the + * instance will only compare equal to itself. */ + NM_CMP_DIRECT((uintptr_t) a, (uintptr_t) b); + nm_assert_not_reached(); + return 0; + } - case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID: + switch (cmp_type) { + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID: - flags_mask &= ~_ROUTING_RULE_FLAGS_IGNORE; + flags_mask &= ~_ROUTING_RULE_FLAGS_IGNORE; - /* fall-through */ - case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY: + /* fall-through */ + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY: - cmp_full = FALSE; + cmp_full = FALSE; - /* fall-through */ - case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL: - NM_CMP_FIELD (a, b, addr_family); - NM_CMP_FIELD (a, b, action); - NM_CMP_FIELD (a, b, priority); - NM_CMP_FIELD (a, b, tun_id); + /* fall-through */ + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL: + NM_CMP_FIELD(a, b, addr_family); + NM_CMP_FIELD(a, b, action); + NM_CMP_FIELD(a, b, priority); + NM_CMP_FIELD(a, b, tun_id); - if (_routing_rule_compare (cmp_type, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV)) { - if (cmp_full) - NM_CMP_FIELD (a, b, l3mdev); - else - NM_CMP_FIELD_BOOL (a, b, l3mdev); - } + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV)) { + if (cmp_full) + NM_CMP_FIELD(a, b, l3mdev); + else + NM_CMP_FIELD_BOOL(a, b, l3mdev); + } - NM_CMP_FIELD (a, b, table); + NM_CMP_FIELD(a, b, table); - NM_CMP_DIRECT (a->flags & flags_mask, b->flags & flags_mask); + NM_CMP_DIRECT(a->flags & flags_mask, b->flags & flags_mask); - NM_CMP_FIELD (a, b, fwmark); - NM_CMP_FIELD (a, b, fwmask); + NM_CMP_FIELD(a, b, fwmark); + NM_CMP_FIELD(a, b, fwmask); - if ( cmp_full - || ( cmp_type == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY - && a->action == FR_ACT_GOTO)) - NM_CMP_FIELD (a, b, goto_target); + if (cmp_full + || (cmp_type == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY + && a->action == FR_ACT_GOTO)) + NM_CMP_FIELD(a, b, goto_target); - NM_CMP_FIELD (a, b, suppress_prefixlen_inverse); - NM_CMP_FIELD (a, b, suppress_ifgroup_inverse); - NM_CMP_FIELD (a, b, tos); + NM_CMP_FIELD(a, b, suppress_prefixlen_inverse); + NM_CMP_FIELD(a, b, suppress_ifgroup_inverse); + NM_CMP_FIELD(a, b, tos); - if (cmp_full || a->addr_family == AF_INET) - NM_CMP_FIELD (a, b, flow); + if (cmp_full || a->addr_family == AF_INET) + NM_CMP_FIELD(a, b, flow); - if (_routing_rule_compare (cmp_type, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL)) - NM_CMP_FIELD (a, b, protocol); + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL)) + NM_CMP_FIELD(a, b, protocol); - if (_routing_rule_compare (cmp_type, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO)) { - NM_CMP_FIELD (a, b, ip_proto); - NM_CMP_FIELD (a, b, sport_range.start); - NM_CMP_FIELD (a, b, sport_range.end); - NM_CMP_FIELD (a, b, dport_range.start); - NM_CMP_FIELD (a, b, dport_range.end); - } + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO)) { + NM_CMP_FIELD(a, b, ip_proto); + NM_CMP_FIELD(a, b, sport_range.start); + NM_CMP_FIELD(a, b, sport_range.end); + NM_CMP_FIELD(a, b, dport_range.start); + NM_CMP_FIELD(a, b, dport_range.end); + } - addr_size = nm_utils_addr_family_to_size (a->addr_family); + addr_size = nm_utils_addr_family_to_size(a->addr_family); - NM_CMP_FIELD (a, b, src_len); - if (cmp_full || a->src_len > 0) - NM_CMP_FIELD_MEMCMP_LEN (a, b, src, addr_size); + NM_CMP_FIELD(a, b, src_len); + if (cmp_full || a->src_len > 0) + NM_CMP_FIELD_MEMCMP_LEN(a, b, src, addr_size); - NM_CMP_FIELD (a, b, dst_len); - if (cmp_full || a->dst_len > 0) - NM_CMP_FIELD_MEMCMP_LEN (a, b, dst, addr_size); + NM_CMP_FIELD(a, b, dst_len); + if (cmp_full || a->dst_len > 0) + NM_CMP_FIELD_MEMCMP_LEN(a, b, dst, addr_size); - if (_routing_rule_compare (cmp_type, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)) { - NM_CMP_FIELD_UNSAFE (a, b, uid_range_has); - if (cmp_full || a->uid_range_has) { - NM_CMP_FIELD (a, b, uid_range.start); - NM_CMP_FIELD (a, b, uid_range.end); - } - } + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)) { + NM_CMP_FIELD_UNSAFE(a, b, uid_range_has); + if (cmp_full || a->uid_range_has) { + NM_CMP_FIELD(a, b, uid_range.start); + NM_CMP_FIELD(a, b, uid_range.end); + } + } - NM_CMP_FIELD_STR (a, b, iifname); - NM_CMP_FIELD_STR (a, b, oifname); - return 0; - } + NM_CMP_FIELD_STR(a, b, iifname); + NM_CMP_FIELD_STR(a, b, oifname); + return 0; + } - nm_assert_not_reached (); - return 0; + nm_assert_not_reached(); + return 0; } /** @@ -7841,378 +8489,488 @@ nm_platform_routing_rule_cmp (const NMPlatformRoutingRule *a, * Returns: -1, 0, or 1 according to the comparison **/ int -nm_platform_ip_address_cmp_expiry (const NMPlatformIPAddress *a, const NMPlatformIPAddress *b) +nm_platform_ip_address_cmp_expiry(const NMPlatformIPAddress *a, const NMPlatformIPAddress *b) { - gint64 ta = 0, tb = 0; + gint64 ta = 0, tb = 0; - NM_CMP_SELF (a, b); + NM_CMP_SELF(a, b); - if (a->lifetime == NM_PLATFORM_LIFETIME_PERMANENT || a->lifetime == 0) - ta = G_MAXINT64; - else if (a->timestamp) - ta = ((gint64) a->timestamp) + a->lifetime; + if (a->lifetime == NM_PLATFORM_LIFETIME_PERMANENT || a->lifetime == 0) + ta = G_MAXINT64; + else if (a->timestamp) + ta = ((gint64) a->timestamp) + a->lifetime; - if (b->lifetime == NM_PLATFORM_LIFETIME_PERMANENT || b->lifetime == 0) - tb = G_MAXINT64; - else if (b->timestamp) - tb = ((gint64) b->timestamp) + b->lifetime; + if (b->lifetime == NM_PLATFORM_LIFETIME_PERMANENT || b->lifetime == 0) + tb = G_MAXINT64; + else if (b->timestamp) + tb = ((gint64) b->timestamp) + b->lifetime; - if (ta == tb) { - /* if the lifetime is equal, compare the preferred time. */ - ta = tb = 0; + if (ta == tb) { + /* if the lifetime is equal, compare the preferred time. */ + ta = tb = 0; - if (a->preferred == NM_PLATFORM_LIFETIME_PERMANENT || a->lifetime == 0 /* lifetime==0 means permanent! */) - ta = G_MAXINT64; - else if (a->timestamp) - ta = ((gint64) a->timestamp) + a->preferred; + if (a->preferred == NM_PLATFORM_LIFETIME_PERMANENT + || a->lifetime == 0 /* lifetime==0 means permanent! */) + ta = G_MAXINT64; + else if (a->timestamp) + ta = ((gint64) a->timestamp) + a->preferred; - if (b->preferred == NM_PLATFORM_LIFETIME_PERMANENT|| b->lifetime == 0) - tb = G_MAXINT64; - else if (b->timestamp) - tb = ((gint64) b->timestamp) + b->preferred; + if (b->preferred == NM_PLATFORM_LIFETIME_PERMANENT || b->lifetime == 0) + tb = G_MAXINT64; + else if (b->timestamp) + tb = ((gint64) b->timestamp) + b->preferred; - if (ta == tb) - return 0; - } + if (ta == tb) + return 0; + } - return ta < tb ? -1 : 1; + return ta < tb ? -1 : 1; } +/*****************************************************************************/ + +GHashTable * +nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex) +{ + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter iter; + const NMPObject * obj; + NMPLookup lookup; + GHashTable * hash; + + g_return_val_if_fail(NM_IS_PLATFORM(self), NULL); + g_return_val_if_fail(ifindex > 0, NULL); + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex); + + head_entry = nmp_cache_lookup(NM_PLATFORM_GET_PRIVATE(self)->cache, &lookup); + + if (!head_entry) + return NULL; + + hash = g_hash_table_new(nm_direct_hash, NULL); + + nmp_cache_iter_for_each (&iter, head_entry, &obj) { + const NMPlatformIP4Address *a = NMP_OBJECT_CAST_IP4_ADDRESS(obj); + + g_hash_table_add(hash, GUINT_TO_POINTER(a->address)); + } + + return hash; +} + +/*****************************************************************************/ + const char * -nm_platform_signal_change_type_to_string (NMPlatformSignalChangeType change_type) +nm_platform_signal_change_type_to_string(NMPlatformSignalChangeType change_type) { - switch (change_type) { - case NM_PLATFORM_SIGNAL_ADDED: - return "added"; - case NM_PLATFORM_SIGNAL_CHANGED: - return "changed"; - case NM_PLATFORM_SIGNAL_REMOVED: - return "removed"; - default: - g_return_val_if_reached ("UNKNOWN"); - } + switch (change_type) { + case NM_PLATFORM_SIGNAL_ADDED: + return "added"; + case NM_PLATFORM_SIGNAL_CHANGED: + return "changed"; + case NM_PLATFORM_SIGNAL_REMOVED: + return "removed"; + default: + g_return_val_if_reached("UNKNOWN"); + } } static void -log_link (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformLink *device, NMPlatformSignalChangeType change_type, gpointer user_data) +log_link(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformLink * device, + NMPlatformSignalChangeType change_type, + gpointer user_data) { - _LOG3D ("signal: link %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_link_to_string (device, NULL, 0)); + _LOG3D("signal: link %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_link_to_string(device, NULL, 0)); } static void -log_ip4_address (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformIP4Address *address, NMPlatformSignalChangeType change_type, gpointer user_data) +log_ip4_address(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP4Address * address, + NMPlatformSignalChangeType change_type, + gpointer user_data) { - _LOG3D ("signal: address 4 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip4_address_to_string (address, NULL, 0)); + _LOG3D("signal: address 4 %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_ip4_address_to_string(address, NULL, 0)); } static void -log_ip6_address (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformIP6Address *address, NMPlatformSignalChangeType change_type, gpointer user_data) +log_ip6_address(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP6Address * address, + NMPlatformSignalChangeType change_type, + gpointer user_data) { - _LOG3D ("signal: address 6 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip6_address_to_string (address, NULL, 0)); + _LOG3D("signal: address 6 %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_ip6_address_to_string(address, NULL, 0)); } static void -log_ip4_route (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformIP4Route *route, NMPlatformSignalChangeType change_type, gpointer user_data) +log_ip4_route(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP4Route * route, + NMPlatformSignalChangeType change_type, + gpointer user_data) { - _LOG3D ("signal: route 4 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip4_route_to_string (route, NULL, 0)); + _LOG3D("signal: route 4 %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_ip4_route_to_string(route, NULL, 0)); } static void -log_ip6_route (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformIP6Route *route, NMPlatformSignalChangeType change_type, gpointer user_data) +log_ip6_route(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP6Route * route, + NMPlatformSignalChangeType change_type, + gpointer user_data) { - _LOG3D ("signal: route 6 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip6_route_to_string (route, NULL, 0)); + _LOG3D("signal: route 6 %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_ip6_route_to_string(route, NULL, 0)); } static void -log_routing_rule (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformRoutingRule *routing_rule, NMPlatformSignalChangeType change_type, gpointer user_data) +log_routing_rule(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformRoutingRule * routing_rule, + NMPlatformSignalChangeType change_type, + gpointer user_data) { - /* routing rules don't have an ifindex. We probably should refactor the signals that are emitted for platform changes. */ - _LOG3D ("signal: rt-rule %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_routing_rule_to_string (routing_rule, NULL, 0)); + /* routing rules don't have an ifindex. We probably should refactor the signals that are emitted for platform changes. */ + _LOG3D("signal: rt-rule %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_routing_rule_to_string(routing_rule, NULL, 0)); } static void -log_qdisc (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformQdisc *qdisc, NMPlatformSignalChangeType change_type, gpointer user_data) +log_qdisc(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformQdisc * qdisc, + NMPlatformSignalChangeType change_type, + gpointer user_data) { - _LOG3D ("signal: qdisc %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_qdisc_to_string (qdisc, NULL, 0)); + _LOG3D("signal: qdisc %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_qdisc_to_string(qdisc, NULL, 0)); } static void -log_tfilter (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformTfilter *tfilter, NMPlatformSignalChangeType change_type, gpointer user_data) +log_tfilter(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformTfilter * tfilter, + NMPlatformSignalChangeType change_type, + gpointer user_data) { - _LOG3D ("signal: tfilter %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_tfilter_to_string (tfilter, NULL, 0)); + _LOG3D("signal: tfilter %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_tfilter_to_string(tfilter, NULL, 0)); } /*****************************************************************************/ void -nm_platform_cache_update_emit_signal (NMPlatform *self, - NMPCacheOpsType cache_op, - const NMPObject *obj_old, - const NMPObject *obj_new) -{ - gboolean visible_new; - gboolean visible_old; - const NMPObject *o; - const NMPClass *klass; - int ifindex; - - nm_assert (NM_IN_SET ((NMPlatformSignalChangeType) cache_op, NM_PLATFORM_SIGNAL_NONE, - NM_PLATFORM_SIGNAL_ADDED, - NM_PLATFORM_SIGNAL_CHANGED, - NM_PLATFORM_SIGNAL_REMOVED)); - - ASSERT_nmp_cache_ops (nm_platform_get_cache (self), cache_op, obj_old, obj_new); - - NMTST_ASSERT_PLATFORM_NETNS_CURRENT (self); - - switch (cache_op) { - case NMP_CACHE_OPS_ADDED: - if (!nmp_object_is_visible (obj_new)) - return; - o = obj_new; - break; - case NMP_CACHE_OPS_UPDATED: - visible_old = nmp_object_is_visible (obj_old); - visible_new = nmp_object_is_visible (obj_new); - if (!visible_old && visible_new) { - o = obj_new; - cache_op = NMP_CACHE_OPS_ADDED; - } else if (visible_old && !visible_new) { - o = obj_old; - cache_op = NMP_CACHE_OPS_REMOVED; - } else if (!visible_new) { - /* it was invisible and stayed invisible. Nothing to do. */ - return; - } else - o = obj_new; - break; - case NMP_CACHE_OPS_REMOVED: - if (!nmp_object_is_visible (obj_old)) - return; - o = obj_old; - break; - default: - nm_assert (cache_op == NMP_CACHE_OPS_UNCHANGED); - return; - } - - klass = NMP_OBJECT_GET_CLASS (o); - - if (klass->obj_type == NMP_OBJECT_TYPE_ROUTING_RULE) - ifindex = 0; - else - ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (o)->ifindex; - - if ( klass->obj_type == NMP_OBJECT_TYPE_IP4_ROUTE - && NM_PLATFORM_GET_PRIVATE (self)->ip4_dev_route_blacklist_gc_timeout_id - && NM_IN_SET (cache_op, NMP_CACHE_OPS_ADDED, NMP_CACHE_OPS_UPDATED)) - _ip4_dev_route_blacklist_notify_route (self, o); - - _LOG3t ("emit signal %s %s: %s", - klass->signal_type, - nm_platform_signal_change_type_to_string ((NMPlatformSignalChangeType) cache_op), - nmp_object_to_string (o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - - nmp_object_ref (o); - g_signal_emit (self, - _nm_platform_signal_id_get (klass->signal_type_id), - 0, - (int) klass->obj_type, - ifindex, - &o->object, - (int) cache_op); - nmp_object_unref (o); +nm_platform_cache_update_emit_signal(NMPlatform * self, + NMPCacheOpsType cache_op, + const NMPObject *obj_old, + const NMPObject *obj_new) +{ + gboolean visible_new; + gboolean visible_old; + const NMPObject *o; + const NMPClass * klass; + int ifindex; + + nm_assert(NM_IN_SET((NMPlatformSignalChangeType) cache_op, + NM_PLATFORM_SIGNAL_NONE, + NM_PLATFORM_SIGNAL_ADDED, + NM_PLATFORM_SIGNAL_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED)); + + ASSERT_nmp_cache_ops(nm_platform_get_cache(self), cache_op, obj_old, obj_new); + + NMTST_ASSERT_PLATFORM_NETNS_CURRENT(self); + + switch (cache_op) { + case NMP_CACHE_OPS_ADDED: + if (!nmp_object_is_visible(obj_new)) + return; + o = obj_new; + break; + case NMP_CACHE_OPS_UPDATED: + visible_old = nmp_object_is_visible(obj_old); + visible_new = nmp_object_is_visible(obj_new); + if (!visible_old && visible_new) { + o = obj_new; + cache_op = NMP_CACHE_OPS_ADDED; + } else if (visible_old && !visible_new) { + o = obj_old; + cache_op = NMP_CACHE_OPS_REMOVED; + } else if (!visible_new) { + /* it was invisible and stayed invisible. Nothing to do. */ + return; + } else + o = obj_new; + break; + case NMP_CACHE_OPS_REMOVED: + if (!nmp_object_is_visible(obj_old)) + return; + o = obj_old; + break; + default: + nm_assert(cache_op == NMP_CACHE_OPS_UNCHANGED); + return; + } + + klass = NMP_OBJECT_GET_CLASS(o); + + if (klass->obj_type == NMP_OBJECT_TYPE_ROUTING_RULE) + ifindex = 0; + else + ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(o)->ifindex; + + if (klass->obj_type == NMP_OBJECT_TYPE_IP4_ROUTE + && NM_PLATFORM_GET_PRIVATE(self)->ip4_dev_route_blacklist_gc_timeout_id + && NM_IN_SET(cache_op, NMP_CACHE_OPS_ADDED, NMP_CACHE_OPS_UPDATED)) + _ip4_dev_route_blacklist_notify_route(self, o); + + _LOG3t("emit signal %s %s: %s", + klass->signal_type, + nm_platform_signal_change_type_to_string((NMPlatformSignalChangeType) cache_op), + nmp_object_to_string(o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + + nmp_object_ref(o); + g_signal_emit(self, + _nm_platform_signal_id_get(klass->signal_type_id), + 0, + (int) klass->obj_type, + ifindex, + &o->object, + (int) cache_op); + nmp_object_unref(o); } /*****************************************************************************/ NMPCache * -nm_platform_get_cache (NMPlatform *self) +nm_platform_get_cache(NMPlatform *self) { - return NM_PLATFORM_GET_PRIVATE (self)->cache; + return NM_PLATFORM_GET_PRIVATE(self)->cache; } NMPNetns * -nm_platform_netns_get (NMPlatform *self) +nm_platform_netns_get(NMPlatform *self) { - _CHECK_SELF (self, klass, NULL); + _CHECK_SELF(self, klass, NULL); - return self->_netns; + return self->_netns; } gboolean -nm_platform_netns_push (NMPlatform *self, NMPNetns **netns) +nm_platform_netns_push(NMPlatform *self, NMPNetns **netns) { - g_return_val_if_fail (NM_IS_PLATFORM (self), FALSE); + g_return_val_if_fail(NM_IS_PLATFORM(self), FALSE); - if ( self->_netns - && !nmp_netns_push (self->_netns)) { - NM_SET_OUT (netns, NULL); - return FALSE; - } + if (self->_netns && !nmp_netns_push(self->_netns)) { + NM_SET_OUT(netns, NULL); + return FALSE; + } - NM_SET_OUT (netns, self->_netns); - return TRUE; + NM_SET_OUT(netns, self->_netns); + return TRUE; } /*****************************************************************************/ const _NMPlatformVTableRouteUnion nm_platform_vtable_route = { - .v4 = { - .is_ip4 = TRUE, - .obj_type = NMP_OBJECT_TYPE_IP4_ROUTE, - .addr_family = AF_INET, - .sizeof_route = sizeof (NMPlatformIP4Route), - .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip4_route_cmp, - .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, char *buf, gsize len)) nm_platform_ip4_route_to_string, - }, - .v6 = { - .is_ip4 = FALSE, - .obj_type = NMP_OBJECT_TYPE_IP6_ROUTE, - .addr_family = AF_INET6, - .sizeof_route = sizeof (NMPlatformIP6Route), - .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip6_route_cmp, - .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, char *buf, gsize len)) nm_platform_ip6_route_to_string, - }, + .v4 = + { + .is_ip4 = TRUE, + .obj_type = NMP_OBJECT_TYPE_IP4_ROUTE, + .addr_family = AF_INET, + .sizeof_route = sizeof(NMPlatformIP4Route), + .route_cmp = (int (*)(const NMPlatformIPXRoute *a, + const NMPlatformIPXRoute *b, + NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip4_route_cmp, + .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, + char * buf, + gsize len)) nm_platform_ip4_route_to_string, + }, + .v6 = + { + .is_ip4 = FALSE, + .obj_type = NMP_OBJECT_TYPE_IP6_ROUTE, + .addr_family = AF_INET6, + .sizeof_route = sizeof(NMPlatformIP6Route), + .route_cmp = (int (*)(const NMPlatformIPXRoute *a, + const NMPlatformIPXRoute *b, + NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip6_route_cmp, + .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, + char * buf, + gsize len)) nm_platform_ip6_route_to_string, + }, }; /*****************************************************************************/ static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMPlatform *self = NM_PLATFORM (object); - NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_NETNS_SUPPORT: - /* construct-only */ - if (g_value_get_boolean (value)) { - NMPNetns *netns; - - netns = nmp_netns_get_current (); - if (netns) - self->_netns = g_object_ref (netns); - } - break; - case PROP_USE_UDEV: - /* construct-only */ - priv->use_udev = g_value_get_boolean (value); - break; - case PROP_LOG_WITH_PTR: - /* construct-only */ - priv->log_with_ptr = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMPlatform * self = NM_PLATFORM(object); + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_NETNS_SUPPORT: + /* construct-only */ + if (g_value_get_boolean(value)) { + NMPNetns *netns; + + netns = nmp_netns_get_current(); + if (netns) + self->_netns = g_object_ref(netns); + } + break; + case PROP_USE_UDEV: + /* construct-only */ + priv->use_udev = g_value_get_boolean(value); + break; + case PROP_LOG_WITH_PTR: + /* construct-only */ + priv->log_with_ptr = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -nm_platform_init (NMPlatform *self) +nm_platform_init(NMPlatform *self) { - self->_priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_PLATFORM, NMPlatformPrivate); + self->_priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_PLATFORM, NMPlatformPrivate); } static GObject * -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) +constructor(GType type, guint n_construct_params, GObjectConstructParam *construct_params) { - GObject *object; - NMPlatform *self; - NMPlatformPrivate *priv; + GObject * object; + NMPlatform * self; + NMPlatformPrivate *priv; - object = G_OBJECT_CLASS (nm_platform_parent_class)->constructor (type, - n_construct_params, - construct_params); - self = NM_PLATFORM (object); - priv = NM_PLATFORM_GET_PRIVATE (self); + object = G_OBJECT_CLASS(nm_platform_parent_class) + ->constructor(type, n_construct_params, construct_params); + self = NM_PLATFORM(object); + priv = NM_PLATFORM_GET_PRIVATE(self); - priv->multi_idx = nm_dedup_multi_index_new (); + priv->multi_idx = nm_dedup_multi_index_new(); - priv->cache = nmp_cache_new (priv->multi_idx, - priv->use_udev); + priv->cache = nmp_cache_new(priv->multi_idx, priv->use_udev); - return object; + return object; } static void -finalize (GObject *object) +finalize(GObject *object) { - NMPlatform *self = NM_PLATFORM (object); - NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE (self); + NMPlatform * self = NM_PLATFORM(object); + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); - nm_clear_g_source (&priv->ip4_dev_route_blacklist_check_id); - nm_clear_g_source (&priv->ip4_dev_route_blacklist_gc_timeout_id); - nm_clear_pointer (&priv->ip4_dev_route_blacklist_hash, g_hash_table_unref); - g_clear_object (&self->_netns); - nm_dedup_multi_index_unref (priv->multi_idx); - nmp_cache_free (priv->cache); + nm_clear_g_source(&priv->ip4_dev_route_blacklist_check_id); + nm_clear_g_source(&priv->ip4_dev_route_blacklist_gc_timeout_id); + nm_clear_pointer(&priv->ip4_dev_route_blacklist_hash, g_hash_table_unref); + g_clear_object(&self->_netns); + nm_dedup_multi_index_unref(priv->multi_idx); + nmp_cache_free(priv->cache); } static void -nm_platform_class_init (NMPlatformClass *platform_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (platform_class); - - g_type_class_add_private (object_class, sizeof (NMPlatformPrivate)); - - object_class->constructor = constructor; - object_class->set_property = set_property; - object_class->finalize = finalize; - - platform_class->wifi_set_powersave = wifi_set_powersave; - - g_object_class_install_property - (object_class, PROP_NETNS_SUPPORT, - g_param_spec_boolean (NM_PLATFORM_NETNS_SUPPORT, "", "", - NM_PLATFORM_NETNS_SUPPORT_DEFAULT, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_USE_UDEV, - g_param_spec_boolean (NM_PLATFORM_USE_UDEV, "", "", - FALSE, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_LOG_WITH_PTR, - g_param_spec_boolean (NM_PLATFORM_LOG_WITH_PTR, "", "", - TRUE, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - -#define SIGNAL(signal, signal_id, method) \ - G_STMT_START { \ - signals[signal] = \ - g_signal_new_class_handler (""signal_id"", \ - G_OBJECT_CLASS_TYPE (object_class), \ - G_SIGNAL_RUN_FIRST, \ - G_CALLBACK (method), \ - NULL, NULL, NULL, \ - G_TYPE_NONE, 4, \ - G_TYPE_INT, /* (int) NMPObjectType */ \ - G_TYPE_INT, /* ifindex */ \ - G_TYPE_POINTER /* const NMPObject * */, \ - G_TYPE_INT /* (int) NMPlatformSignalChangeType */ \ - ); \ - } G_STMT_END - - /* Signals */ - SIGNAL (NM_PLATFORM_SIGNAL_ID_LINK, NM_PLATFORM_SIGNAL_LINK_CHANGED, log_link); - SIGNAL (NM_PLATFORM_SIGNAL_ID_IP4_ADDRESS, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, log_ip4_address); - SIGNAL (NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, log_ip6_address); - SIGNAL (NM_PLATFORM_SIGNAL_ID_IP4_ROUTE, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, log_ip4_route); - SIGNAL (NM_PLATFORM_SIGNAL_ID_IP6_ROUTE, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, log_ip6_route); - SIGNAL (NM_PLATFORM_SIGNAL_ID_ROUTING_RULE, NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED, log_routing_rule); - SIGNAL (NM_PLATFORM_SIGNAL_ID_QDISC, NM_PLATFORM_SIGNAL_QDISC_CHANGED, log_qdisc); - SIGNAL (NM_PLATFORM_SIGNAL_ID_TFILTER, NM_PLATFORM_SIGNAL_TFILTER_CHANGED, log_tfilter); +nm_platform_class_init(NMPlatformClass *platform_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(platform_class); + + g_type_class_add_private(object_class, sizeof(NMPlatformPrivate)); + + object_class->constructor = constructor; + object_class->set_property = set_property; + object_class->finalize = finalize; + + platform_class->wifi_set_powersave = wifi_set_powersave; + + g_object_class_install_property( + object_class, + PROP_NETNS_SUPPORT, + g_param_spec_boolean(NM_PLATFORM_NETNS_SUPPORT, + "", + "", + NM_PLATFORM_NETNS_SUPPORT_DEFAULT, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + object_class, + PROP_USE_UDEV, + g_param_spec_boolean(NM_PLATFORM_USE_UDEV, + "", + "", + FALSE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + object_class, + PROP_LOG_WITH_PTR, + g_param_spec_boolean(NM_PLATFORM_LOG_WITH_PTR, + "", + "", + TRUE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + +#define SIGNAL(signal, signal_id, method) \ + G_STMT_START \ + { \ + signals[signal] = \ + g_signal_new_class_handler("" signal_id "", \ + G_OBJECT_CLASS_TYPE(object_class), \ + G_SIGNAL_RUN_FIRST, \ + G_CALLBACK(method), \ + NULL, \ + NULL, \ + NULL, \ + G_TYPE_NONE, \ + 4, \ + G_TYPE_INT, /* (int) NMPObjectType */ \ + G_TYPE_INT, /* ifindex */ \ + G_TYPE_POINTER /* const NMPObject * */, \ + G_TYPE_INT /* (int) NMPlatformSignalChangeType */ \ + ); \ + } \ + G_STMT_END + + /* Signals */ + SIGNAL(NM_PLATFORM_SIGNAL_ID_LINK, NM_PLATFORM_SIGNAL_LINK_CHANGED, log_link); + SIGNAL(NM_PLATFORM_SIGNAL_ID_IP4_ADDRESS, + NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + log_ip4_address); + SIGNAL(NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS, + NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + log_ip6_address); + SIGNAL(NM_PLATFORM_SIGNAL_ID_IP4_ROUTE, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, log_ip4_route); + SIGNAL(NM_PLATFORM_SIGNAL_ID_IP6_ROUTE, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, log_ip6_route); + SIGNAL(NM_PLATFORM_SIGNAL_ID_ROUTING_RULE, + NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED, + log_routing_rule); + SIGNAL(NM_PLATFORM_SIGNAL_ID_QDISC, NM_PLATFORM_SIGNAL_QDISC_CHANGED, log_qdisc); + SIGNAL(NM_PLATFORM_SIGNAL_ID_TFILTER, NM_PLATFORM_SIGNAL_TFILTER_CHANGED, log_tfilter); } |