summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Donner <hendrik@rennod.org>2016-03-02 23:31:35 +0100
committerPatrik Flykt <patrik.flykt@linux.intel.com>2016-03-08 15:52:33 +0200
commitcefa38a30af75a7eacf8b80ea7c67ec949883ddf (patch)
tree05947b71d034c2fa6f88b48e05f68bb3a0185a70
parentabe3ae4c8aeae920ce91713c59c510838625bd58 (diff)
downloadconnman-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.c15
-rw-r--r--vpn/plugins/vpn.h1
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,