diff options
author | Hendrik Donner <hendrik@rennod.org> | 2016-03-02 23:31:35 +0100 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2016-03-08 15:52:33 +0200 |
commit | cefa38a30af75a7eacf8b80ea7c67ec949883ddf (patch) | |
tree | 05947b71d034c2fa6f88b48e05f68bb3a0185a70 | |
parent | abe3ae4c8aeae920ce91713c59c510838625bd58 (diff) | |
download | connman-cefa38a30af75a7eacf8b80ea7c67ec949883ddf.tar.gz |
vpn: Add tap device support
Allow VPN drivers to implement a function for specifying flags for
device creation. This allows VPN plugins to use tap or tun devices
depending on their configuration.
-rw-r--r-- | vpn/plugins/vpn.c | 15 | ||||
-rw-r--r-- | vpn/plugins/vpn.h | 1 |
2 files changed, 11 insertions, 5 deletions
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c index 1b5af6ea..9a423850 100644 --- a/vpn/plugins/vpn.c +++ b/vpn/plugins/vpn.c @@ -56,6 +56,7 @@ struct vpn_data { unsigned int watch; enum vpn_state state; struct connman_task *task; + int tun_flags; }; struct vpn_driver_data { @@ -89,7 +90,7 @@ static int stop_vpn(struct vpn_provider *provider) return 0; memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + ifr.ifr_flags = data->tun_flags | IFF_NO_PI; sprintf(ifr.ifr_name, "%s", data->if_name); fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC); @@ -335,7 +336,7 @@ static DBusMessage *vpn_notify(struct connman_task *task, return NULL; } -static int vpn_create_tun(struct vpn_provider *provider) +static int vpn_create_tun(struct vpn_provider *provider, int flags) { struct vpn_data *data = vpn_provider_get_data(provider); struct ifreq ifr; @@ -355,7 +356,7 @@ static int vpn_create_tun(struct vpn_provider *provider) } memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + ifr.ifr_flags = flags | IFF_NO_PI; for (i = 0; i < 256; i++) { sprintf(ifr.ifr_name, "vpn%d", i); @@ -371,6 +372,7 @@ static int vpn_create_tun(struct vpn_provider *provider) goto exist_err; } + data->tun_flags = flags; data->if_name = (char *)g_strdup(ifr.ifr_name); if (!data->if_name) { connman_error("Failed to allocate memory"); @@ -412,7 +414,7 @@ static int vpn_connect(struct vpn_provider *provider, struct vpn_data *data = vpn_provider_get_data(provider); struct vpn_driver_data *vpn_driver_data; const char *name; - int ret = 0; + int ret = 0, tun_flags = IFF_TUN; enum vpn_state state = VPN_STATE_UNKNOWN; if (data) @@ -460,7 +462,10 @@ static int vpn_connect(struct vpn_provider *provider, } if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) { - ret = vpn_create_tun(provider); + if (vpn_driver_data->vpn_driver->device_flags) { + tun_flags = vpn_driver_data->vpn_driver->device_flags(provider); + } + ret = vpn_create_tun(provider, tun_flags); if (ret < 0) goto exist_err; } diff --git a/vpn/plugins/vpn.h b/vpn/plugins/vpn.h index bf56728d..cb94bdcd 100644 --- a/vpn/plugins/vpn.h +++ b/vpn/plugins/vpn.h @@ -50,6 +50,7 @@ struct vpn_driver { void (*disconnect) (struct vpn_provider *provider); int (*error_code) (struct vpn_provider *provider, int exit_code); int (*save) (struct vpn_provider *provider, GKeyFile *keyfile); + int (*device_flags) (struct vpn_provider *provider); }; int vpn_register(const char *name, struct vpn_driver *driver, |