You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
9.8 KiB
243 lines
9.8 KiB
2 days ago
|
From 3fe666c300e9d7022c1e6f583aceeaa1ccc0975e Mon Sep 17 00:00:00 2001
|
||
|
From: Wen Liang <wenliang@redhat.com>
|
||
|
Date: Fri, 20 Dec 2024 10:10:25 -0500
|
||
|
Subject: [PATCH 1/1] vpn: fix routing rules support in vpn conenctions
|
||
|
|
||
|
This commit introduces the ability to manage routing rules specifically
|
||
|
for VPN connections. These rules allow finer control over traffic
|
||
|
routing by enabling the specification of policy-based routing for
|
||
|
traffic over the VPN.
|
||
|
|
||
|
- Updated the connection backend to apply rules during VPN activation.
|
||
|
- Ensured proper cleanup of routing rules upon VPN deactivation.
|
||
|
|
||
|
This enhancement improves VPN usability in scenarios requiring advanced
|
||
|
routing configurations, such as split tunneling and traffic
|
||
|
prioritization.
|
||
|
|
||
|
Resolves: https://issues.redhat.com/browse/RHEL-70160
|
||
|
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2092
|
||
|
https://gitlab.freedesktop.org/NetworkManager/NetworkManager-ci/-/merge_requests/1842
|
||
|
(cherry picked from commit 308e34a501482d01c1cc6c87c38791ad9f34dc1f)
|
||
|
(cherry picked from commit a24b347e93e37b04aa0f5698efcb462c02517c09)
|
||
|
(cherry picked from commit b5c46f8a8d644e1c5a6dc07e06d5dab3338e9a91)
|
||
|
(cherry picked from commit 7824d5e5ae5db78abdc6fa24453d939198a5d1da)
|
||
|
(cherry picked from commit f5e8217f77863742ac17b2ad30134a14125acd40)
|
||
|
(cherry picked from commit dcbe04ef5f8bf947d1da4e55a1b9b0ca498d852d)
|
||
|
(cherry picked from commit 49a8b0650f2a19c0e16e2912c88b8e74c5aa8feb)
|
||
|
---
|
||
|
src/core/devices/nm-device.c | 62 +++++++++++++++++++-------------
|
||
|
src/core/devices/nm-device.h | 6 ++++
|
||
|
src/core/vpn/nm-vpn-connection.c | 7 +++-
|
||
|
3 files changed, 50 insertions(+), 25 deletions(-)
|
||
|
|
||
|
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
|
||
|
index e54942440f..9c4e581e68 100644
|
||
|
--- a/src/core/devices/nm-device.c
|
||
|
+++ b/src/core/devices/nm-device.c
|
||
|
@@ -9577,31 +9577,34 @@ lldp_setup(NMDevice *self, NMTernary enabled)
|
||
|
* as externally added ones. Don't restart NetworkManager if
|
||
|
* you care about that.
|
||
|
*/
|
||
|
-static void
|
||
|
-_routing_rules_sync(NMDevice *self, NMTernary set_mode)
|
||
|
+void
|
||
|
+nm_routing_rules_sync(NMConnection *applied_connection,
|
||
|
+ NMTernary set_mode,
|
||
|
+ GPtrArray *(*get_extra_rules)(NMDevice *self),
|
||
|
+ NMDevice *self,
|
||
|
+ NMNetns *netns)
|
||
|
{
|
||
|
- 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);
|
||
|
+ NMPGlobalTracker *global_tracker = nm_netns_get_global_tracker(netns);
|
||
|
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;
|
||
|
- user_tag_2 = &priv->v6_route_table;
|
||
|
+ if (self) {
|
||
|
+ user_tag_1 = ((guint32 *) self) + 1;
|
||
|
+ user_tag_2 = ((guint32 *) self) + 2;
|
||
|
+ } else {
|
||
|
+ user_tag_1 = ((guint32 *) applied_connection) + 1;
|
||
|
+ user_tag_2 = ((guint32 *) applied_connection) + 2;
|
||
|
+ }
|
||
|
|
||
|
if (set_mode == NM_TERNARY_TRUE) {
|
||
|
- NMConnection *applied_connection;
|
||
|
NMSettingIPConfig *s_ip;
|
||
|
guint i, num;
|
||
|
int is_ipv4;
|
||
|
|
||
|
untrack_only_dirty = TRUE;
|
||
|
|
||
|
- applied_connection = nm_device_get_applied_connection(self);
|
||
|
-
|
||
|
for (is_ipv4 = 0; applied_connection && is_ipv4 < 2; is_ipv4++) {
|
||
|
int addr_family = is_ipv4 ? AF_INET : AF_INET6;
|
||
|
|
||
|
@@ -9628,10 +9631,10 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- if (klass->get_extra_rules) {
|
||
|
+ if (get_extra_rules) {
|
||
|
gs_unref_ptrarray GPtrArray *extra_rules = NULL;
|
||
|
|
||
|
- extra_rules = klass->get_extra_rules(self);
|
||
|
+ extra_rules = get_extra_rules(self);
|
||
|
if (extra_rules) {
|
||
|
for (i = 0; i < extra_rules->len; i++) {
|
||
|
nmp_global_tracker_track_rule(
|
||
|
@@ -9646,7 +9649,7 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode)
|
||
|
}
|
||
|
|
||
|
nmp_global_tracker_untrack_all(global_tracker, user_tag_1, !untrack_only_dirty, TRUE);
|
||
|
- if (klass->get_extra_rules)
|
||
|
+ if (get_extra_rules)
|
||
|
nmp_global_tracker_untrack_all(global_tracker, user_tag_2, !untrack_only_dirty, TRUE);
|
||
|
|
||
|
keep_deleted_rules = FALSE;
|
||
|
@@ -9706,8 +9709,8 @@ tc_commit(NMDevice *self)
|
||
|
static void
|
||
|
activate_stage2_device_config(NMDevice *self)
|
||
|
{
|
||
|
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||
|
- NMDeviceClass *klass;
|
||
|
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||
|
+ NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self);
|
||
|
NMActStageReturn ret;
|
||
|
NMSettingWired *s_wired;
|
||
|
gboolean no_firmware = FALSE;
|
||
|
@@ -9730,7 +9733,11 @@ activate_stage2_device_config(NMDevice *self)
|
||
|
priv->tc_committed = TRUE;
|
||
|
}
|
||
|
|
||
|
- _routing_rules_sync(self, NM_TERNARY_TRUE);
|
||
|
+ nm_routing_rules_sync(nm_device_get_applied_connection(self),
|
||
|
+ NM_TERNARY_TRUE,
|
||
|
+ klass->get_extra_rules,
|
||
|
+ self,
|
||
|
+ nm_device_get_netns(self));
|
||
|
|
||
|
if (!nm_device_sys_iface_state_is_external_or_assume(self)) {
|
||
|
if (!nm_device_bring_up_full(self, FALSE, TRUE, &no_firmware)) {
|
||
|
@@ -9742,7 +9749,6 @@ activate_stage2_device_config(NMDevice *self)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- klass = NM_DEVICE_GET_CLASS(self);
|
||
|
if (klass->act_stage2_config_also_for_external_or_assume
|
||
|
|| !nm_device_sys_iface_state_is_external_or_assume(self)) {
|
||
|
NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
|
||
|
@@ -12984,7 +12990,11 @@ check_and_reapply_connection(NMDevice *self,
|
||
|
|
||
|
nm_device_activate_schedule_stage3_ip_config(self, FALSE);
|
||
|
|
||
|
- _routing_rules_sync(self, NM_TERNARY_TRUE);
|
||
|
+ nm_routing_rules_sync(nm_device_get_applied_connection(self),
|
||
|
+ NM_TERNARY_TRUE,
|
||
|
+ klass->get_extra_rules,
|
||
|
+ self,
|
||
|
+ nm_device_get_netns(self));
|
||
|
|
||
|
reactivate_proxy_config(self);
|
||
|
|
||
|
@@ -15450,6 +15460,7 @@ static void
|
||
|
nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanup_type)
|
||
|
{
|
||
|
NMDevicePrivate *priv;
|
||
|
+ NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self);
|
||
|
int ifindex;
|
||
|
|
||
|
g_return_if_fail(NM_IS_DEVICE(self));
|
||
|
@@ -15474,8 +15485,8 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu
|
||
|
}
|
||
|
|
||
|
/* Call device type-specific deactivation */
|
||
|
- if (NM_DEVICE_GET_CLASS(self)->deactivate)
|
||
|
- NM_DEVICE_GET_CLASS(self)->deactivate(self);
|
||
|
+ if (klass->deactivate)
|
||
|
+ klass->deactivate(self);
|
||
|
|
||
|
ifindex = nm_device_get_ip_ifindex(self);
|
||
|
|
||
|
@@ -15497,8 +15508,11 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu
|
||
|
|
||
|
priv->tc_committed = FALSE;
|
||
|
|
||
|
- _routing_rules_sync(self,
|
||
|
- cleanup_type == CLEANUP_TYPE_KEEP ? NM_TERNARY_DEFAULT : NM_TERNARY_FALSE);
|
||
|
+ nm_routing_rules_sync(nm_device_get_applied_connection(self),
|
||
|
+ cleanup_type == CLEANUP_TYPE_KEEP ? NM_TERNARY_DEFAULT : NM_TERNARY_FALSE,
|
||
|
+ klass->get_extra_rules,
|
||
|
+ self,
|
||
|
+ nm_device_get_netns(self));
|
||
|
|
||
|
if (ifindex > 0)
|
||
|
nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self), ifindex, NULL);
|
||
|
@@ -15527,7 +15541,7 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu
|
||
|
/* for other device states (UNAVAILABLE, DISCONNECTED), allow the
|
||
|
* device to overwrite the reset behavior, so that Wi-Fi can set
|
||
|
* a randomized MAC address used during scanning. */
|
||
|
- NM_DEVICE_GET_CLASS(self)->deactivate_reset_hw_addr(self);
|
||
|
+ klass->deactivate_reset_hw_addr(self);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h
|
||
|
index 68387a2149..e58c2088b9 100644
|
||
|
--- a/src/core/devices/nm-device.h
|
||
|
+++ b/src/core/devices/nm-device.h
|
||
|
@@ -821,4 +821,10 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean
|
||
|
|
||
|
void nm_device_clear_dns_lookup_data(NMDevice *self, const char *reason);
|
||
|
|
||
|
+void nm_routing_rules_sync(NMConnection *applied_connection,
|
||
|
+ NMTernary set_mode,
|
||
|
+ GPtrArray *(*get_extra_rules)(NMDevice *self),
|
||
|
+ NMDevice *self,
|
||
|
+ NMNetns *netns);
|
||
|
+
|
||
|
#endif /* __NETWORKMANAGER_DEVICE_H__ */
|
||
|
diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c
|
||
|
index 1607d2013a..0068b52bc3 100644
|
||
|
--- a/src/core/vpn/nm-vpn-connection.c
|
||
|
+++ b/src/core/vpn/nm-vpn-connection.c
|
||
|
@@ -903,7 +903,8 @@ fw_call_cleanup(NMVpnConnection *self)
|
||
|
static void
|
||
|
vpn_cleanup(NMVpnConnection *self, NMDevice *parent_dev)
|
||
|
{
|
||
|
- const char *iface;
|
||
|
+ NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
|
||
|
+ const char *iface;
|
||
|
|
||
|
/* Remove zone from firewall */
|
||
|
iface = nm_vpn_connection_get_ip_iface(self, FALSE);
|
||
|
@@ -915,6 +916,8 @@ vpn_cleanup(NMVpnConnection *self, NMDevice *parent_dev)
|
||
|
fw_call_cleanup(self);
|
||
|
|
||
|
_l3cfg_l3cd_clear_all(self);
|
||
|
+
|
||
|
+ nm_routing_rules_sync(_get_applied_connection(self), NM_TERNARY_FALSE, NULL, NULL, priv->netns);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -2206,6 +2209,8 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict
|
||
|
|
||
|
_l3cfg_l3cd_set(self, L3CD_TYPE_IP_X(IS_IPv4), l3cd);
|
||
|
|
||
|
+ nm_routing_rules_sync(_get_applied_connection(self), NM_TERNARY_TRUE, NULL, NULL, priv->netns);
|
||
|
+
|
||
|
_check_complete(self, TRUE);
|
||
|
}
|
||
|
|
||
|
--
|
||
|
2.45.0
|
||
|
|