[network-manager-libreswan/lr/multiple-vpn: 8/9] service: handle route updates and deletions
- From: Lubomir Rintel <lkundrak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-libreswan/lr/multiple-vpn: 8/9] service: handle route updates and deletions
- Date: Wed, 4 Nov 2015 15:32:31 +0000 (UTC)
commit e20ede418eb4ea9d8b8f1333eccc59ed39e07a8f
Author: Thomas Haller <thaller redhat com>
Date: Tue Nov 3 14:25:11 2015 +0100
service: handle route updates and deletions
src/nm-libreswan-service.c | 71 +++++++++++++++++++++++++++++++++++++-------
1 files changed, 60 insertions(+), 11 deletions(-)
---
diff --git a/src/nm-libreswan-service.c b/src/nm-libreswan-service.c
index da4e561..32b3d56 100644
--- a/src/nm-libreswan-service.c
+++ b/src/nm-libreswan-service.c
@@ -112,7 +112,7 @@ typedef struct {
ConnectStep connect_step;
NMConnection *connection;
NMDBusLibreswanHelper *dbus_skeleton;
- GSList *routes;
+ GPtrArray *routes;
GIOChannel *channel;
guint io_id;
@@ -136,6 +136,14 @@ typedef struct {
/****************************************************************/
+guint32
+nm_utils_ip4_prefix_to_netmask (guint32 prefix)
+{
+ return prefix < 32 ? ~htonl(0xFFFFFFFF >> prefix) : 0xFFFFFFFF;
+}
+
+/****************************************************************/
+
typedef struct {
const char *name;
GType type;
@@ -1131,6 +1139,42 @@ fail:
return NULL;
}
+static void
+_take_route (GPtrArray *routes, GVariant *new, gboolean alive)
+{
+ guint32 network, network2, netmask;
+ guint32 plen, plen2;
+ guint i;
+
+ if (!new)
+ return;
+
+ g_variant_get_child (new, 0, "u", &network);
+ g_variant_get_child (new, 1, "u", &plen);
+
+ netmask = nm_utils_ip4_prefix_to_netmask (plen);
+
+ for (i = 0; i < routes->len; i++) {
+ GVariant *r = routes->pdata[i];
+
+ g_variant_get_child (r, 0, "u", &network2);
+ g_variant_get_child (r, 1, "u", &plen2);
+
+ if ( plen2 == plen
+ && ((network ^ network2) & netmask) == 0) {
+ g_ptr_array_remove_index (routes, i);
+ break;
+ }
+ }
+
+ if (alive) {
+ /* On new or update, we always add the new route to the end.
+ * For update, we basically move the route to the end. */
+ g_ptr_array_add (routes, g_variant_ref_sink (new));
+ } else
+ g_variant_unref (new);
+}
+
static gboolean
handle_callback (NMDBusLibreswanHelper *object,
GDBusMethodInvocation *invocation,
@@ -1140,9 +1184,10 @@ handle_callback (NMDBusLibreswanHelper *object,
NMLibreswanPluginPrivate *priv = NM_LIBRESWAN_PLUGIN_GET_PRIVATE (user_data);
GVariantBuilder config;
GVariantBuilder builder;
- GSList *iter;
GVariant *val;
gboolean success = FALSE;
+ guint i;
+ const char *verbs;
g_message ("Configuration from the helper received.");
@@ -1220,17 +1265,17 @@ handle_callback (NMDBusLibreswanHelper *object,
if (val)
g_variant_builder_add (&config, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, val);
+ verbs = lookup_string (env, "PLUTO_VERBS");
+
/* This route */
- /* TODO: We just cumulate the routes on up-client. We probably should add and remove them
- * on route-client and unroute-client verbs. */
- val = route_to_gvariant (env);
- if (val)
- priv->routes = g_slist_append (priv->routes, g_variant_ref_sink (val));
+ _take_route (priv->routes, route_to_gvariant (env),
+ g_strcmp0 (verbs, "unroute-client") != 0
+ && g_strcmp0 (verbs, "unroute-host") != 0);
/* Routes */
g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau"));
- for (iter = priv->routes; iter; iter = g_slist_next (iter))
- g_variant_builder_add_value (&builder, (GVariant *) iter->data);
+ for (i = 0; i < priv->routes->len; i++)
+ g_variant_builder_add_value (&builder, (GVariant *) priv->routes->pdata[i]);
g_variant_builder_add (&config, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_ROUTES,
g_variant_builder_end (&builder));
@@ -1708,8 +1753,7 @@ real_disconnect (NMVpnServicePlugin *plugin, GError **error)
NMLibreswanPluginPrivate *priv = NM_LIBRESWAN_PLUGIN_GET_PRIVATE (plugin);
gboolean ret;
- g_slist_free_full (priv->routes, (GDestroyNotify) g_variant_unref);
- priv->routes = NULL;
+ g_ptr_array_set_size (priv->routes, 0);
if (!priv->connection)
return TRUE;
@@ -1755,6 +1799,9 @@ dispose (GObject *object)
static void
nm_libreswan_plugin_init (NMLibreswanPlugin *plugin)
{
+ NMLibreswanPluginPrivate *priv = NM_LIBRESWAN_PLUGIN_GET_PRIVATE (plugin);
+
+ priv->routes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_variant_unref);
}
static void
@@ -1766,6 +1813,8 @@ finalize (GObject *object)
connect_cleanup (NM_LIBRESWAN_PLUGIN (object));
g_clear_object (&priv->connection);
+ g_ptr_array_unref (priv->routes);
+
G_OBJECT_CLASS (nm_libreswan_plugin_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]