summary refs log tree commit diff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/devices/nm-device.c66
-rw-r--r--src/core/devices/nm-device.h6
-rw-r--r--src/core/dhcp/nm-dhcp-client.c19
-rw-r--r--src/core/dhcp/nm-dhcp-client.h2
-rw-r--r--src/core/dhcp/nm-dhcp-nettools.c5
-rw-r--r--src/core/platform/tests/test-link.c11
-rw-r--r--src/core/vpn/nm-vpn-connection.c11
7 files changed, 82 insertions, 38 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 516e13df..6c5a9b5a 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -1462,7 +1462,7 @@ _prop_get_connection_mptcp_flags(NMDevice *self)
 
     if (!NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_DISABLED)) {
         if (!NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_ALSO_WITHOUT_SYSCTL)) {
-            guint32 v;
+            gint32 v;
 
             /* If enabled, but without "also-without-sysctl", then MPTCP is still
              * disabled, if the sysctl says so...
@@ -10377,31 +10377,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;
 
@@ -10440,10 +10443,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(
@@ -10458,7 +10461,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;
@@ -10518,8 +10521,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;
@@ -10544,7 +10547,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_managed_type_is_external_or_assume(self)) {
         if (!nm_device_bring_up_full(self, FALSE, TRUE, &no_firmware)) {
@@ -10556,7 +10563,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_managed_type_is_external_or_assume(self)) {
         NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
@@ -11383,7 +11389,7 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family)
     /* Take the NML3ConfigData from the previous lease (if any) that was passed to the NMDhcpClient.
      * This may be the old lease only used during the duration of a reapply until we get the
      * new lease. */
-    previous_lease = nm_dhcp_client_get_lease(priv->ipdhcp_data_x[IS_IPv4].client);
+    previous_lease = nm_dhcp_client_get_lease(priv->ipdhcp_data_x[IS_IPv4].client, TRUE);
 
     if (!priv->ipdhcp_data_x[IS_IPv4].config) {
         priv->ipdhcp_data_x[IS_IPv4].config = nm_dhcp_config_new(addr_family, previous_lease);
@@ -13931,7 +13937,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);
 
@@ -16493,6 +16503,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));
@@ -16517,8 +16528,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);
 
@@ -16540,8 +16551,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);
@@ -16570,7 +16584,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 b84bbb65..9b051ab4 100644
--- a/src/core/devices/nm-device.h
+++ b/src/core/devices/nm-device.h
@@ -848,4 +848,10 @@ void nm_device_clear_dns_lookup_data(NMDevice *self, const char *reason);
 
 gboolean nm_device_get_allow_autoconnect_on_external(NMDevice *self);
 
+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/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c
index 4ebc1754..cd6e67e2 100644
--- a/src/core/dhcp/nm-dhcp-client.c
+++ b/src/core/dhcp/nm-dhcp-client.c
@@ -275,10 +275,25 @@ nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys)
     return options;
 }
 
+/**
+ * nm_dhcp_client_get_lease():
+ * @self: the client
+ * @ignore_acd_pending: FALSE means to only return the lease that already
+ * passed ACD, thus it is in use by us. TRUE means to return a new lease
+ * that might still be pending of Address Collision Detection (ACD) check,
+ * if there is one, or return the current lease that passed ACD if not.
+ *
+ * Returns the current lease that passed ACD or a pending lease still under
+ * ACD check.
+ *
+ */
 const NML3ConfigData *
-nm_dhcp_client_get_lease(NMDhcpClient *self)
+nm_dhcp_client_get_lease(NMDhcpClient *self, gboolean ignore_acd_pending)
 {
-    return NM_DHCP_CLIENT_GET_PRIVATE(self)->l3cd_curr;
+    if (ignore_acd_pending)
+        return NM_DHCP_CLIENT_GET_PRIVATE(self)->l3cd_curr;
+    else
+        return NM_DHCP_CLIENT_GET_PRIVATE(self)->l3cd_next;
 }
 
 /*****************************************************************************/
diff --git a/src/core/dhcp/nm-dhcp-client.h b/src/core/dhcp/nm-dhcp-client.h
index 2b262f76..8c685faf 100644
--- a/src/core/dhcp/nm-dhcp-client.h
+++ b/src/core/dhcp/nm-dhcp-client.h
@@ -242,7 +242,7 @@ const NMDhcpClientConfig *nm_dhcp_client_get_config(NMDhcpClient *self);
 
 pid_t nm_dhcp_client_get_pid(NMDhcpClient *self);
 
-const NML3ConfigData *nm_dhcp_client_get_lease(NMDhcpClient *self);
+const NML3ConfigData *nm_dhcp_client_get_lease(NMDhcpClient *self, gboolean ignore_acd_pending);
 
 void nm_dhcp_client_stop(NMDhcpClient *self, gboolean release);
 
diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c
index b81ce77a..f4f244c6 100644
--- a/src/core/dhcp/nm-dhcp-nettools.c
+++ b/src/core/dhcp/nm-dhcp-nettools.c
@@ -1484,7 +1484,10 @@ stop(NMDhcpClient *client, gboolean release)
     NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
 
     if (release) {
-        if (n_dhcp4_client_probe_release(priv->probe))
+        /* After we receive a lease from server, it doesn't matter if we completed ACD,
+         * we should send the release message. */
+        if (nm_dhcp_client_get_lease(client, FALSE)
+            && n_dhcp4_client_probe_release(priv->probe) < 0)
             _LOGT("dhcp-client4: failed to send request with RELEASE message");
     }
 
diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c
index 9f63b896..bcb135d3 100644
--- a/src/core/platform/tests/test-link.c
+++ b/src/core/platform/tests/test-link.c
@@ -2264,7 +2264,7 @@ test_software_detect_add(const char *testpath, NMLinkType link_type, int test_mo
 }
 
 /*****************************************************************************/
-/*
+
 static void
 _assert_xgress_qos_mappings_impl(int ifindex, gboolean is_ingress_map, int n_entries, int n, ...)
 {
@@ -2344,8 +2344,7 @@ _assert_vlan_flags(int ifindex, _NMVlanFlags flags)
     g_assert(plnk);
     g_assert_cmpint(plnk->flags, ==, flags);
 }
-*/
-/*
+
 static void
 test_vlan_set_xgress(void)
 {
@@ -2361,7 +2360,6 @@ test_vlan_set_xgress(void)
     ifindex =
         nmtstp_assert_wait_for_link(NM_PLATFORM_GET, DEVICE_NAME, NM_LINK_TYPE_VLAN, 100)->ifindex;
 
-
     g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 4, 5));
     _assert_ingress_qos_mappings(ifindex, 1, 4, 5);
 
@@ -2392,7 +2390,6 @@ test_vlan_set_xgress(void)
     g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 9, 4));
     _assert_ingress_qos_mappings(ifindex, 3, 0, 5, 3, 8, 4, 5);
 
-
     g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 7, 3));
     _assert_egress_qos_mappings(ifindex, 1, 7, 3);
 
@@ -2694,7 +2691,7 @@ test_vlan_set_xgress(void)
     nmtstp_link_delete(NULL, -1, ifindex, DEVICE_NAME, TRUE);
     nmtstp_link_delete(NULL, -1, ifindex_parent, PARENT_NAME, TRUE);
 }
-*/
+
 /*****************************************************************************/
 
 static void
@@ -4108,7 +4105,7 @@ _nmtstp_setup_tests(void)
         test_software_detect_add("/link/software/detect/wireguard/1", NM_LINK_TYPE_WIREGUARD, 1);
         test_software_detect_add("/link/software/detect/wireguard/2", NM_LINK_TYPE_WIREGUARD, 2);
 
-        //       g_test_add_func("/link/software/vlan/set-xgress", test_vlan_set_xgress);
+        g_test_add_func("/link/software/vlan/set-xgress", test_vlan_set_xgress);
 
         g_test_add_func("/link/set-properties", test_link_set_properties);
 
diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c
index b5a7fc4c..c14682b8 100644
--- a/src/core/vpn/nm-vpn-connection.c
+++ b/src/core/vpn/nm-vpn-connection.c
@@ -905,7 +905,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);
@@ -917,6 +918,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
@@ -1242,6 +1245,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd,
             .gateway    = parent_gw.addr4,
             .rt_source  = NM_IP_CONFIG_SOURCE_VPN,
             .metric_any = TRUE,
+            .table_any  = TRUE,
         };
     } else {
         route.r6 = (NMPlatformIP6Route){
@@ -1251,6 +1255,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd,
             .gateway    = parent_gw.addr6,
             .rt_source  = NM_IP_CONFIG_SOURCE_VPN,
             .metric_any = TRUE,
+            .table_any  = TRUE,
         };
     }
     nm_l3_config_data_add_route(l3cd, addr_family, NULL, &route.rx);
@@ -1267,6 +1272,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd,
                 .plen       = 32,
                 .rt_source  = NM_IP_CONFIG_SOURCE_VPN,
                 .metric_any = TRUE,
+                .table_any  = TRUE,
             };
         } else {
             route.r6 = (NMPlatformIP6Route){
@@ -1274,6 +1280,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd,
                 .plen       = 128,
                 .rt_source  = NM_IP_CONFIG_SOURCE_VPN,
                 .metric_any = TRUE,
+                .table_any  = TRUE,
             };
         }
         nm_l3_config_data_add_route(l3cd, addr_family, NULL, &route.rx);
@@ -2274,6 +2281,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);
 }