diff --git a/Makefile.am b/Makefile.am index f4b892e96c..762e229b86 100644 --- a/Makefile.am +++ b/Makefile.am @@ -604,12 +604,12 @@ src_libnm_platform_libnm_platform_la_SOURCES = \ src/libnm-platform/nm-platform.c \ src/libnm-platform/nm-platform.h \ src/libnm-platform/nmp-base.h \ + src/libnm-platform/nmp-global-tracker.c \ + src/libnm-platform/nmp-global-tracker.h \ src/libnm-platform/nmp-netns.c \ src/libnm-platform/nmp-netns.h \ src/libnm-platform/nmp-object.c \ src/libnm-platform/nmp-object.h \ - src/libnm-platform/nmp-route-manager.c \ - src/libnm-platform/nmp-route-manager.h \ src/libnm-platform/wifi/nm-wifi-utils-nl80211.c \ src/libnm-platform/wifi/nm-wifi-utils-nl80211.h \ src/libnm-platform/wifi/nm-wifi-utils-private.h \ diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c index bdb96cb298..179c2a22a5 100644 --- a/src/core/devices/nm-device-wireguard.c +++ b/src/core/devices/nm-device-wireguard.c @@ -18,7 +18,7 @@ #include "nm-device-private.h" #include "libnm-platform/nm-platform.h" #include "libnm-platform/nmp-object.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" #include "nm-device-factory.h" #include "nm-active-connection.h" #include "nm-act-request.h" diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 8c58453b55..f2de8c9c89 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -41,7 +41,7 @@ #include "libnm-platform/nm-platform.h" #include "libnm-platform/nm-platform-utils.h" #include "libnm-platform/nmp-object.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" #include "ndisc/nm-ndisc.h" #include "ndisc/nm-lndp-ndisc.h" @@ -9491,13 +9491,13 @@ lldp_setup(NMDevice *self, NMTernary enabled) static void _routing_rules_sync(NMDevice *self, NMTernary set_mode) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - NMPRouteManager *route_manager = nm_netns_get_route_manager(nm_device_get_netns(self)); - NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self); - gboolean untrack_only_dirty = FALSE; - gboolean keep_deleted_rules; - gpointer user_tag_1; - gpointer user_tag_2; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMPGlobalTracker *global_tracker = nm_netns_get_global_tracker(nm_device_get_netns(self)); + NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self); + gboolean untrack_only_dirty = FALSE; + gboolean keep_deleted_rules; + gpointer user_tag_1; + gpointer user_tag_2; /* take two arbitrary user-tag pointers that belong to @self. */ user_tag_1 = &priv->v4_route_table; @@ -9529,13 +9529,13 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode) nm_ip_routing_rule_to_platform(rule, &plrule); /* We track this rule, but we also make it explicitly not weakly-tracked - * (meaning to untrack NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG at + * (meaning to untrack NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG at * the same time). */ - nmp_route_manager_track_rule(route_manager, - &plrule, - 10, - user_tag_1, - NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); + nmp_global_tracker_track_rule(global_tracker, + &plrule, + 10, + user_tag_1, + NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG); } } @@ -9545,25 +9545,25 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode) extra_rules = klass->get_extra_rules(self); if (extra_rules) { for (i = 0; i < extra_rules->len; i++) { - nmp_route_manager_track_rule( - route_manager, + nmp_global_tracker_track_rule( + global_tracker, NMP_OBJECT_CAST_ROUTING_RULE(extra_rules->pdata[i]), 10, user_tag_2, - NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); + NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG); } } } } - nmp_route_manager_untrack_all(route_manager, user_tag_1, !untrack_only_dirty, TRUE); + nmp_global_tracker_untrack_all(global_tracker, user_tag_1, !untrack_only_dirty, TRUE); if (klass->get_extra_rules) - nmp_route_manager_untrack_all(route_manager, user_tag_2, !untrack_only_dirty, TRUE); + nmp_global_tracker_untrack_all(global_tracker, user_tag_2, !untrack_only_dirty, TRUE); keep_deleted_rules = FALSE; if (set_mode == NM_TERNARY_DEFAULT) { /* when exiting NM, we leave the device up and the rules configured. - * We just call nmp_route_manager_sync() to forget about the synced rules, + * We just call nmp_global_tracker_sync() to forget about the synced rules, * but we don't actually delete them. * * FIXME: that is a problem after restart of NetworkManager, because these @@ -9577,7 +9577,7 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode) * file and track them after restart again. */ keep_deleted_rules = TRUE; } - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, keep_deleted_rules); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, keep_deleted_rules); } static gboolean diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c index 23afa1833e..839aacb853 100644 --- a/src/core/nm-l3cfg.c +++ b/src/core/nm-l3cfg.c @@ -12,7 +12,7 @@ #include "libnm-glib-aux/nm-time-utils.h" #include "libnm-platform/nm-platform.h" #include "libnm-platform/nmp-object.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" #include "nm-netns.h" #include "n-acd/src/n-acd.h" #include "nm-l3-ipv4ll.h" @@ -3450,15 +3450,16 @@ nm_l3cfg_remove_config_all_dirty(NML3Cfg *self, gconstpointer tag) /*****************************************************************************/ -#define _NODEV_ROUTES_TAG(self, IS_IPv4) ((gconstpointer) (&(&(self)->priv.route_manager)[IS_IPv4])) +#define _NODEV_ROUTES_TAG(self, IS_IPv4) \ + ((gconstpointer) (&(&(self)->priv.global_tracker)[IS_IPv4])) static gboolean _nodev_routes_untrack(NML3Cfg *self, int addr_family) { - return nmp_route_manager_untrack_all(self->priv.route_manager, - _NODEV_ROUTES_TAG(self, NM_IS_IPv4(addr_family)), - FALSE, - TRUE); + return nmp_global_tracker_untrack_all(self->priv.global_tracker, + _NODEV_ROUTES_TAG(self, NM_IS_IPv4(addr_family)), + FALSE, + TRUE); } static void @@ -3478,12 +3479,12 @@ _nodev_routes_sync(NML3Cfg *self, for (i = 0; i < routes_nodev->len; i++) { const NMPObject *obj = routes_nodev->pdata[i]; - if (nmp_route_manager_track(self->priv.route_manager, - obj_type, - NMP_OBJECT_CAST_IP_ROUTE(obj), - 1, - _NODEV_ROUTES_TAG(self, IS_IPv4), - NULL)) + if (nmp_global_tracker_track(self->priv.global_tracker, + obj_type, + NMP_OBJECT_CAST_IP_ROUTE(obj), + 1, + _NODEV_ROUTES_TAG(self, IS_IPv4), + NULL)) changed = TRUE; } @@ -3492,7 +3493,9 @@ out_clear: changed = TRUE; if (changed || commit_type >= NM_L3_CFG_COMMIT_TYPE_REAPPLY) - nmp_route_manager_sync(self->priv.route_manager, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), FALSE); + nmp_global_tracker_sync(self->priv.global_tracker, + NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), + FALSE); } /*****************************************************************************/ @@ -4764,7 +4767,8 @@ constructed(GObject *object) self->priv.platform = g_object_ref(nm_netns_get_platform(self->priv.netns)); nm_assert(NM_IS_PLATFORM(self->priv.platform)); - self->priv.route_manager = nmp_route_manager_ref(nm_netns_get_route_manager(self->priv.netns)); + self->priv.global_tracker = + nmp_global_tracker_ref(nm_netns_get_global_tracker(self->priv.netns)); _LOGT("created (netns=" NM_HASH_OBFUSCATE_PTR_FMT ")", NM_HASH_OBFUSCATE_PTR(self->priv.netns)); @@ -4819,13 +4823,13 @@ finalize(GObject *object) nm_assert(c_list_is_empty(&self->priv.p->obj_state_zombie_lst_head)); if (_nodev_routes_untrack(self, AF_INET)) - nmp_route_manager_sync(self->priv.route_manager, NMP_OBJECT_TYPE_IP4_ROUTE, FALSE); + nmp_global_tracker_sync(self->priv.global_tracker, NMP_OBJECT_TYPE_IP4_ROUTE, FALSE); if (_nodev_routes_untrack(self, AF_INET6)) - nmp_route_manager_sync(self->priv.route_manager, NMP_OBJECT_TYPE_IP6_ROUTE, FALSE); + nmp_global_tracker_sync(self->priv.global_tracker, NMP_OBJECT_TYPE_IP6_ROUTE, FALSE); g_clear_object(&self->priv.netns); g_clear_object(&self->priv.platform); - nm_clear_pointer(&self->priv.route_manager, nmp_route_manager_unref); + nm_clear_pointer(&self->priv.global_tracker, nmp_global_tracker_unref); nm_clear_l3cd(&self->priv.p->combined_l3cd_merged); nm_clear_l3cd(&self->priv.p->combined_l3cd_commited); diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h index bead34933e..e0257623eb 100644 --- a/src/core/nm-l3cfg.h +++ b/src/core/nm-l3cfg.h @@ -196,18 +196,18 @@ typedef struct { } NML3ConfigNotifyData; struct _NML3CfgPrivate; -struct _NMPRouteManager; +struct _NMPGlobalTracker; struct _NML3Cfg { GObject parent; struct { - struct _NML3CfgPrivate *p; - NMNetns *netns; - NMPlatform *platform; - struct _NMPRouteManager *route_manager; - const NMPObject *plobj; - const NMPObject *plobj_next; - int ifindex; + struct _NML3CfgPrivate *p; + NMNetns *netns; + NMPlatform *platform; + struct _NMPGlobalTracker *global_tracker; + const NMPObject *plobj; + const NMPObject *plobj_next; + int ifindex; } priv; }; diff --git a/src/core/nm-netns.c b/src/core/nm-netns.c index f120e43d06..5ee6315292 100644 --- a/src/core/nm-netns.c +++ b/src/core/nm-netns.c @@ -15,21 +15,21 @@ #include "nm-l3cfg.h" #include "libnm-platform/nm-platform.h" #include "libnm-platform/nmp-netns.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PLATFORM, ); typedef struct { - NMNetns *_self_signal_user_data; - NMPlatform *platform; - NMPNetns *platform_netns; - NMPRouteManager *route_manager; - GHashTable *l3cfgs; - GHashTable *shared_ips; - CList l3cfg_signal_pending_lst_head; - GSource *signal_pending_idle_source; + NMNetns *_self_signal_user_data; + NMPlatform *platform; + NMPNetns *platform_netns; + NMPGlobalTracker *global_tracker; + GHashTable *l3cfgs; + GHashTable *shared_ips; + CList l3cfg_signal_pending_lst_head; + GSource *signal_pending_idle_source; } NMNetnsPrivate; struct _NMNetns { @@ -79,10 +79,10 @@ nm_netns_get_platform(NMNetns *self) return NM_NETNS_GET_PRIVATE(self)->platform; } -NMPRouteManager * -nm_netns_get_route_manager(NMNetns *self) +NMPGlobalTracker * +nm_netns_get_global_tracker(NMNetns *self) { - return NM_NETNS_GET_PRIVATE(self)->route_manager; + return NM_NETNS_GET_PRIVATE(self)->global_tracker; } NMDedupMultiIndex * @@ -397,14 +397,14 @@ constructed(GObject *object) priv->platform_netns = nm_platform_netns_get(priv->platform); - priv->route_manager = nmp_route_manager_new(priv->platform); + priv->global_tracker = nmp_global_tracker_new(priv->platform); /* Weakly track the default rules with a dummy user-tag. These * rules are always weekly tracked... */ - nmp_route_manager_track_rule_default(priv->route_manager, - AF_UNSPEC, - 0, - nm_netns_parent_class /* static dummy user-tag */); + nmp_global_tracker_track_rule_default(priv->global_tracker, + AF_UNSPEC, + 0, + nm_netns_parent_class /* static dummy user-tag */); /* Also weakly track all existing rules. These were added before NetworkManager * starts, so they are probably none of NetworkManager's business. @@ -414,12 +414,12 @@ constructed(GObject *object) * of NetworkManager, we just don't know. * * For that reason, whenever we will touch such rules later one, we make them - * fully owned and no longer weekly tracked. See %NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG. */ - nmp_route_manager_track_rule_from_platform(priv->route_manager, - NULL, - AF_UNSPEC, - 0, - NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); + * fully owned and no longer weekly tracked. See %NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG. */ + nmp_global_tracker_track_rule_from_platform(priv->global_tracker, + NULL, + AF_UNSPEC, + 0, + NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG); G_OBJECT_CLASS(nm_netns_parent_class)->constructed(object); @@ -469,7 +469,7 @@ dispose(GObject *object) g_clear_object(&priv->platform); nm_clear_pointer(&priv->l3cfgs, g_hash_table_unref); - nm_clear_pointer(&priv->route_manager, nmp_route_manager_unref); + nm_clear_pointer(&priv->global_tracker, nmp_global_tracker_unref); G_OBJECT_CLASS(nm_netns_parent_class)->dispose(object); } diff --git a/src/core/nm-netns.h b/src/core/nm-netns.h index deb1d1f006..17c1c63743 100644 --- a/src/core/nm-netns.h +++ b/src/core/nm-netns.h @@ -29,7 +29,7 @@ NMNetns *nm_netns_new(struct _NMPlatform *platform); struct _NMPlatform *nm_netns_get_platform(NMNetns *self); NMPNetns *nm_netns_get_platform_netns(NMNetns *self); -struct _NMPRouteManager *nm_netns_get_route_manager(NMNetns *self); +struct _NMPGlobalTracker *nm_netns_get_global_tracker(NMNetns *self); struct _NMDedupMultiIndex *nm_netns_get_multi_idx(NMNetns *self); diff --git a/src/core/platform/tests/test-route.c b/src/core/platform/tests/test-route.c index 322293e927..f0142fcb5f 100644 --- a/src/core/platform/tests/test-route.c +++ b/src/core/platform/tests/test-route.c @@ -10,7 +10,7 @@ #include "nm-core-utils.h" #include "libnm-platform/nm-platform-utils.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" #include "test-common.h" @@ -1647,8 +1647,8 @@ again: if (TEST_SYNC) { gs_unref_hashtable GHashTable *unique_priorities = g_hash_table_new(NULL, NULL); - nm_auto_unref_route_manager NMPRouteManager *route_manager = - nmp_route_manager_new(platform); + nm_auto_unref_global_tracker NMPGlobalTracker *global_tracker = + nmp_global_tracker_new(platform); gs_unref_ptrarray GPtrArray *objs_sync = NULL; gconstpointer USER_TAG_1 = &platform; gconstpointer USER_TAG_2 = &unique_priorities; @@ -1670,29 +1670,29 @@ again: } for (i = 0; i < objs_sync->len; i++) { - nmp_route_manager_track_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - 1, - USER_TAG_1, - NULL); + nmp_global_tracker_track_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + 1, + USER_TAG_1, + NULL); if (nmtst_get_rand_bool()) { /* this has no effect, because a negative priority (of same absolute value) * has lower priority than the positive priority above. */ - nmp_route_manager_track_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - -1, - USER_TAG_2, - NULL); + nmp_global_tracker_track_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + -1, + USER_TAG_2, + NULL); } if (nmtst_get_rand_uint32() % objs_sync->len == 0) { - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), ==, i + 1); } } - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), ==, objs_sync->len); @@ -1700,37 +1700,37 @@ again: for (i = 0; i < objs_sync->len; i++) { switch (nmtst_get_rand_uint32() % 3) { case 0: - nmp_route_manager_untrack_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - USER_TAG_1); - nmp_route_manager_untrack_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - USER_TAG_1); + nmp_global_tracker_untrack_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + USER_TAG_1); + nmp_global_tracker_untrack_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + USER_TAG_1); break; case 1: - nmp_route_manager_track_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - -1, - USER_TAG_1, - NULL); + nmp_global_tracker_track_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + -1, + USER_TAG_1, + NULL); break; case 2: - nmp_route_manager_track_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - -2, - USER_TAG_2, - NULL); + nmp_global_tracker_track_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + -2, + USER_TAG_2, + NULL); break; } if (nmtst_get_rand_uint32() % objs_sync->len == 0) { - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), ==, objs_sync->len - i - 1); } } - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); } else { for (i = 0; i < objs->len;) { diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index 6128b0cb8a..9c0d16164a 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -44,6 +44,15 @@ G_STATIC_ASSERT(_nm_alignof(struct in_addr) <= _nm_alignof(NMIPAddr)); G_STATIC_ASSERT(_nm_alignof(struct in6_addr) <= _nm_alignof(NMIPAddr)); G_STATIC_ASSERT(_nm_alignof(NMEtherAddr) <= _nm_alignof(NMIPAddr)); +int +nm_ip_addr_cmp_for_sort(gconstpointer a, gconstpointer b, gpointer user_data) +{ + /* This is a compare function that can be used for sorting IP addresses. + * Essentially, it calls memcmp(). @user_data must be GINT_TO_POINTER(addr_family). + * @a and @b must be either pointers to in_addr_t, struct in6_addr or NMIPAddr. */ + return nm_ip_addr_cmp(GPOINTER_TO_INT(user_data), a, b); +} + /* this initializes a struct in_addr/in6_addr and allows for untrusted * arguments (like unsuitable @addr_family or @src_len). It's almost safe * in the sense that it verifies input arguments strictly. Also, it diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index 6cdc8875ef..ab183d9ac8 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -243,11 +243,16 @@ extern const NMIPAddr nm_ip_addr_zero; static inline int nm_ip_addr_cmp(int addr_family, gconstpointer a, gconstpointer b) { + /* Note that @a and @b are not required to be full NMIPAddr unions. + * Depending on @addr_family, they can also be only in_addr_t or + * struct in6_addr. */ NM_CMP_SELF(a, b); NM_CMP_DIRECT_MEMCMP(a, b, nm_utils_addr_family_to_size(addr_family)); return 0; } +int nm_ip_addr_cmp_for_sort(gconstpointer a, gconstpointer b, gpointer user_data); + static inline gboolean nm_ip_addr_equal(int addr_family, gconstpointer a, gconstpointer b) { @@ -277,8 +282,15 @@ nm_ip_addr_set(int addr_family, gpointer dst, gconstpointer src) nm_assert(dst); nm_assert(src); - /* this MUST use memcpy() (or similar means) to support unaligned src/dst pointers. */ + /* this MUST use memcpy() to support unaligned src/dst pointers. */ memcpy(dst, src, nm_utils_addr_family_to_size(addr_family)); + + /* Note that @dst is not necessarily a NMIPAddr, it could also be just + * an in_addr_t/struct in6_addr. We thus can only set the bytes that + * we know are present based on the address family. + * + * Using this function to initialize an NMIPAddr union (for IPv4) leaves + * uninitalized bytes. Avoid that by using nm_ip_addr_init() instead. */ } static inline NMIPAddr @@ -291,6 +303,8 @@ nm_ip_addr_init(int addr_family, gconstpointer src) G_STATIC_ASSERT_EXPR(sizeof(NMIPAddr) == sizeof(struct in6_addr)); + /* this MUST use memcpy() to support unaligned src/dst pointers. */ + if (NM_IS_IPv4(addr_family)) { memcpy(&a, src, sizeof(in_addr_t)); @@ -499,8 +513,16 @@ gboolean nm_utils_ip_is_site_local(int addr_family, const void *address); /*****************************************************************************/ -#define NM_IPV4LL_NETWORK ((in_addr_t) (htonl(0xA9FE0000lu))) -#define NM_IPV4LL_NETMASK ((in_addr_t) (htonl(0xFFFF0000lu))) +#define NM_IPV4LL_NETWORK ((in_addr_t) htonl(0xA9FE0000lu)) +#define NM_IPV4LL_NETMASK ((in_addr_t) htonl(0xFFFF0000lu)) + +static inline gboolean +nm_utils_ip4_address_is_loopback(in_addr_t addr) +{ + /* There is also IN_LOOPBACK() in , but there the + * argument is in host order not `in_addr_t`. */ + return (addr & htonl(0xFF000000u)) == htonl(0x7F000000u); +} static inline gboolean nm_utils_ip4_address_is_link_local(in_addr_t addr) diff --git a/src/libnm-platform/meson.build b/src/libnm-platform/meson.build index d0a7c6c20e..e273046f10 100644 --- a/src/libnm-platform/meson.build +++ b/src/libnm-platform/meson.build @@ -7,9 +7,9 @@ libnm_platform = static_library( 'nm-netlink.c', 'nm-platform-utils.c', 'nm-platform.c', + 'nmp-global-tracker.c', 'nmp-netns.c', 'nmp-object.c', - 'nmp-route-manager.c', 'wifi/nm-wifi-utils-nl80211.c', 'wifi/nm-wifi-utils.c', 'wpan/nm-wpan-utils.c', diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index 26831c3718..e445d0757b 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -7,6 +7,8 @@ #include "nm-linux-platform.h" +#include "libnm-std-aux/nm-linux-compat.h" + #include #include #include @@ -23,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -8963,8 +8964,7 @@ ip4_address_add(NMPlatform *platform, plen, &peer_addr, flags, - nm_utils_ip4_address_is_link_local(addr) ? RT_SCOPE_LINK - : RT_SCOPE_UNIVERSE, + nm_platform_ip4_address_get_scope(addr), lifetime, preferred, broadcast_address, diff --git a/src/libnm-platform/nm-netlink.h b/src/libnm-platform/nm-netlink.h index ccd4b787c7..ec4fd4f3b8 100644 --- a/src/libnm-platform/nm-netlink.h +++ b/src/libnm-platform/nm-netlink.h @@ -304,6 +304,7 @@ nla_put_uint32(struct nl_msg *msg, int attrtype, uint32_t val) G_STMT_START \ { \ type __nla_tmp = value; \ + \ NLA_PUT(msg, attrtype, sizeof(type), &__nla_tmp); \ } \ G_STMT_END diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index 121886707d..26fffe23ac 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -1549,6 +1549,37 @@ nm_platform_route_type_uncoerce(guint8 type_coerced) return nm_platform_route_type_coerce(type_coerced); } +static inline guint8 +nm_platform_ip4_address_get_scope(in_addr_t addr) +{ + /* For IPv4 addresses, we can set any scope we want (for any address). + * However, there are scopes that make sense based on the address, + * so choose those. */ + return nm_utils_ip4_address_is_loopback(addr) ? (254 /* RT_SCOPE_HOST */) + : nm_utils_ip4_address_is_link_local(addr) ? (253 /* RT_SCOPE_LINK */) + : (0 /* RT_SCOPE_UNIVERSE */); +} + +static inline guint8 +nm_platform_ip6_address_get_scope(const struct in6_addr *addr) +{ + /* For IPv6, kernel does not allow userspace to configure the address scope. + * Instead, it is calculated based on the address. See rt_scope() and + * ipv6_addr_scope(). We do the same here. */ + return IN6_IS_ADDR_LOOPBACK(addr) ? (254 /* RT_SCOPE_HOST */) + : IN6_IS_ADDR_LINKLOCAL(addr) ? (253 /* RT_SCOPE_LINK */) + : IN6_IS_ADDR_SITELOCAL(addr) ? (200 /* RT_SCOPE_SITE */) + : (0 /* RT_SCOPE_UNIVERSE */); +} + +static inline guint8 +nm_platform_ip_address_get_scope(int addr_family, gconstpointer addr) +{ + if (NM_IS_IPv4(addr_family)) + return nm_platform_ip4_address_get_scope(*((in_addr_t *) addr)); + return nm_platform_ip6_address_get_scope(addr); +} + gboolean nm_platform_get_use_udev(NMPlatform *self); gboolean nm_platform_get_log_with_ptr(NMPlatform *self); gboolean nm_platform_get_cache_tc(NMPlatform *self); diff --git a/src/libnm-platform/nmp-route-manager.c b/src/libnm-platform/nmp-global-tracker.c similarity index 71% rename from src/libnm-platform/nmp-route-manager.c rename to src/libnm-platform/nmp-global-tracker.c index 842301b1bd..dd3df38d80 100644 --- a/src/libnm-platform/nmp-route-manager.c +++ b/src/libnm-platform/nmp-global-tracker.c @@ -2,7 +2,7 @@ #include "libnm-glib-aux/nm-default-glib-i18n-lib.h" -#include "nmp-route-manager.h" +#include "nmp-global-tracker.h" #include #include @@ -13,7 +13,37 @@ /*****************************************************************************/ -struct _NMPRouteManager { +/* NMPGlobalTracker tracks certain objects for the entire network namespace and can + * commit them. + * + * We tend to configure things per-interface and per-profile. In many cases, + * we thereby only need to care about the things for that interface. For example, + * we can configure IP addresses and (unicast) routes without having a system wide + * view. That is mainly, because such objects are themselves tied to an ifindex. + * + * However, for certain objects that's not the case. For example, policy routing + * rules, certain route types (blackhole, unavailable, prohibit, throw) and MPTCP + * endpoints require a holistic view of the system. That is, because rules and + * these route types have no ifindex. For MPTCP endpoints, they have an ifindex, + * however we can only configure a small number of them at a time, so we need a + * central (global) instance that can track which endpoints to configure. + * + * In general, the NMPGlobalTracker tracks objects for the entire namespace, and + * it's sync() method will figure out how to configure them. + * + * Since the users of NMPGloablTracker (NML3Cfg, NMDevice) themselves don't + * have this holistic view, the API of NMPGlobalTracker allows them to track + * individual objects independently (they register their objects for a private + * user-tag). If multiple such independent users track the same object, the tracking + * priority (track_priority_val) determines which one wins. + * + * NMPGlobalTracker can not only track whether an object should be present, + * it also can track whether it should be absent. See track_priority_present. + */ + +/*****************************************************************************/ + +struct _NMPGlobalTracker { NMPlatform *platform; GHashTable *by_obj; GHashTable *by_user_tag; @@ -25,17 +55,17 @@ struct _NMPRouteManager { /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_PLATFORM -#define _NMLOG_PREFIX_NAME "route-manager" +#define _NMLOG_PREFIX_NAME "global-tracker" #define _NMLOG(level, ...) __NMLOG_DEFAULT(level, LOGD_PLATFORM, _NMLOG_PREFIX_NAME, __VA_ARGS__) /*****************************************************************************/ static gboolean -NMP_IS_ROUTE_MANAGER(gpointer self) +NMP_IS_GLOBAL_TRACKER(gpointer self) { - return self && ((NMPRouteManager *) self)->ref_count > 0 - && NM_IS_PLATFORM(((NMPRouteManager *) self)->platform); + return self && ((NMPGlobalTracker *) self)->ref_count > 0 + && NM_IS_PLATFORM(((NMPGlobalTracker *) self)->platform); } /*****************************************************************************/ @@ -46,19 +76,20 @@ typedef struct { CList obj_lst; CList user_tag_lst; - /* track_priority_val zero is special: those are weakly tracked rules. + /* @track_priority_val zero is special: those are weakly tracked objects. * That means: NetworkManager will restore them only if it removed them earlier. * But it will not remove or add them otherwise. * - * Otherwise, the track_priority_val goes together with track_priority_present. - * In case of one rule being tracked multiple times (with different priorities), + * Otherwise, @track_priority_val goes together with @track_priority_present. + * In case of one object being tracked multiple times (with different priorities), * the one with higher priority wins. See _track_obj_data_get_best_data(). * Then, the winning present state either enforces that the rule is present * or absent. * - * If a rules is not tracked at all, it is ignored by NetworkManager. Assuming - * that it was added externally by the user. But unlike weakly tracked rules, - * NM will *not* restore such rules if NetworkManager themself removed them. */ + * If an object is not tracked at all, it is ignored by NetworkManager (except + * for MPTCP endpoints for the tracked interface). Assuming that it was added + * externally by the user. But unlike weakly tracked rules, NM will *not* restore + * such rules if NetworkManager themself removed them. */ guint32 track_priority_val; bool track_priority_present : 1; @@ -70,9 +101,9 @@ typedef enum { CONFIG_STATE_ADDED_BY_US = 1, CONFIG_STATE_REMOVED_BY_US = 2, - /* ConfigState encodes whether the rule was touched by us at all (CONFIG_STATE_NONE). + /* ConfigState encodes whether the object was touched by us at all (CONFIG_STATE_NONE). * - * Maybe we would only need to track whether we touched the rule at all. But we + * Maybe we would only need to track whether we touched the object at all. But we * track it more in detail what we did: did we add it (CONFIG_STATE_ADDED_BY_US) * or did we remove it (CONFIG_STATE_REMOVED_BY_US)? * Finally, we need CONFIG_STATE_OWNED_BY_US, which means that we didn't actively @@ -88,16 +119,16 @@ typedef struct { CList by_obj_lst; - /* indicates whether we configured/removed the rule (during sync()). We need that, so - * if the rule gets untracked, that we know to remove/restore it. + /* indicates whether we configured/removed the object (during sync()). We need that, so + * if the object gets untracked, that we know to remove/restore it. * - * This makes NMPRouteManager stateful (beyond the configuration that indicates - * which rules are tracked). - * After a restart, NetworkManager would no longer remember which rules were added + * This makes NMPGlobalTracker stateful (beyond the configuration that indicates + * which objects are tracked). + * After a restart, NetworkManager would no longer remember which objects were added * by us. * - * That is partially fixed by NetworkManager taking over the rules that it - * actively configures (see %NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG). */ + * That is partially fixed by NetworkManager taking over the objects that it + * actively configures (see %NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG). */ ConfigState config_state; } TrackObjData; @@ -108,15 +139,15 @@ typedef struct { /*****************************************************************************/ -static void _track_data_untrack(NMPRouteManager *self, - TrackData *track_data, - gboolean remove_user_tag_data, - gboolean make_owned_by_us); +static void _track_data_untrack(NMPGlobalTracker *self, + TrackData *track_data, + gboolean remove_user_tag_data, + gboolean make_owned_by_us); /*****************************************************************************/ static CList * -_by_obj_lst_head(NMPRouteManager *self, NMPObjectType obj_type) +_by_obj_lst_head(NMPGlobalTracker *self, NMPObjectType obj_type) { G_STATIC_ASSERT(G_N_ELEMENTS(self->by_obj_lst_heads) == 3); @@ -266,8 +297,8 @@ _track_data_lookup(GHashTable *by_data, const NMPObject *obj, gconstpointer user /*****************************************************************************/ /** - * nmp_route_manager_track: - * @self: the #NMPRouteManager instance + * nmp_global_tracker_track: + * @self: the #NMPGlobalTracker instance * @obj_type: the NMPObjectType of @obj that we are tracking. * @obj: the NMPlatformObject (of type NMPObjectType) to track. Usually * a #NMPlatformRoutingRule, #NMPlatformIP4Route or #NMPlatformIP6Route @@ -282,20 +313,20 @@ _track_data_lookup(GHashTable *by_data, const NMPObject *obj, gconstpointer user * @user_tag: the tag associated with tracking this rule. The same tag * must be used to untrack the rule later. * @user_tag_untrack: if not %NULL, at the same time untrack this user-tag - * for the same rule. Note that this is different from a plain nmp_route_manager_untrack_rule(), + * for the same rule. Note that this is different from a plain nmp_global_tracker_untrack_rule(), * because it enforces ownership of the now tracked rule. On the other hand, - * a plain nmp_route_manager_untrack_rule() merely forgets about the tracking. - * The purpose here is to set this to %NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG. + * a plain nmp_global_tracker_untrack_rule() merely forgets about the tracking. + * The purpose here is to set this to %NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG. * * Returns: %TRUE, if something changed. */ gboolean -nmp_route_manager_track(NMPRouteManager *self, - NMPObjectType obj_type, - gconstpointer obj, - gint32 track_priority, - gconstpointer user_tag, - gconstpointer user_tag_untrack) +nmp_global_tracker_track(NMPGlobalTracker *self, + NMPObjectType obj_type, + gconstpointer obj, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack) { NMPObject obj_stack; const NMPObject *p_obj_stack; @@ -307,7 +338,7 @@ nmp_route_manager_track(NMPRouteManager *self, guint32 track_priority_val; gboolean track_priority_present; - g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), FALSE); + g_return_val_if_fail(NMP_IS_GLOBAL_TRACKER(self), FALSE); g_return_val_if_fail(obj, FALSE); g_return_val_if_fail(user_tag, FALSE); @@ -414,15 +445,15 @@ nmp_route_manager_track(NMPRouteManager *self, } static void -_track_data_untrack(NMPRouteManager *self, - TrackData *track_data, - gboolean remove_user_tag_data, - gboolean make_owned_by_us) +_track_data_untrack(NMPGlobalTracker *self, + TrackData *track_data, + gboolean remove_user_tag_data, + gboolean make_owned_by_us) { char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE]; TrackObjData *obj_data; - nm_assert(NMP_IS_ROUTE_MANAGER(self)); + nm_assert(NMP_IS_GLOBAL_TRACKER(self)); _track_data_assert(track_data, TRUE); nm_assert(self->by_data); nm_assert(g_hash_table_lookup(self->by_data, track_data) == track_data); @@ -467,17 +498,17 @@ _track_data_untrack(NMPRouteManager *self, } gboolean -nmp_route_manager_untrack(NMPRouteManager *self, - NMPObjectType obj_type, - gconstpointer obj, - gconstpointer user_tag) +nmp_global_tracker_untrack(NMPGlobalTracker *self, + NMPObjectType obj_type, + gconstpointer obj, + gconstpointer user_tag) { NMPObject obj_stack; const NMPObject *p_obj_stack; TrackData *track_data; gboolean changed = FALSE; - g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), FALSE); + g_return_val_if_fail(NMP_IS_GLOBAL_TRACKER(self), FALSE); nm_assert(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE, @@ -499,12 +530,12 @@ nmp_route_manager_untrack(NMPRouteManager *self, } void -nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag) +nmp_global_tracker_set_dirty(NMPGlobalTracker *self, gconstpointer user_tag) { TrackData *track_data; TrackUserTagData *user_tag_data; - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); g_return_if_fail(user_tag); user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); @@ -516,17 +547,17 @@ nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag) } gboolean -nmp_route_manager_untrack_all(NMPRouteManager *self, - gconstpointer user_tag, - gboolean all /* or only dirty */, - gboolean make_survivors_dirty) +nmp_global_tracker_untrack_all(NMPGlobalTracker *self, + gconstpointer user_tag, + gboolean all /* or only dirty */, + gboolean make_survivors_dirty) { TrackData *track_data; TrackData *track_data_safe; TrackUserTagData *user_tag_data; gboolean changed = FALSE; - g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), FALSE); + g_return_val_if_fail(NMP_IS_GLOBAL_TRACKER(self), FALSE); g_return_val_if_fail(user_tag, FALSE); user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); @@ -554,7 +585,7 @@ nmp_route_manager_untrack_all(NMPRouteManager *self, /*****************************************************************************/ void -nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean keep_deleted) +nmp_global_tracker_sync(NMPGlobalTracker *self, NMPObjectType obj_type, gboolean keep_deleted) { char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE]; const NMDedupMultiHeadEntry *pl_head_entry; @@ -567,7 +598,7 @@ nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean k guint i; const TrackData *td_best; - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); g_return_if_fail(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE, @@ -677,18 +708,18 @@ nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean k /*****************************************************************************/ void -nmp_route_manager_track_rule_from_platform(NMPRouteManager *self, - NMPlatform *platform, - int addr_family, - gint32 tracking_priority, - gconstpointer user_tag) +nmp_global_tracker_track_rule_from_platform(NMPGlobalTracker *self, + NMPlatform *platform, + int addr_family, + gint32 tracking_priority, + gconstpointer user_tag) { NMPLookup lookup; const NMDedupMultiHeadEntry *head_entry; NMDedupMultiIter iter; const NMPObject *o; - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); if (!platform) platform = self->platform; @@ -705,98 +736,98 @@ nmp_route_manager_track_rule_from_platform(NMPRouteManager *self, if (addr_family != AF_UNSPEC && rr->addr_family != addr_family) continue; - nmp_route_manager_track_rule(self, rr, tracking_priority, user_tag, NULL); + nmp_global_tracker_track_rule(self, rr, tracking_priority, user_tag, NULL); } } /*****************************************************************************/ void -nmp_route_manager_track_rule_default(NMPRouteManager *self, - int addr_family, - gint32 track_priority, - gconstpointer user_tag) +nmp_global_tracker_track_rule_default(NMPGlobalTracker *self, + int addr_family, + gint32 track_priority, + gconstpointer user_tag) { - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); /* track the default rules. See also `man ip-rule`. */ if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET, - .priority = 0, - .table = RT_TABLE_LOCAL, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET, - .priority = 32766, - .table = RT_TABLE_MAIN, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET, - .priority = 32767, - .table = RT_TABLE_DEFAULT, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 0, + .table = RT_TABLE_LOCAL, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 32766, + .table = RT_TABLE_MAIN, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 32767, + .table = RT_TABLE_DEFAULT, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); } if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET6, - .priority = 0, - .table = RT_TABLE_LOCAL, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET6, - .priority = 32766, - .table = RT_TABLE_MAIN, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET6, + .priority = 0, + .table = RT_TABLE_LOCAL, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET6, + .priority = 32766, + .table = RT_TABLE_MAIN, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); } } /*****************************************************************************/ -NMPRouteManager * -nmp_route_manager_new(NMPlatform *platform) +NMPGlobalTracker * +nmp_global_tracker_new(NMPlatform *platform) { - NMPRouteManager *self; + NMPGlobalTracker *self; g_return_val_if_fail(NM_IS_PLATFORM(platform), NULL); G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(TrackUserTagData, user_tag) == 0); - self = g_slice_new(NMPRouteManager); - *self = (NMPRouteManager){ + self = g_slice_new(NMPGlobalTracker); + *self = (NMPGlobalTracker){ .ref_count = 1, .platform = g_object_ref(platform), .by_data = @@ -816,19 +847,19 @@ nmp_route_manager_new(NMPlatform *platform) return self; } -NMPRouteManager * -nmp_route_manager_ref(NMPRouteManager *self) +NMPGlobalTracker * +nmp_global_tracker_ref(NMPGlobalTracker *self) { - g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), NULL); + g_return_val_if_fail(NMP_IS_GLOBAL_TRACKER(self), NULL); self->ref_count++; return self; } void -nmp_route_manager_unref(NMPRouteManager *self) +nmp_global_tracker_unref(NMPGlobalTracker *self) { - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); if (--self->ref_count > 0) return; diff --git a/src/libnm-platform/nmp-global-tracker.h b/src/libnm-platform/nmp-global-tracker.h new file mode 100644 index 0000000000..61a4c1eb58 --- /dev/null +++ b/src/libnm-platform/nmp-global-tracker.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NMP_GLOBAL_TRACKER_H__ +#define __NMP_GLOBAL_TRACKER_H__ + +#include "nm-platform.h" + +/*****************************************************************************/ + +#define NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG ((const void *) nmp_global_tracker_new) + +typedef struct _NMPGlobalTracker NMPGlobalTracker; + +NMPGlobalTracker *nmp_global_tracker_new(NMPlatform *platform); + +NMPGlobalTracker *nmp_global_tracker_ref(NMPGlobalTracker *self); +void nmp_global_tracker_unref(NMPGlobalTracker *self); + +#define nm_auto_unref_global_tracker nm_auto(_nmp_global_tracker_unref) +NM_AUTO_DEFINE_FCN0(NMPGlobalTracker *, _nmp_global_tracker_unref, nmp_global_tracker_unref); + +gboolean nmp_global_tracker_track(NMPGlobalTracker *self, + NMPObjectType obj_type, + gconstpointer obj, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack); + +static inline gboolean +nmp_global_tracker_track_rule(NMPGlobalTracker *self, + const NMPlatformRoutingRule *routing_rule, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack) +{ + return nmp_global_tracker_track(self, + NMP_OBJECT_TYPE_ROUTING_RULE, + routing_rule, + track_priority, + user_tag, + user_tag_untrack); +} + +void nmp_global_tracker_track_rule_default(NMPGlobalTracker *self, + int addr_family, + gint32 track_priority, + gconstpointer user_tag); + +void nmp_global_tracker_track_rule_from_platform(NMPGlobalTracker *self, + NMPlatform *platform, + int addr_family, + gint32 tracking_priority, + gconstpointer user_tag); + +gboolean nmp_global_tracker_untrack(NMPGlobalTracker *self, + NMPObjectType obj_type, + gconstpointer obj, + gconstpointer user_tag); + +static inline gboolean +nmp_global_tracker_untrack_rule(NMPGlobalTracker *self, + const NMPlatformRoutingRule *routing_rule, + gconstpointer user_tag) +{ + return nmp_global_tracker_untrack(self, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule, user_tag); +} + +void nmp_global_tracker_set_dirty(NMPGlobalTracker *self, gconstpointer user_tag); + +gboolean nmp_global_tracker_untrack_all(NMPGlobalTracker *self, + gconstpointer user_tag, + gboolean all /* or only dirty */, + gboolean make_survivors_dirty); + +void nmp_global_tracker_sync(NMPGlobalTracker *self, NMPObjectType obj_type, gboolean keep_deleted); + +/*****************************************************************************/ + +#endif /* __NMP_GLOBAL_TRACKER_H__ */ diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c index eb5306a66d..edccef3373 100644 --- a/src/libnm-platform/nmp-object.c +++ b/src/libnm-platform/nmp-object.c @@ -1564,6 +1564,8 @@ _vt_cmd_plobj_id_cmp(mptcp_addr, NMPlatformMptcpAddr, { * for instances which are not "in_kernel". While we might receive unexpected values * from kernel, we should not create them for internal purposes. */ NM_CMP_FIELD_MEMCMP_LEN(obj1, obj2, addr, nm_utils_addr_family_to_size(obj1->addr_family)); + + NM_CMP_FIELD(obj1, obj2, port); } }); @@ -1657,7 +1659,7 @@ _vt_cmd_plobj_id_hash_update(mptcp_addr, NMPlatformMptcpAddr, { nm_hash_update_val(h, obj->id); } else { /* _vt_cmd_plobj_id_cmp_mptcp_addr for why. */ - nm_hash_update_vals(h, obj->id, obj->addr_family); + nm_hash_update_vals(h, obj->id, obj->addr_family, obj->port); nm_hash_update(h, &obj->addr, nm_utils_addr_family_to_size(obj->addr_family)); } }); diff --git a/src/libnm-platform/nmp-route-manager.h b/src/libnm-platform/nmp-route-manager.h deleted file mode 100644 index 97ec3840df..0000000000 --- a/src/libnm-platform/nmp-route-manager.h +++ /dev/null @@ -1,79 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#ifndef __NMP_ROUTE_MANAGER_H__ -#define __NMP_ROUTE_MANAGER_H__ - -#include "nm-platform.h" - -/*****************************************************************************/ - -#define NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG ((const void *) nmp_route_manager_new) - -typedef struct _NMPRouteManager NMPRouteManager; - -NMPRouteManager *nmp_route_manager_new(NMPlatform *platform); - -NMPRouteManager *nmp_route_manager_ref(NMPRouteManager *self); -void nmp_route_manager_unref(NMPRouteManager *self); - -#define nm_auto_unref_route_manager nm_auto(_nmp_route_manager_unref) -NM_AUTO_DEFINE_FCN0(NMPRouteManager *, _nmp_route_manager_unref, nmp_route_manager_unref); - -gboolean nmp_route_manager_track(NMPRouteManager *self, - NMPObjectType obj_type, - gconstpointer obj, - gint32 track_priority, - gconstpointer user_tag, - gconstpointer user_tag_untrack); - -static inline gboolean -nmp_route_manager_track_rule(NMPRouteManager *self, - const NMPlatformRoutingRule *routing_rule, - gint32 track_priority, - gconstpointer user_tag, - gconstpointer user_tag_untrack) -{ - return nmp_route_manager_track(self, - NMP_OBJECT_TYPE_ROUTING_RULE, - routing_rule, - track_priority, - user_tag, - user_tag_untrack); -} - -void nmp_route_manager_track_rule_default(NMPRouteManager *self, - int addr_family, - gint32 track_priority, - gconstpointer user_tag); - -void nmp_route_manager_track_rule_from_platform(NMPRouteManager *self, - NMPlatform *platform, - int addr_family, - gint32 tracking_priority, - gconstpointer user_tag); - -gboolean nmp_route_manager_untrack(NMPRouteManager *self, - NMPObjectType obj_type, - gconstpointer obj, - gconstpointer user_tag); - -static inline gboolean -nmp_route_manager_untrack_rule(NMPRouteManager *self, - const NMPlatformRoutingRule *routing_rule, - gconstpointer user_tag) -{ - return nmp_route_manager_untrack(self, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule, user_tag); -} - -void nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag); - -gboolean nmp_route_manager_untrack_all(NMPRouteManager *self, - gconstpointer user_tag, - gboolean all /* or only dirty */, - gboolean make_survivors_dirty); - -void nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean keep_deleted); - -/*****************************************************************************/ - -#endif /* __NMP_ROUTE_MANAGER_H__ */ diff --git a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c index 1875a42068..eab50f1615 100644 --- a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c @@ -9,14 +9,14 @@ #include "nm-wifi-utils-nl80211.h" +#include "libnm-std-aux/nm-linux-compat.h" + #include #include #include #include #include -#include "linux-headers/nl80211-vnd-intel.h" - #include "libnm-log-core/nm-logging.h" #include "libnm-platform/nm-netlink.h" #include "nm-wifi-utils-private.h" diff --git a/src/libnm-platform/wpan/nm-wpan-utils.c b/src/libnm-platform/wpan/nm-wpan-utils.c index 0afbe58d3e..9350a2a780 100644 --- a/src/libnm-platform/wpan/nm-wpan-utils.c +++ b/src/libnm-platform/wpan/nm-wpan-utils.c @@ -80,7 +80,8 @@ _nl802154_alloc_msg(guint16 genl_family_id, int ifindex, uint8_t cmd, uint16_t f nm_auto_nlmsg struct nl_msg *msg = NULL; msg = nlmsg_alloc(); - genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, genl_family_id, 0, flags, cmd, 0); + if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, genl_family_id, 0, flags, cmd, 0)) + goto nla_put_failure; NLA_PUT_U32(msg, NL802154_ATTR_IFINDEX, ifindex); return g_steal_pointer(&msg); diff --git a/src/libnm-std-aux/nm-linux-compat.h b/src/libnm-std-aux/nm-linux-compat.h index 7ca7ec781c..2675393d87 100644 --- a/src/libnm-std-aux/nm-linux-compat.h +++ b/src/libnm-std-aux/nm-linux-compat.h @@ -21,5 +21,7 @@ #include "linux-headers/ethtool.h" #include "linux-headers/nl802154.h" +#include "linux-headers/nl80211-vnd-intel.h" +#include "linux-headers/mptcp.h" #endif /* __NM_LINUX_COMPAT_H__ */