merge: branch 'bg/mptcp-endpoints'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2141

(cherry picked from commit 472a7b48e8)
This commit is contained in:
Beniamino Galvani
2025-02-24 08:56:27 +01:00
3 changed files with 81 additions and 11 deletions

View File

@@ -372,6 +372,8 @@ G_DEFINE_TYPE(NML3Cfg, nm_l3cfg, G_TYPE_OBJECT)
#define _NETNS_WATCHER_IP_ADDR_TAG(self, addr_family) \ #define _NETNS_WATCHER_IP_ADDR_TAG(self, addr_family) \
((gconstpointer) & (((char *) self)[1 + NM_IS_IPv4(addr_family)])) ((gconstpointer) & (((char *) self)[1 + NM_IS_IPv4(addr_family)]))
#define _NETNS_WATCHER_MPTCP_IPV6_TAG(self) ((gconstpointer) & (((char *) self)[3]))
/*****************************************************************************/ /*****************************************************************************/
#define _NMLOG_DOMAIN LOGD_CORE #define _NMLOG_DOMAIN LOGD_CORE
@@ -4960,7 +4962,7 @@ next:
} }
out: out:
nm_netns_watcher_remove_all(self->priv.netns, TAG, FALSE); nm_netns_watcher_remove_dirty(self->priv.netns, TAG);
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -4973,6 +4975,30 @@ _global_tracker_mptcp_untrack(NML3Cfg *self, int addr_family)
TRUE); TRUE);
} }
static void
mptcp_ipv6_addr_cb(NMNetns *netns,
NMNetnsWatcherType watcher_type,
const NMNetnsWatcherData *watcher_data,
gconstpointer tag,
const NMNetnsWatcherEventData *event_data,
gpointer user_data)
{
NML3Cfg *self = user_data;
if (event_data->ip_addr.change_type == NM_PLATFORM_SIGNAL_REMOVED)
return;
nm_assert(NMP_OBJECT_GET_TYPE(event_data->ip_addr.obj) == NMP_OBJECT_TYPE_IP6_ADDRESS);
if (event_data->ip_addr.obj->ip6_address.n_ifa_flags & IFA_F_TENTATIVE)
return;
/* We are inside the handler for a platform event, we should not
* perform other operations on platform synchronously. Schedule a
* commit in a idle handler. */
nm_l3cfg_commit_on_idle_schedule(self, NM_L3_CFG_COMMIT_TYPE_AUTO);
}
static gboolean static gboolean
_l3_commit_mptcp_af(NML3Cfg *self, _l3_commit_mptcp_af(NML3Cfg *self,
NML3CfgCommitType commit_type, NML3CfgCommitType commit_type,
@@ -5051,6 +5077,8 @@ _l3_commit_mptcp_af(NML3Cfg *self,
self->priv.p->combined_l3cd_commited, self->priv.p->combined_l3cd_commited,
addr_family, addr_family,
(const NMPlatformIPAddress **) &addr) { (const NMPlatformIPAddress **) &addr) {
const NMPObject *obj;
/* We want to evaluate the with-{loopback,link_local}-{4,6} flags based on the actual /* We want to evaluate the with-{loopback,link_local}-{4,6} flags based on the actual
* ifa_scope that the address will have once we configure it. * ifa_scope that the address will have once we configure it.
* "addr" is an address we want to configure, we expect that it will * "addr" is an address we want to configure, we expect that it will
@@ -5077,6 +5105,34 @@ _l3_commit_mptcp_af(NML3Cfg *self,
break; break;
} }
obj = nm_platform_ip_address_get(self->priv.platform,
addr_family,
self->priv.ifindex,
addr);
if (!obj) {
/* The address is not yet configured in platform, typically due to
* IPv4 DAD; skip it for now otherwise the kernel will try to use
* the endpoint, it will fail, and it will never try it again. */
goto skip_addr;
}
if (!IS_IPv4 && (obj->ip6_address.n_ifa_flags & IFA_F_TENTATIVE)) {
NMNetnsWatcherData watcher_data = {};
/* The endpoint is not usable when the address is tentative.
* Watch the address until it becomes non-tentative and then
* schedule a new commit. */
watcher_data.ip_addr.addr.addr_family = AF_INET6;
watcher_data.ip_addr.addr.addr.addr6 = addr->a6.address;
nm_netns_watcher_add(self->priv.netns,
NM_NETNS_WATCHER_TYPE_IP_ADDR,
&watcher_data,
_NETNS_WATCHER_MPTCP_IPV6_TAG(self),
mptcp_ipv6_addr_cb,
self);
goto skip_addr;
}
a.addr = nm_ip_addr_init(addr_family, addr->ax.address_ptr); a.addr = nm_ip_addr_init(addr_family, addr->ax.address_ptr);
/* We track the address with different priorities, that depends /* We track the address with different priorities, that depends
@@ -5105,6 +5161,8 @@ skip_addr:
} }
} }
nm_netns_watcher_remove_dirty(self->priv.netns, _NETNS_WATCHER_MPTCP_IPV6_TAG(self));
if (!any_tracked) { if (!any_tracked) {
/* We need to make it known that this ifindex is used. Track a dummy object. */ /* We need to make it known that this ifindex is used. Track a dummy object. */
if (nmp_global_tracker_track( if (nmp_global_tracker_track(
@@ -5841,12 +5899,9 @@ finalize(GObject *object)
gboolean changed; gboolean changed;
if (self->priv.netns) { if (self->priv.netns) {
nm_netns_watcher_remove_all(self->priv.netns, nm_netns_watcher_remove_all(self->priv.netns, _NETNS_WATCHER_IP_ADDR_TAG(self, AF_INET));
_NETNS_WATCHER_IP_ADDR_TAG(self, AF_INET), nm_netns_watcher_remove_all(self->priv.netns, _NETNS_WATCHER_IP_ADDR_TAG(self, AF_INET6));
TRUE); nm_netns_watcher_remove_all(self->priv.netns, _NETNS_WATCHER_MPTCP_IPV6_TAG(self));
nm_netns_watcher_remove_all(self->priv.netns,
_NETNS_WATCHER_IP_ADDR_TAG(self, AF_INET6),
TRUE);
} }
nm_prioq_destroy(&self->priv.p->failedobj_prioq); nm_prioq_destroy(&self->priv.p->failedobj_prioq);

View File

@@ -1369,8 +1369,8 @@ nm_netns_watcher_remove_handle(NMNetns *self, NMNetnsWatcherHandle *handle)
g_object_unref(self); g_object_unref(self);
} }
void static void
nm_netns_watcher_remove_all(NMNetns *self, gconstpointer tag, gboolean all) watcher_remove(NMNetns *self, gconstpointer tag, gboolean all)
{ {
NMNetnsPrivate *priv; NMNetnsPrivate *priv;
WatcherByTag *watcher_by_tag; WatcherByTag *watcher_by_tag;
@@ -1420,6 +1420,21 @@ nm_netns_watcher_remove_all(NMNetns *self, gconstpointer tag, gboolean all)
} }
} }
void
nm_netns_watcher_remove_all(NMNetns *self, gconstpointer tag)
{
watcher_remove(self, tag, TRUE);
}
/* Similar to nm_netns_watcher_remove_all(), but removes only watchers
* that were marked as "dirty" in a previous call of this function and were
* not added back via nm_netns_watcher_add() in the meantime. */
void
nm_netns_watcher_remove_dirty(NMNetns *self, gconstpointer tag)
{
watcher_remove(self, tag, FALSE);
}
/*****************************************************************************/ /*****************************************************************************/
static void static void

View File

@@ -98,7 +98,7 @@ void nm_netns_watcher_add(NMNetns *self,
NMNetnsWatcherCallback callback, NMNetnsWatcherCallback callback,
gpointer user_data); gpointer user_data);
void void nm_netns_watcher_remove_all(NMNetns *self, gconstpointer tag);
nm_netns_watcher_remove_all(NMNetns *self, gconstpointer tag, gboolean all /* or only dirty */); void nm_netns_watcher_remove_dirty(NMNetns *self, gconstpointer tag);
#endif /* __NM_NETNS_H__ */ #endif /* __NM_NETNS_H__ */