Re: complex openvpn - can nm just launch?



On Fri, 2010-04-09 at 09:43 +0200, Robert Vogelgesang wrote:
> Dan,
> 
> On Thu, Apr 08, 2010 at 05:15:54PM -0700, Dan Williams wrote:
> > On Tue, 2010-04-06 at 22:01 +0000, Alessandro Bono wrote:
> > > On Tue, 06 Apr 2010 09:25:44 -0700, Dan Williams wrote:
> > > 
> > > > On Tue, 2010-04-06 at 10:05 -0600, Scott Serr wrote:
> > > >> I have an openvpn config file that works fine with openvpn.  (ubuntu
> > > >> lucid beta)  As far as I can tell there is no way to create a like
> > > >> config in the nm openvpn editor.  I can make one somewhat similar and
> > > >> export, but it doesn't look enough like mine to work.
> > > > 
> > > > Which options?
> > > 
> > > Hi Dan
> > > 
> > > this is my (short) list of missing options/features 
> > > 
> > > - support for external dhcp on the server side, normally I configure 
> > > openvpn server to push only data that I can't provide via dhcp server. So 
> > > ip/mask/dns is taken from dhcp and additional route from openvpn
> > > This configuration works perfectly for windows machine, on certain 
> > > customer I have a dedicated openvpn only for me because I can't use 
> > > "normal" openvpn configuration :-(
> > 
> > Yeah, we need support for this internally.  Right now we pretty much
> > assume a tunnel approach, not TAP.  It's not that hard to fix that I
> > guess; but in general the real fix for this would be helped by some of
> > the activation changes that I'd like to do to fix the PPPoE issues that
> > people currently have.
> 
> I'd like to see this feature, too.  Could you please elaborate on what
> has to be done to support this?

1) add an "method" item to NetworkManagerVPN.h:

/* string: IP4 configuration method */
#define NM_VPN_PLUGIN_IP4_CONFIG_METHOD "method"

/* Values for NM_VPN_PLUGIN_IP4_CONFIG_METHOD */
#define NM_VPN_PLUGIN_IP4_CONFIG_METHOD_DHCP "dhcp"
#define NM_VPN_PLUGIN_IP4_CONFIG_METHOD_STATIC "static"

if the plugin doesn't send 'method' in the config dict, or the item is a
zero-length string, 'static' is assumed.

2) In the openvpn plugin, if we're supposed to use DHCP (is tap always
used with DHCP, or are there cases where it's not?) then we add the
NM_VPN_PLUGIN_IP4_CONFIG_METHOD item to the returned IP4 config struct
with the value "dhcp".

3) Then we need to modify nm_vpn_connection_ip4_config_get() and split
it into two functions, one for DHCP and one for static.  Take the stuff
at the bottom of that function (everything below print_vpn_config()) and
put that into a separate function that gets called by both the static
and dhcp processing bits.  So you'll have something like:

nm_vpn_connection_ip4_config_get()
{
   const char *method = "static";

   /* remove the timeout since the plugin replied */
   g_source_remove (priv->ipconfig_timeout);
   priv->ipconfig_timeout = 0;

   val = g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_METHOD);
   if (val && G_VALUE_HOLDS_STRING (val))
       method = g_value_get_string (val);

   if (!method || !strcmp (method, NM_VPN_PLUGIN_IP4_CONFIG_METHOD_STATIC)) {
      if (handle_static_ip4_config (connection, config_hash))
          return;
   } else if (method && !strcmp (method, NM_VPN_PLUGIN_IP4_CONFIG_METHOD_DHCP)) {
      if (handle_dhcp_ip4_config (connection, config_hash))
          return;
   } else
       nm_log_err (LOGD_VPN, "unknown vpn IP4 method '%s', method);

/* same error stuff as at the bottom of the function now */

}

For the DHCP4 bits, we'll want to build up the NMIP4Config object as
much as possible and cache that in priv->ip4_config while DHCP is
completing.  We'll need to add a few things to teh NMVPNConnection
object's private data, like:

	NMDHCPManager * dhcp_manager;
	NMDHCPClient *  dhcp4_client;
	gulong          dhcp4_state_sigid;
	gulong          dhcp4_timeout_sigid;

(see nm-device.c for DHCP stuff).

When the NMVPNConnection is initialized, lets grab a reference to the
DHCP manager in nm_vpn_connection_init():

	priv->dhcp_manager = nm_dhcp_manager_get ();

and then in handle_dhcp_ip4_config() we'll do something like:

