platform: merge branch 'th/mptcp-1'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1312
This commit is contained in:
Thomas Haller 2022-07-26 18:24:08 +02:00
commit 56f0fb752e
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
21 changed files with 434 additions and 331 deletions

View file

@ -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 \

View file

@ -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"

View file

@ -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

View file

@ -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);

View file

@ -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;
};

View file

@ -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);
}

View file

@ -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);

View file

@ -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;) {

View file

@ -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

View file

@ -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 <linux/in.h>, 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)

View file

@ -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',

View file

@ -7,6 +7,8 @@
#include "nm-linux-platform.h"
#include "libnm-std-aux/nm-linux-compat.h"
#include <arpa/inet.h>
#include <dlfcn.h>
#include <endian.h>
@ -23,7 +25,6 @@
#include <linux/if_vlan.h>
#include <linux/ip6_tunnel.h>
#include <linux/tc_act/tc_mirred.h>
#include <linux-headers/mptcp.h>
#include <netinet/icmp6.h>
#include <netinet/in.h>
#include <net/if_arp.h>
@ -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,

View file

@ -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

View file

@ -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);

View file

@ -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 <linux/fib_rules.h>
#include <linux/rtnetlink.h>
@ -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;

View file

@ -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__ */

View file

@ -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));
}
});

View file

@ -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__ */

View file

@ -9,14 +9,14 @@
#include "nm-wifi-utils-nl80211.h"
#include "libnm-std-aux/nm-linux-compat.h"
#include <sys/ioctl.h>
#include <net/ethernet.h>
#include <unistd.h>
#include <linux/nl80211.h>
#include <linux/if.h>
#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"

View file

@ -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);

View file

@ -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__ */