summaryrefslogtreecommitdiff
path: root/src/core/vpn/nm-vpn-connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/vpn/nm-vpn-connection.c')
-rw-r--r--src/core/vpn/nm-vpn-connection.c116
1 files changed, 75 insertions, 41 deletions
diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c
index 3dba9ff6c8..de0c9f7104 100644
--- a/src/core/vpn/nm-vpn-connection.c
+++ b/src/core/vpn/nm-vpn-connection.c
@@ -2099,20 +2099,12 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict
NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4))
nm_l3_config_data_add_route(l3cd, addr_family, route, NULL);
}
- } else if (IS_IPv4 ? g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, "aau", &var_iter)
- : g_variant_lookup(dict,
- NM_VPN_PLUGIN_IP6_CONFIG_ROUTES,
- "a(ayuayu)",
- &var_iter)) {
- _nm_unused nm_auto_free_variant_iter GVariantIter *var_iter_ref_owner = var_iter;
- NMPlatformIPXRoute route = {};
- guint32 plen;
- GVariant *next_hop;
- GVariant *dest;
- guint32 prefix;
- guint32 metric;
+ } else if (IS_IPv4) {
+ if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, "aau", &var_iter)) {
+ _nm_unused nm_auto_free_variant_iter GVariantIter *var_iter_ref_owner = var_iter;
+ NMPlatformIPXRoute route = {};
+ guint32 plen;
- if (IS_IPv4) {
while (g_variant_iter_next(var_iter, "@au", &v)) {
_nm_unused gs_unref_variant GVariant *v_ref_owner = v;
@@ -2151,42 +2143,84 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict
break;
}
}
- } else {
- while (
- g_variant_iter_next(var_iter, "(@ayu@ayu)", &dest, &prefix, &next_hop, &metric)) {
- _nm_unused gs_unref_variant GVariant *next_hop_ref_owner = next_hop;
- _nm_unused gs_unref_variant GVariant *dest_ref_owner = dest;
+ }
+ } else {
+ _nm_unused nm_auto_free_variant_iter GVariantIter *var_iter_ref_owner = NULL;
+ NMPlatformIPXRoute route = {};
+ guint32 prefix;
+ guint32 metric;
+ NMOptionBool new_signature = NM_OPTION_BOOL_DEFAULT;
+
+ /* IPv6 and no "preserve-routes" */
+
+ if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, "a(ayuayu)", &var_iter))
+ new_signature = FALSE;
+ else if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, "a(ayuayuay)", &var_iter))
+ new_signature = TRUE;
+ else
+ var_iter = NULL;
+
+ var_iter_ref_owner = var_iter;
+
+ while (TRUE) {
+ gs_unref_variant GVariant *next_hop = NULL;
+ gs_unref_variant GVariant *dest = NULL;
+ gs_unref_variant GVariant *pref_src = NULL;
+
+ if (new_signature == NM_OPTION_BOOL_DEFAULT) {
+ break;
+ } else if (new_signature) {
+ if (!g_variant_iter_next(var_iter,
+ "(@ayu@ayu@ay)",
+ &dest,
+ &prefix,
+ &next_hop,
+ &metric,
+ &pref_src))
+ break;
+ } else {
+ if (!g_variant_iter_next(var_iter,
+ "(@ayu@ayu)",
+ &dest,
+ &prefix,
+ &next_hop,
+ &metric))
+ break;
+ }
- if (prefix > 128)
- continue;
+ if (prefix > 128)
+ continue;
- route.r6 = (NMPlatformIP6Route){
- .plen = prefix,
- .table_any = TRUE,
- .metric_any = TRUE,
- .rt_source = NM_IP_CONFIG_SOURCE_VPN,
- };
+ route.r6 = (NMPlatformIP6Route){
+ .plen = prefix,
+ .table_any = TRUE,
+ .metric_any = TRUE,
+ .rt_source = NM_IP_CONFIG_SOURCE_VPN,
+ };
- if (!nm_ip_addr_set_from_variant(AF_INET6, &route.r6.network, dest, NULL))
- continue;
+ if (!nm_ip_addr_set_from_variant(AF_INET6, &route.r6.network, dest, NULL))
+ continue;
- nm_ip_addr_set_from_variant(AF_INET6, &route.r6.gateway, next_hop, NULL);
+ if (pref_src
+ && !nm_ip_addr_set_from_variant(AF_INET6, &route.r6.pref_src, pref_src, NULL))
+ continue;
- nm_ip6_addr_clear_host_address(&route.r6.network, &route.r6.network, route.r6.plen);
+ nm_ip_addr_set_from_variant(AF_INET6, &route.r6.gateway, next_hop, NULL);
- if (!IN6_IS_ADDR_UNSPECIFIED(&priv->ip_data_6.gw_external.addr6)
- && IN6_ARE_ADDR_EQUAL(&route.r6.network, &priv->ip_data_6.gw_external.addr6)
- && route.r6.plen == 128) {
- /* Ignore host routes to the VPN gateway since NM adds one itself.
- * Since NM knows more about the routing situation than the VPN
- * server, we want to use the NM created route instead of whatever
- * the server provides.
- */
- continue;
- }
+ nm_ip6_addr_clear_host_address(&route.r6.network, &route.r6.network, route.r6.plen);
- nm_l3_config_data_add_route_6(l3cd, &route.r6);
+ if (!IN6_IS_ADDR_UNSPECIFIED(&priv->ip_data_6.gw_external.addr6)
+ && IN6_ARE_ADDR_EQUAL(&route.r6.network, &priv->ip_data_6.gw_external.addr6)
+ && route.r6.plen == 128) {
+ /* Ignore host routes to the VPN gateway since NM adds one itself.
+ * Since NM knows more about the routing situation than the VPN
+ * server, we want to use the NM created route instead of whatever
+ * the server provides.
+ */
+ continue;
}
+
+ nm_l3_config_data_add_route_6(l3cd, &route.r6);
}
}