5 * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <sys/ioctl.h>
34 #include <sys/types.h>
35 #include <linux/if_tun.h>
38 #include <dbus/dbus.h>
40 #include <glib/gprintf.h>
42 #include <connman/log.h>
43 #include <connman/rtnl.h>
44 #include <connman/task.h>
45 #include <connman/inet.h>
47 #include "../vpn-rtnl.h"
48 #include "../vpn-provider.h"
53 struct vpn_provider *provider;
58 struct connman_task *task;
62 struct vpn_driver_data {
65 struct vpn_driver *vpn_driver;
66 struct vpn_provider_driver provider_driver;
69 GHashTable *driver_hash = NULL;
71 static int stop_vpn(struct vpn_provider *provider)
73 struct vpn_data *data = vpn_provider_get_data(provider);
74 struct vpn_driver_data *vpn_driver_data;
82 name = vpn_provider_get_driver_name(provider);
86 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
88 if (vpn_driver_data && vpn_driver_data->vpn_driver &&
89 vpn_driver_data->vpn_driver->flags == VPN_FLAG_NO_TUN)
92 memset(&ifr, 0, sizeof(ifr));
93 ifr.ifr_flags = data->tun_flags | IFF_NO_PI;
94 sprintf(ifr.ifr_name, "%s", data->if_name);
96 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
99 connman_error("Failed to open /dev/net/tun to device %s: %s",
100 data->if_name, strerror(errno));
104 if (ioctl(fd, TUNSETIFF, (void *)&ifr)) {
106 connman_error("Failed to TUNSETIFF for device %s to it: %s",
107 data->if_name, strerror(errno));
112 if (ioctl(fd, TUNSETPERSIST, 0)) {
114 connman_error("Failed to set tun device %s nonpersistent: %s",
115 data->if_name, strerror(errno));
120 DBG("Killed tun device %s", data->if_name);
124 void vpn_died(struct connman_task *task, int exit_code, void *user_data)
126 struct vpn_provider *provider = user_data;
127 struct vpn_data *data = vpn_provider_get_data(provider);
128 int state = VPN_STATE_FAILURE;
129 enum vpn_provider_error ret;
131 DBG("provider %p data %p", provider, data);
139 vpn_provider_set_data(provider, NULL);
141 if (data->watch != 0) {
142 vpn_rtnl_remove_watch(data->watch);
144 vpn_provider_unref(provider);
148 if (state != VPN_STATE_READY && state != VPN_STATE_DISCONNECT) {
150 struct vpn_driver_data *vpn_data = NULL;
152 name = vpn_provider_get_driver_name(provider);
154 vpn_data = g_hash_table_lookup(driver_hash, name);
157 vpn_data->vpn_driver->error_code)
158 ret = vpn_data->vpn_driver->error_code(provider,
161 ret = VPN_PROVIDER_ERROR_UNKNOWN;
163 vpn_provider_indicate_error(provider, ret);
165 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE);
167 vpn_provider_set_index(provider, -1);
170 vpn_provider_unref(data->provider);
171 g_free(data->if_name);
175 connman_task_destroy(task);
178 int vpn_set_ifname(struct vpn_provider *provider, const char *ifname)
180 struct vpn_data *data = vpn_provider_get_data(provider);
183 if (!ifname || !data)
186 index = connman_inet_ifindex(ifname);
191 g_free(data->if_name);
193 data->if_name = (char *)g_strdup(ifname);
194 vpn_provider_set_index(provider, index);
199 static int vpn_set_state(struct vpn_provider *provider,
200 enum vpn_provider_state state)
202 struct vpn_data *data = vpn_provider_get_data(provider);
207 case VPN_PROVIDER_STATE_UNKNOWN:
209 case VPN_PROVIDER_STATE_IDLE:
210 data->state = VPN_STATE_IDLE;
212 case VPN_PROVIDER_STATE_CONNECT:
213 case VPN_PROVIDER_STATE_READY:
214 data->state = VPN_STATE_CONNECT;
216 case VPN_PROVIDER_STATE_DISCONNECT:
217 data->state = VPN_STATE_DISCONNECT;
219 case VPN_PROVIDER_STATE_FAILURE:
220 data->state = VPN_STATE_FAILURE;
227 static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
229 struct vpn_provider *provider = user_data;
230 struct vpn_data *data = vpn_provider_get_data(provider);
232 if ((data->flags & IFF_UP) != (flags & IFF_UP)) {
233 if (flags & IFF_UP) {
234 data->state = VPN_STATE_READY;
235 vpn_provider_set_state(provider,
236 VPN_PROVIDER_STATE_READY);
242 static DBusMessage *vpn_notify(struct connman_task *task,
243 DBusMessage *msg, void *user_data)
245 struct vpn_provider *provider = user_data;
246 struct vpn_data *data;
247 struct vpn_driver_data *vpn_driver_data;
249 int state, index, err;
251 data = vpn_provider_get_data(provider);
253 name = vpn_provider_get_driver_name(provider);
256 DBG("Cannot find VPN driver for provider %p", provider);
257 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
261 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
262 if (!vpn_driver_data) {
263 DBG("Cannot find VPN driver data for name %s", name);
264 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
268 state = vpn_driver_data->vpn_driver->notify(msg, provider);
270 DBG("provider %p driver %s state %d", provider, name, state);
273 case VPN_STATE_CONNECT:
274 case VPN_STATE_READY:
275 if (data->state == VPN_STATE_READY) {
277 * This is the restart case, in which case we must
278 * just set the IP address.
280 * We need to remove first the old address, just
281 * replacing the old address will not work as expected
282 * because the old address will linger in the interface
283 * and not disapper so the clearing is needed here.
285 * Also the state must change, otherwise the routes
286 * will not be set properly.
288 vpn_provider_set_state(provider,
289 VPN_PROVIDER_STATE_CONNECT);
291 vpn_provider_clear_address(provider, AF_INET);
292 vpn_provider_clear_address(provider, AF_INET6);
294 vpn_provider_change_address(provider);
295 vpn_provider_set_state(provider,
296 VPN_PROVIDER_STATE_READY);
300 index = vpn_provider_get_index(provider);
301 vpn_provider_ref(provider);
302 data->watch = vpn_rtnl_add_newlink_watch(index,
303 vpn_newlink, provider);
304 err = connman_inet_ifup(index);
306 if (err == -EALREADY)
308 * So the interface is up already, that is just
309 * great. Unfortunately in this case the
310 * newlink watch might not have been called at
311 * all. We must manually call it here so that
312 * the provider can go to ready state and the
313 * routes are setup properly.
315 vpn_newlink(IFF_UP, 0, provider);
317 DBG("Cannot take interface %d up err %d/%s",
318 index, -err, strerror(-err));
322 case VPN_STATE_UNKNOWN:
324 case VPN_STATE_DISCONNECT:
325 case VPN_STATE_FAILURE:
326 vpn_provider_set_state(provider,
327 VPN_PROVIDER_STATE_DISCONNECT);
330 case VPN_STATE_AUTH_FAILURE:
331 vpn_provider_indicate_error(provider,
332 VPN_PROVIDER_ERROR_AUTH_FAILED);
339 #if defined TIZEN_EXT
340 static void vpn_event(struct vpn_provider *provider, int state)
342 struct vpn_driver_data *vpn_driver_data;
345 name = vpn_provider_get_driver_name(provider);
347 DBG("Cannot find VPN driver for provider %p", provider);
348 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
352 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
353 if (!vpn_driver_data) {
354 DBG("Cannot find VPN driver data for name %s", name);
355 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
359 DBG("provider %p driver %s state %d", provider, name, state);
362 case VPN_STATE_CONNECT:
363 vpn_provider_set_state(provider,
364 VPN_PROVIDER_STATE_CONNECT);
366 case VPN_STATE_READY:
367 vpn_provider_set_state(provider,
368 VPN_PROVIDER_STATE_READY);
371 case VPN_STATE_UNKNOWN:
373 case VPN_STATE_DISCONNECT:
374 case VPN_STATE_FAILURE:
375 vpn_provider_set_state(provider,
376 VPN_PROVIDER_STATE_DISCONNECT);
379 case VPN_STATE_AUTH_FAILURE:
380 vpn_provider_indicate_error(provider,
381 VPN_PROVIDER_ERROR_AUTH_FAILED);
389 static int vpn_create_tun(struct vpn_provider *provider, int flags)
391 struct vpn_data *data = vpn_provider_get_data(provider);
399 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
402 connman_error("Failed to open /dev/net/tun: %s",
408 memset(&ifr, 0, sizeof(ifr));
409 ifr.ifr_flags = flags | IFF_NO_PI;
411 for (i = 0; i < 256; i++) {
412 sprintf(ifr.ifr_name, "vpn%d", i);
414 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
419 connman_error("Failed to find available tun device");
425 data->tun_flags = flags;
426 data->if_name = (char *)g_strdup(ifr.ifr_name);
427 if (!data->if_name) {
428 connman_error("Failed to allocate memory");
434 if (ioctl(fd, TUNSETPERSIST, 1)) {
436 connman_error("Failed to set tun persistent: %s",
445 index = connman_inet_ifindex(data->if_name);
447 connman_error("Failed to get tun ifindex");
452 vpn_provider_set_index(provider, index);
460 static int vpn_connect(struct vpn_provider *provider,
461 vpn_provider_connect_cb_t cb,
462 const char *dbus_sender, void *user_data)
464 struct vpn_data *data = vpn_provider_get_data(provider);
465 struct vpn_driver_data *vpn_driver_data;
467 int ret = 0, tun_flags = IFF_TUN;
468 enum vpn_state state = VPN_STATE_UNKNOWN;
473 DBG("data %p state %d", data, state);
476 case VPN_STATE_UNKNOWN:
477 data = g_try_new0(struct vpn_data, 1);
481 data->provider = vpn_provider_ref(provider);
486 vpn_provider_set_data(provider, data);
489 case VPN_STATE_DISCONNECT:
491 case VPN_STATE_FAILURE:
492 case VPN_STATE_AUTH_FAILURE:
493 data->state = VPN_STATE_IDLE;
496 case VPN_STATE_CONNECT:
499 case VPN_STATE_READY:
503 name = vpn_provider_get_driver_name(provider);
507 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
509 if (!vpn_driver_data || !vpn_driver_data->vpn_driver) {
514 if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) {
515 if (vpn_driver_data->vpn_driver->device_flags) {
516 tun_flags = vpn_driver_data->vpn_driver->device_flags(provider);
518 ret = vpn_create_tun(provider, tun_flags);
523 data->task = connman_task_create(vpn_driver_data->program);
531 if (connman_task_set_notify(data->task, "notify",
532 vpn_notify, provider)) {
535 connman_task_destroy(data->task);
541 #if defined TIZEN_EXT
542 if(vpn_driver_data->vpn_driver->set_event_cb)
543 vpn_driver_data->vpn_driver->set_event_cb(vpn_event, provider);
546 ret = vpn_driver_data->vpn_driver->connect(provider, data->task,
547 data->if_name, cb, dbus_sender,
549 if (ret < 0 && ret != -EINPROGRESS) {
551 connman_task_destroy(data->task);
556 DBG("%s started with dev %s",
557 vpn_driver_data->provider_driver.name, data->if_name);
559 data->state = VPN_STATE_CONNECT;
564 vpn_provider_set_index(provider, -1);
565 vpn_provider_set_data(provider, NULL);
566 vpn_provider_unref(data->provider);
567 g_free(data->if_name);
573 static int vpn_probe(struct vpn_provider *provider)
578 static int vpn_disconnect(struct vpn_provider *provider)
580 struct vpn_data *data = vpn_provider_get_data(provider);
581 struct vpn_driver_data *vpn_driver_data;
584 DBG("disconnect provider %p:", provider);
589 name = vpn_provider_get_driver_name(provider);
593 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
594 if (vpn_driver_data->vpn_driver->disconnect)
595 vpn_driver_data->vpn_driver->disconnect(provider);
597 if (data->watch != 0) {
598 vpn_provider_unref(provider);
599 vpn_rtnl_remove_watch(data->watch);
603 data->state = VPN_STATE_DISCONNECT;
604 connman_task_stop(data->task);
609 static int vpn_remove(struct vpn_provider *provider)
611 struct vpn_data *data;
613 data = vpn_provider_get_data(provider);
617 if (data->watch != 0) {
618 vpn_provider_unref(provider);
619 vpn_rtnl_remove_watch(data->watch);
623 connman_task_stop(data->task);
625 g_usleep(G_USEC_PER_SEC);
630 static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile)
632 struct vpn_driver_data *vpn_driver_data;
635 name = vpn_provider_get_driver_name(provider);
636 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
637 if (vpn_driver_data &&
638 vpn_driver_data->vpn_driver->save)
639 return vpn_driver_data->vpn_driver->save(provider, keyfile);
644 int vpn_register(const char *name, struct vpn_driver *vpn_driver,
647 struct vpn_driver_data *data;
649 data = g_try_new0(struct vpn_driver_data, 1);
654 data->program = program;
656 data->vpn_driver = vpn_driver;
658 data->provider_driver.name = name;
659 data->provider_driver.disconnect = vpn_disconnect;
660 data->provider_driver.connect = vpn_connect;
661 data->provider_driver.probe = vpn_probe;
662 data->provider_driver.remove = vpn_remove;
663 data->provider_driver.save = vpn_save;
664 data->provider_driver.set_state = vpn_set_state;
667 driver_hash = g_hash_table_new_full(g_str_hash,
672 connman_error("driver_hash not initialized for %s", name);
677 g_hash_table_replace(driver_hash, (char *)name, data);
679 vpn_provider_driver_register(&data->provider_driver);
684 void vpn_unregister(const char *name)
686 struct vpn_driver_data *data;
688 data = g_hash_table_lookup(driver_hash, name);
692 vpn_provider_driver_unregister(&data->provider_driver);
694 g_hash_table_remove(driver_hash, name);
696 if (g_hash_table_size(driver_hash) == 0)
697 g_hash_table_destroy(driver_hash);