static gboolean
handle_dhcp_ip4_config (NMVPNConnection *vpn, GHashTable *config)
{
    NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn);
    NMSettingConnection *s_con;
    NMSettingIP4Config *s_ip4;
    const char *uuid;

    <get as much stuff from the 'config' as possible and stuff that
     into priv->ip4_config, see nm_vpn_connection_ip4_config_get() for
     how to do this>

    s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_CONNECTION));
    s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_IP4_CONFIG));
    priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager,
                                                    <tap interface name from plugin 'config' hash table>,
                                                    nm_setting_connection_get_uuid (s_con),
                                                    s_ip4,
                                                    <dhcp timeout in seconds, probably around 30>,
                                                    NULL);
    if (!priv->dhcp4_client) {
        nm_log_dbg (LOGD_VPN, "failed to start DHCPv4!");
        g_object_unref (priv->ip4_config);
        priv->ip4_config = NULL;
        return FALSE;
    }

    <this is the signal that the DHCP client object emits when the DHCP
     client's state changes>
    priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client,
                                                "state-changed",
                                                G_CALLBACK (dhcp_state_changed),
                                                vpn);
    <start the failure timer so we can fail the VPN connection if DHCP fails>
    priv->dhcp4_timeout_sigid = g_signal_connect (priv->dhcp4_client,
                                                  "timeout",
                                                  G_CALLBACK (dhcp_timeout),
                                                  vpn);
    return TRUE;
}

and of course take a look at nm-device.c's dhcp_state_changed() and
dhcp_timeout() for what we should be doing in response to this stuff.
You should probably create a "dhcp4_cleanup()" function that we can call
from dispose(), connection_state_changed(), and a few other places that
cleans up all the DHCP4 stuff:

static void
dhcp4_cleanup (NMVPNConnection *self)
{
    NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn);

    if (priv->dhcp4_client) {
        if (priv->dhcp4_timeout_sigid) {
            g_signal_handler_disconnect (priv->dhcp4_client, priv->dhcp4_timeout_sigid);
            priv->dhcp4_timeout_sigid = 0;
        }

        if (priv->dhcp4_state_sigid) {
            g_signal_handler_disconnect (priv->dhcp4_client, priv->dhcp4_state_sigid);
            priv->dhcp4_state_sigid = 0;
        }

        g_object_unref (priv->dhcp4_client);
        priv->dhcp4_client = NULL;
    }
}

so when the timeout signal gets fired, you'll do something like this:

static void
dhcp_timeout (NMDHCPClient *client, gpointer user_data)
{
    NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
    NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn); 

    if (!priv->act_request)
        return;

    nm_dhcp_client_stop (client);

    nm_vpn_connection_set_vpn_state (self,
                                     NM_VPN_CONNECTION_STATE_FAILED,
                                     NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID);
}

and when the DHCP client gets a lease, something like what's in
nm-device.c's dhcp_state_changed() function.  INstead of calling the
nm_device_activate_schedule_* functions though, you'll be using
nm_vpn_connection_set_vpn_state() and setting either success or failure
state.

Let me know if you have more questions :)  Happy to help.

Dan

> If it's not too much work, I'd give it a try over the next few
> weekends (I'd like to use this feature mid-May ;-)).
> 
> 	Robert
> 
> > 
> > > - support for multiple remote server 
> > 
> > Yeah; the trick there is going to be pulling out the IP of the current
> > server and using that to update the routing table, since we have to add
> > a host route to the VPN server over the underlying hardware interface.
> > Maybe that already works just fine for multi-server case, not sure.
> > 
> > Dan
> > 
> > > 
> > > > 
> > > > Dan
> > > > 
> > > >> I've tried importing/exporting a tweaking, but the wizard thing just
> > > >> isn't flexible enough.  (the xml-ization aka 'registry-ization' of just
> > > >> standard config files seems to bite me in various aspects of computing)
> > > >> 
> > > >> I'd like to launch openvpn with my config file from nm.  Is there a
> > > >> way? Short of that is there a way to make dbus or whatever think of I
> > > >> have network without launching from nm?
> > > >> 
> > > >> Thanks!
> > > >> -Scott
> > > >> 
> > > >> _______________________________________________ NetworkManager-list
> > > >> mailing list
> > > >> NetworkManager-list gnome org
> > > >> http://mail.gnome.org/mailman/listinfo/networkmanager-list
> > > 
> > > 
> > > 
> > > 
> > > 
> > 
> > 
> > _______________________________________________
> > networkmanager-list mailing list
> > networkmanager-list gnome org
> > http://mail.gnome.org/mailman/listinfo/networkmanager-list




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