[network-manager-openswan/lr/multiple-vpn] service: handle route updates and deletions
- From: Thomas Haller <thaller src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openswan/lr/multiple-vpn] service: handle route updates and deletions
- Date: Tue, 3 Nov 2015 13:26:05 +0000 (UTC)
commit 18c11e8fa1863ccd618596eef2d3542a8e55f3e3
Author: Thomas Haller <thaller redhat com>
Date: Tue Nov 3 14:25:11 2015 +0100
service: handle route updates and deletions
src/nm-openswan-service.c | 71 ++++++++++++++++++++++++++++++++++++++-------
1 files changed, 60 insertions(+), 11 deletions(-)
---
diff --git a/src/nm-openswan-service.c b/src/nm-openswan-service.c
index 67da6a5..5b8ab7b 100644
--- a/src/nm-openswan-service.c
+++ b/src/nm-openswan-service.c
@@ -112,7 +112,7 @@ typedef struct {
ConnectStep connect_step;
NMConnection *connection;
NMDBusOpenswanHelper *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;
@@ -430,8 +438,7 @@ ipsec_stop (NMOpenSwanPlugin *self, GError **error)
const char *argv[5];
guint i = 0;
- 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;
@@ -1161,6 +1168,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 (NMDBusOpenswanHelper *object,
GDBusMethodInvocation *invocation,
@@ -1170,9 +1213,10 @@ handle_callback (NMDBusOpenswanHelper *object,
NMOpenSwanPluginPrivate *priv = NM_OPENSWAN_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.");
@@ -1250,17 +1294,17 @@ handle_callback (NMDBusOpenswanHelper *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));
@@ -1764,6 +1808,9 @@ dispose (GObject *object)
static void
nm_openswan_plugin_init (NMOpenSwanPlugin *plugin)
{
+ NMOpenSwanPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (plugin);
+
+ priv->routes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_variant_unref);
}
static void
@@ -1775,6 +1822,8 @@ finalize (GObject *object)
connect_cleanup (NM_OPENSWAN_PLUGIN (object));
g_clear_object (&priv->connection);
+ g_ptr_array_unref (priv->routes);
+
G_OBJECT_CLASS (nm_openswan_plugin_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]