summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/nm-config-data.c2
-rw-r--r--src/core/nm-l3-config-data.c83
-rw-r--r--src/core/nm-l3-config-data.h7
-rw-r--r--src/core/nm-l3cfg.c9
-rw-r--r--src/core/vpn/nm-vpn-connection.c48
5 files changed, 92 insertions, 57 deletions
diff --git a/src/core/nm-config-data.c b/src/core/nm-config-data.c
index d4498edd..5b330f24 100644
--- a/src/core/nm-config-data.c
+++ b/src/core/nm-config-data.c
@@ -849,7 +849,7 @@ nm_config_data_log(const NMConfigData  *self,
                     /* We require that the default values are grouped by their "group".
                      * That is, all default values for a certain "group" are close to
                      * each other in the list. Assert for that. */
-                    for (g2 = g + 1; g2 < groups_full->len; g2++) {
+                    for (g2 = g + 1; g2 < G_N_ELEMENTS(default_values); g2++) {
                         nm_assert(!nm_streq(default_values[g - 1].group, default_values[g2].group));
                     }
                 }
diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c
index a4647116..908c4d65 100644
--- a/src/core/nm-l3-config-data.c
+++ b/src/core/nm-l3-config-data.c
@@ -157,8 +157,8 @@ struct _NML3ConfigData {
     bool has_routes_with_type_local_6_set : 1;
     bool has_routes_with_type_local_4_val : 1;
     bool has_routes_with_type_local_6_val : 1;
-    bool dhcp_enabled_4 : 1;
-    bool dhcp_enabled_6 : 1;
+    bool allow_routes_without_address_4 : 1;
+    bool allow_routes_without_address_6 : 1;
 
     bool ndisc_hop_limit_set : 1;
     bool ndisc_reachable_time_msec_set : 1;
@@ -678,26 +678,28 @@ nm_l3_config_data_new(NMDedupMultiIndex *multi_idx, int ifindex, NMIPConfigSourc
 
     self  = g_slice_new(NML3ConfigData);
     *self = (NML3ConfigData){
-        .ref_count                     = 1,
-        .ifindex                       = ifindex,
-        .multi_idx                     = nm_dedup_multi_index_ref(multi_idx),
-        .mdns                          = NM_SETTING_CONNECTION_MDNS_DEFAULT,
-        .llmnr                         = NM_SETTING_CONNECTION_LLMNR_DEFAULT,
-        .dns_over_tls                  = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT,
-        .flags                         = NM_L3_CONFIG_DAT_FLAGS_NONE,
-        .metered                       = NM_TERNARY_DEFAULT,
-        .proxy_browser_only            = NM_TERNARY_DEFAULT,
-        .proxy_method                  = NM_PROXY_CONFIG_METHOD_UNKNOWN,
-        .route_table_sync_4            = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
-        .route_table_sync_6            = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
-        .never_default_6               = NM_OPTION_BOOL_DEFAULT,
-        .never_default_4               = NM_OPTION_BOOL_DEFAULT,
-        .source                        = source,
-        .ip6_privacy                   = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
-        .mptcp_flags                   = NM_MPTCP_FLAGS_NONE,
-        .ndisc_hop_limit_set           = FALSE,
-        .ndisc_reachable_time_msec_set = FALSE,
-        .ndisc_retrans_timer_msec_set  = FALSE,
+        .ref_count                      = 1,
+        .ifindex                        = ifindex,
+        .multi_idx                      = nm_dedup_multi_index_ref(multi_idx),
+        .mdns                           = NM_SETTING_CONNECTION_MDNS_DEFAULT,
+        .llmnr                          = NM_SETTING_CONNECTION_LLMNR_DEFAULT,
+        .dns_over_tls                   = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT,
+        .flags                          = NM_L3_CONFIG_DAT_FLAGS_NONE,
+        .metered                        = NM_TERNARY_DEFAULT,
+        .proxy_browser_only             = NM_TERNARY_DEFAULT,
+        .proxy_method                   = NM_PROXY_CONFIG_METHOD_UNKNOWN,
+        .route_table_sync_4             = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
+        .route_table_sync_6             = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
+        .never_default_6                = NM_OPTION_BOOL_DEFAULT,
+        .never_default_4                = NM_OPTION_BOOL_DEFAULT,
+        .source                         = source,
+        .ip6_privacy                    = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
+        .mptcp_flags                    = NM_MPTCP_FLAGS_NONE,
+        .ndisc_hop_limit_set            = FALSE,
+        .ndisc_reachable_time_msec_set  = FALSE,
+        .ndisc_retrans_timer_msec_set   = FALSE,
+        .allow_routes_without_address_4 = TRUE,
+        .allow_routes_without_address_6 = TRUE,
     };
 
     _idx_type_init(&self->idx_addresses_4, NMP_OBJECT_TYPE_IP4_ADDRESS);
@@ -1936,15 +1938,30 @@ nm_l3_config_data_set_mptcp_flags(NML3ConfigData *self, NMMptcpFlags mptcp_flags
 }
 
 gboolean
-nm_l3_config_data_get_dhcp_enabled(const NML3ConfigData *self, int addr_family)
+nm_l3_config_data_get_allow_routes_without_address(const NML3ConfigData *self, int addr_family)
 {
     const int IS_IPv4 = NM_IS_IPv4(addr_family);
 
     nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
     if (IS_IPv4) {
-        return self->dhcp_enabled_4;
+        return self->allow_routes_without_address_4;
     } else {
-        return self->dhcp_enabled_6;
+        return self->allow_routes_without_address_6;
+    }
+}
+
+void
+nm_l3_config_data_set_allow_routes_without_address(NML3ConfigData *self,
+                                                   int             addr_family,
+                                                   gboolean        value)
+{
+    const int IS_IPv4 = NM_IS_IPv4(addr_family);
+
+    nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
+    if (IS_IPv4) {
+        self->allow_routes_without_address_4 = value;
+    } else {
+        self->allow_routes_without_address_6 = value;
     }
 }
 
@@ -2758,18 +2775,18 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co
     method = nm_setting_ip_config_get_method(s_ip);
     if (IS_IPv4) {
         if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
-            self->dhcp_enabled_4 = TRUE;
+            self->allow_routes_without_address_4 = FALSE;
         } else {
-            self->dhcp_enabled_4 = FALSE;
+            self->allow_routes_without_address_4 = TRUE;
         }
     } else {
         method = nm_setting_ip_config_get_method(s_ip);
         if (NM_IN_STRSET(method,
                          NM_SETTING_IP6_CONFIG_METHOD_AUTO,
                          NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
-            self->dhcp_enabled_6 = TRUE;
+            self->allow_routes_without_address_6 = FALSE;
         } else {
-            self->dhcp_enabled_6 = FALSE;
+            self->allow_routes_without_address_6 = TRUE;
         }
     }
 
@@ -3456,11 +3473,11 @@ nm_l3_config_data_merge(NML3ConfigData       *self,
         self->dhcp_lease_x[0] = nm_dhcp_lease_ref(self->dhcp_lease_x[0]);
         self->dhcp_lease_x[1] = nm_dhcp_lease_ref(self->dhcp_lease_x[1]);
     }
-    if (src->dhcp_enabled_4)
-        self->dhcp_enabled_4 = TRUE;
+    if (!src->allow_routes_without_address_4)
+        self->allow_routes_without_address_4 = FALSE;
 
-    if (src->dhcp_enabled_6)
-        self->dhcp_enabled_6 = TRUE;
+    if (!src->allow_routes_without_address_6)
+        self->allow_routes_without_address_6 = FALSE;
 }
 
 NML3ConfigData *
diff --git a/src/core/nm-l3-config-data.h b/src/core/nm-l3-config-data.h
index b55b2f41..faf4f0bf 100644
--- a/src/core/nm-l3-config-data.h
+++ b/src/core/nm-l3-config-data.h
@@ -554,7 +554,12 @@ NMSettingIP6ConfigPrivacy nm_l3_config_data_get_ip6_privacy(const NML3ConfigData
 gboolean nm_l3_config_data_set_ip6_privacy(NML3ConfigData           *self,
                                            NMSettingIP6ConfigPrivacy ip6_privacy);
 
-gboolean nm_l3_config_data_get_dhcp_enabled(const NML3ConfigData *self, int addr_family);
+gboolean nm_l3_config_data_get_allow_routes_without_address(const NML3ConfigData *self,
+                                                            int                   addr_family);
+
+void nm_l3_config_data_set_allow_routes_without_address(NML3ConfigData *self,
+                                                        int             addr_family,
+                                                        gboolean        value);
 
 NMProxyConfigMethod nm_l3_config_data_get_proxy_method(const NML3ConfigData *self);
 
diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c
index 12357fba..57baeac2 100644
--- a/src/core/nm-l3cfg.c
+++ b/src/core/nm-l3cfg.c
@@ -1301,7 +1301,6 @@ _commit_collect_routes(NML3Cfg          *self,
     const int                    IS_IPv4 = NM_IS_IPv4(addr_family);
     const NMDedupMultiHeadEntry *head_entry;
     const NMDedupMultiEntry     *entry;
-    gboolean                     is_dhcp_enabled;
 
     nm_assert(routes && !*routes);
     nm_assert(routes_nodev && !*routes_nodev);
@@ -1321,10 +1320,10 @@ _commit_collect_routes(NML3Cfg          *self,
         else {
             nm_assert(NMP_OBJECT_CAST_IP_ROUTE(obj)->ifindex == self->priv.ifindex);
 
-            is_dhcp_enabled =
-                nm_l3_config_data_get_dhcp_enabled(self->priv.p->combined_l3cd_commited,
-                                                   addr_family);
-            if (!any_addrs && is_dhcp_enabled) {
+            if (!any_addrs
+                && !nm_l3_config_data_get_allow_routes_without_address(
+                    self->priv.p->combined_l3cd_commited,
+                    addr_family)) {
                 /* This is a unicast route (or a similar route, which has an
                  * ifindex).
                  *
diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c
index de0c9f71..b5a7fc4c 100644
--- a/src/core/vpn/nm-vpn-connection.c
+++ b/src/core/vpn/nm-vpn-connection.c
@@ -1433,6 +1433,10 @@ _check_complete(NMVpnConnection *self, gboolean success)
     l3cd = nm_l3_config_data_new_from_connection(nm_netns_get_multi_idx(priv->netns),
                                                  nm_vpn_connection_get_ip_ifindex(self, TRUE),
                                                  connection);
+
+    nm_l3_config_data_set_allow_routes_without_address(l3cd, AF_INET, TRUE);
+    nm_l3_config_data_set_allow_routes_without_address(l3cd, AF_INET6, TRUE);
+
     _l3cfg_l3cd_set(self, L3CD_TYPE_STATIC, l3cd);
 
     _l3cfg_l3cd_gw_extern_update(self);
@@ -1988,6 +1992,12 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict
 
     nm_l3_config_data_set_dns_priority(l3cd, AF_INET, NM_DNS_PRIORITY_DEFAULT_VPN);
 
+    _vardict_to_addr(addr_family,
+                     dict,
+                     IS_IPv4 ? NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY
+                             : NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY,
+                     &priv->ip_data_x[IS_IPv4].gw_internal);
+
     if (IS_IPv4) {
         address.a4 = (NMPlatformIP4Address){
             .plen = 24,
@@ -1998,16 +2008,17 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict
         };
     }
 
-    _vardict_to_addr(addr_family,
-                     dict,
-                     IS_IPv4 ? NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY
-                             : NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY,
-                     &priv->ip_data_x[IS_IPv4].gw_internal);
-
-    _vardict_to_addr(addr_family,
-                     dict,
-                     IS_IPv4 ? NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS : NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS,
-                     address.ax.address_ptr);
+    if (_vardict_to_addr(addr_family,
+                         dict,
+                         IS_IPv4 ? NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS
+                                 : NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS,
+                         address.ax.address_ptr)
+        && nm_ip_addr_is_null(addr_family, &address.ax.address_ptr)) {
+        _LOGW("invalid IP%c config received: address is zero",
+              nm_utils_addr_family_to_char(addr_family));
+        _check_complete(self, FALSE);
+        return;
+    }
 
     if (!_vardict_to_addr(addr_family,
                           dict,
@@ -2024,17 +2035,20 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict
                          &u32))
         address.ax.plen = u32;
 
-    if (address.ax.plen > 0 && address.ax.plen <= (IS_IPv4 ? 32 : 128)
-        && !nm_ip_addr_is_null(addr_family, &address.ax.address_ptr)) {
-        address.ax.addr_source = NM_IP_CONFIG_SOURCE_VPN;
-        nm_l3_config_data_add_address(l3cd, addr_family, NULL, &address.ax);
-    } else {
-        _LOGW("invalid IP%c config received: no valid IP address/prefix",
-              nm_utils_addr_family_to_char(addr_family));
+    if (!nm_ip_addr_is_null(addr_family, &address.ax.address_ptr)
+        && (address.ax.plen == 0 || address.ax.plen > (IS_IPv4 ? 32 : 128))) {
+        _LOGW("invalid IP%c config received: invalid prefix %u",
+              nm_utils_addr_family_to_char(addr_family),
+              address.ax.plen);
         _check_complete(self, FALSE);
         return;
     }
 
+    if (!nm_ip_addr_is_null(addr_family, &address.ax.address_ptr)) {
+        address.ax.addr_source = NM_IP_CONFIG_SOURCE_VPN;
+        nm_l3_config_data_add_address(l3cd, addr_family, NULL, &address.ax);
+    }
+
     if (IS_IPv4) {
         if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_DNS, "au", &var_iter)) {
             while (g_variant_iter_next(var_iter, "u", &u32))