[PATCH v2 29/42] vpn-provider: Allow to add complete routes and to remove routes
Jussi Laakkonen <[email protected]> Wed, 13 Aug 2025 18:02:01 +0300
| Newsgroups | dev.linux.lists.connman |
|---|---|
| Message-ID | <[email protected]> |
Adding functionality to add complete routes when all parameters are
known, like with WireGuard. Using the route_env_parse() cb in such case
is too complex and with daemonless VPNs the parameters can be added
once. Move the route lookup into its own function and follow coding
guidelines on memory handling.
Also allow to remove all or a single route from the hash table. In
WireGuard the endpoint may change and this is required for removing the
obsolete routes.
---
vpn/vpn-provider.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++
vpn/vpn-provider.h | 7 ++++++
2 files changed, 61 insertions(+)
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index 0462978b..3942c937 100644
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -3253,6 +3253,60 @@ int vpn_provider_append_route(struct vpn_provider *provider,
return 0;
}
+int vpn_provider_append_route_complete(struct vpn_provider *provider,
+ unsigned long idx, int family,
+ const char *network, const char *netmask,
+ const char *gateway)
+{
+ struct vpn_route *route;
+
+ DBG("provider %p idx %lu family %d network %s netmask %s gateway %s",
+ provider, idx, family, network,
+ netmask, gateway);
+
+ if (!netmask || !gateway || !network)
+ return -EINVAL;
+
+ if (g_hash_table_lookup(provider->routes, GINT_TO_POINTER(idx)))
+ return -EALREADY;
+
+ route = g_new0(struct vpn_route, 1);
+ route->family = family;
+ route->network = g_strdup(network);
+ route->netmask = g_strdup(netmask);
+ route->gateway = g_strdup(gateway);
+
+ g_hash_table_replace(provider->routes, GINT_TO_POINTER(idx), route);
+ provider_schedule_changed(provider);
+
+ return 0;
+}
+
+void vpn_provider_delete_all_routes(struct vpn_provider *provider)
+{
+ DBG("provider %p", provider);
+;
+ if (!__vpn_provider_check_routes(provider))
+ return;
+
+ g_hash_table_remove_all(provider->routes);
+ provider_schedule_changed(provider);
+}
+
+int vpn_provider_delete_route(struct vpn_provider *provider,
+ unsigned long idx)
+{
+ if (!__vpn_provider_check_routes(provider))
+ return -ENOENT;
+
+ if (!g_hash_table_remove(provider->routes, GINT_TO_POINTER(idx)))
+ return -EINVAL;
+
+ provider_schedule_changed(provider);
+
+ return 0;
+}
+
const char *vpn_provider_get_driver_name(struct vpn_provider *provider)
{
if (!provider->driver)
diff --git a/vpn/vpn-provider.h b/vpn/vpn-provider.h
index 8a8b6bfd..c7487525 100644
--- a/vpn/vpn-provider.h
+++ b/vpn/vpn-provider.h
@@ -124,6 +124,13 @@ int vpn_provider_set_nameservers(struct vpn_provider *provider,
const char *nameservers);
int vpn_provider_append_route(struct vpn_provider *provider,
const char *key, const char *value);
+int vpn_provider_append_route_complete(struct vpn_provider *provider,
+ unsigned long idx, int family,
+ const char *address, const char *netmask,
+ const char *gateway);
+void vpn_provider_delete_all_routes(struct vpn_provider *provider);
+int vpn_provider_delete_route(struct vpn_provider *provider,
+ unsigned long index);
const char *vpn_provider_get_driver_name(struct vpn_provider *provider);
const char *vpn_provider_get_save_group(struct vpn_provider *provider);
--
2.39.5