Non default VPN route patch



Hi all,

I made some changes to the current CVS head, which allow setting up
non-default routes for the VPN. In case your home connection is much
better than through the office, you don't want your default route to go
through the VPN.

This only works for the RedHat back end now, but it should be easy to
adjust for other distributions. You'll need an additional gconf key,
called routes in your VPN set up. It should be a list of strings, each
of them representing a single non default route, e.g. "172.16.0.0/16"
which you want to pass through the VPN. If the list is empty, the
behavior should stay the same.

Regards,
-- 
Tomislav Vujec
Manager, Client Development
Red Hat  Otto-Hahn-Straße 20  85609 München-Dornach
Tel +49 89 205071 212 Fax +49 89 205071 111 Cell. +49 172 623 1214
Index: gnome/applet/applet-dbus-info.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/applet-dbus-info.c,v
retrieving revision 1.3
diff -r1.3 applet-dbus-info.c
670a671,746
> /*
>  * nmi_dbus_get_vpn_connection_routes
>  *
>  * Returns routes for a particular VPN connection.
>  *
>  */
> static DBusMessage *nmi_dbus_get_vpn_connection_routes (NMWirelessApplet *applet, DBusMessage *message)
> {
> 	DBusMessage		*reply = NULL;
> 	gchar			*gconf_key = NULL;
> 	char				*name = NULL;
> 	GConfValue		*routes_value = NULL;
> 	GConfValue		*value = NULL;
> 	DBusError			 error;
> 	char				*escaped_name;
> 	DBusMessageIter 	 iter, array_iter;
> 	GSList			*elt;
> 
> 	g_return_val_if_fail (applet != NULL, NULL);
> 	g_return_val_if_fail (message != NULL, NULL);
> 
> 	dbus_error_init (&error);
> 	if (    !dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)
> 		|| (strlen (name) <= 0))
> 	{
> 		reply = nmwa_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "InvalidArguments",
> 							"NetworkManagerInfo::getVPNConnectionRoutes called with invalid arguments.");
> 		return reply;
> 	}
> 
> 	escaped_name = gconf_escape_key (name, strlen (name));
> 
> 	/* User-visible name of connection */
> 	gconf_key = g_strdup_printf ("%s/%s/name", GCONF_PATH_VPN_CONNECTIONS, escaped_name);
> 	if (!(value = gconf_client_get (applet->gconf_client, gconf_key, NULL)))
> 	{
> 		reply = nmwa_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "BadVPNConnectionData",
> 						"NetworkManagerInfo::getVPNConnectionRoutes could not access the name for connection '%s'", name);
> 		return reply;
> 	}
> 	gconf_value_free (value);
> 	g_free (gconf_key);
> 
> 	/* Grab vpn-daemon specific data */
> 	gconf_key = g_strdup_printf ("%s/%s/routes", GCONF_PATH_VPN_CONNECTIONS, escaped_name);
> 	if (!(routes_value = gconf_client_get (applet->gconf_client, gconf_key, NULL))
> 		|| !(routes_value->type == GCONF_VALUE_LIST)
> 		|| !(gconf_value_get_list_type (routes_value) == GCONF_VALUE_STRING))
> 	{
> 		reply = nmwa_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "BadVPNConnectionData",
> 						"NetworkManagerInfo::getVPNConnectionRoutes could not access the routes for connection '%s'", name);
> 		if (routes_value)
> 			gconf_value_free (routes_value);
> 		return reply;
> 	}
> 	g_free (gconf_key);
> 
> 	reply = dbus_message_new_method_return (message);
> 	dbus_message_iter_init_append (reply, &iter);
> 	dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter);
> 
> 	for (elt = gconf_value_get_list (routes_value); elt; elt = g_slist_next (elt))
> 	{
> 		const char *string = gconf_value_get_string ((GConfValue *)elt->data);
> 		if (string)
> 			dbus_message_iter_append_basic (&array_iter, DBUS_TYPE_STRING, &string);
> 	}
> 
> 	dbus_message_iter_close_container (&iter, &array_iter);
> 
> 	gconf_value_free (routes_value);
> 	g_free (escaped_name);
> 
> 	return (reply);
> }
> 
873a950,951
> 	else if (strcmp ("getVPNConnectionRoutes", method) == 0)
> 		reply = nmi_dbus_get_vpn_connection_routes (applet, message);
Index: src/NetworkManagerSystem.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/NetworkManagerSystem.c,v
retrieving revision 1.17
diff -r1.17 NetworkManagerSystem.c
223c223
< gboolean nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config)
---
> gboolean nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config, char **routes, int num_routes)
245d244
< 	nm_system_delete_default_route ();
247c246,258
< 	nm_system_device_add_default_route_via_device_with_iface (iface);
---
> 	if (num_routes == 0)
> 	{
> 		nm_system_delete_default_route ();
> 		nm_system_device_add_default_route_via_device_with_iface (iface);
> 	}
> 	else
> 	{
> 		int i;
> 		for (i = 0; i < num_routes; i++)
> 		{
> 			nm_system_device_add_route_via_device_with_iface (iface, routes[i]);
> 		}
> 	}
Index: src/NetworkManagerSystem.h
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/NetworkManagerSystem.h,v
retrieving revision 1.6
diff -r1.6 NetworkManagerSystem.h
41a42,43
> void			nm_system_device_add_route_via_device_with_iface (const char *iface, const char *route);
> 
67c69
< gboolean		nm_system_vpn_device_set_from_ip4_config	(NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config);
---
> gboolean		nm_system_vpn_device_set_from_ip4_config	(NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config, char **routes, int num_routes);
Index: src/backends/NetworkManagerRedHat.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/backends/NetworkManagerRedHat.c,v
retrieving revision 1.27
diff -r1.27 NetworkManagerRedHat.c
119a120,138
>  * nm_system_device_add_route_via_device_with_iface
>  *
>  * Add route to the given device
>  *
>  */
> void nm_system_device_add_route_via_device_with_iface (const char *iface, const char *route)
> {
> 	char	*buf;
> 
> 	g_return_if_fail (iface != NULL);
> 
> 	/* Add default gateway */
> 	buf = g_strdup_printf ("/sbin/ip route add %s dev %s", route, iface);
> 	nm_spawn_process (buf);
> 	g_free (buf);
> }
> 
> 
> /*
Index: src/vpn-manager/nm-dbus-vpn.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/vpn-manager/nm-dbus-vpn.c,v
retrieving revision 1.3
diff -r1.3 nm-dbus-vpn.c
235a236,316
> /*
>  * nm_dbus_vpn_get_routes
>  *
>  * Get VPN routes from NMI for a vpn connection
>  *
>  * NOTE: caller MUST free returned value using g_strfreev()
>  *
>  */
> char ** nm_dbus_vpn_get_routes (DBusConnection *connection, NMVPNConnection *vpn, int *num_items)
> {
> 	DBusMessage		*message;
> 	DBusError			 error;
> 	DBusMessage		*reply;
> 	char			    **routes = NULL;
> 	const char		*vpn_name;
> 
> 	g_return_val_if_fail (connection != NULL, NULL);
> 	g_return_val_if_fail (vpn != NULL, NULL);
> 	g_return_val_if_fail (num_items != NULL, NULL);
> 
> 	*num_items = -1;
> 
> 	if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getVPNConnectionRoutes")))
> 	{
> 		nm_warning ("nm_dbus_vpn_get_routes(): Couldn't allocate the dbus message");
> 		return (NULL);
> 	}
> 
> 	vpn_name = nm_vpn_connection_get_name (vpn);
> 	dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_INVALID);
> 
> 	dbus_error_init (&error);
> 	reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
> 	dbus_message_unref (message);
> 	if (dbus_error_is_set (&error))
> 		nm_warning ("nm_dbus_vpn_get_routes(): %s raised %s", error.name, error.message);
> 	else if (!reply)
> 		nm_info ("nm_dbus_vpn_get_routes(): reply was NULL.");
> 	else
> 	{
> 		DBusMessageIter iter, array_iter;
> 		GArray *buffer;
> 
> 		dbus_message_iter_init (reply, &iter);
> 		dbus_message_iter_recurse (&iter, &array_iter);
> 
> 		buffer = g_array_new (TRUE, TRUE, sizeof (gchar *));
> 
> 		if (buffer == NULL)
> 			return NULL;
> 
> 		while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING)
> 		{
> 			const char *value;
> 			char *str;
> 		
> 			dbus_message_iter_get_basic (&array_iter, &value);
> 			str = g_strdup (value);
> 			
> 			if (str == NULL)
> 			{
> 				g_array_free (buffer, TRUE);
> 				return NULL;
> 			}
> 
> 			g_array_append_val (buffer, str);
> 
> 			dbus_message_iter_next (&array_iter);
> 		}
> 		routes = (gchar **)(buffer->data);
> 		*num_items = buffer->len;
> 		g_array_free (buffer, FALSE);
> 	}
> 	
> 	if (reply)
> 		dbus_message_unref (reply);
> 
> 	return (routes);
> }
> 
> 
Index: src/vpn-manager/nm-dbus-vpn.h
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/vpn-manager/nm-dbus-vpn.h,v
retrieving revision 1.3
diff -r1.3 nm-dbus-vpn.h
37a38,39
> char **			nm_dbus_vpn_get_routes					(DBusConnection *connection, NMVPNConnection *vpn, int *num_items);
> 
Index: src/vpn-manager/nm-vpn-manager.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/vpn-manager/nm-vpn-manager.c,v
retrieving revision 1.5
diff -r1.5 nm-vpn-manager.c
436a437,439
> 			int num_routes = -1;
> 			char **routes = nm_dbus_vpn_get_routes (manager->app_data->dbus_connection, con, &num_routes);
> 		
438c441,442
< 												manager->active_device, manager->active_config);
---
> 												manager->active_device, manager->active_config,
> 												routes, num_routes);
440a445
> 			g_strfreev(routes);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]