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
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <linux/if_tun.h>
37 #include <dbus/dbus.h>
39 #include <glib/gprintf.h>
41 #include <connman/log.h>
42 #include <connman/rtnl.h>
43 #include <connman/task.h>
44 #include <connman/inet.h>
46 #include "../vpn-rtnl.h"
47 #include "../vpn-provider.h"
52 struct vpn_provider *provider;
57 struct connman_task *task;
61 struct vpn_driver_data {
64 struct vpn_driver *vpn_driver;
65 struct vpn_provider_driver provider_driver;
68 GHashTable *driver_hash = NULL;
70 static int stop_vpn(struct vpn_provider *provider)
72 struct vpn_data *data = vpn_provider_get_data(provider);
73 struct vpn_driver_data *vpn_driver_data;
81 name = vpn_provider_get_driver_name(provider);
85 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
87 if (vpn_driver_data && vpn_driver_data->vpn_driver &&
88 vpn_driver_data->vpn_driver->flags == VPN_FLAG_NO_TUN)
91 memset(&ifr, 0, sizeof(ifr));
92 ifr.ifr_flags = data->tun_flags | IFF_NO_PI;
93 sprintf(ifr.ifr_name, "%s", data->if_name);
95 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
98 connman_error("Failed to open /dev/net/tun to device %s: %s",
99 data->if_name, strerror(errno));
103 if (ioctl(fd, TUNSETIFF, (void *)&ifr)) {
105 connman_error("Failed to TUNSETIFF for device %s to it: %s",
106 data->if_name, strerror(errno));
111 if (ioctl(fd, TUNSETPERSIST, 0)) {
113 connman_error("Failed to set tun device %s nonpersistent: %s",
114 data->if_name, strerror(errno));
119 DBG("Killed tun device %s", data->if_name);
123 void vpn_died(struct connman_task *task, int exit_code, void *user_data)
125 struct vpn_provider *provider = user_data;
126 struct vpn_data *data = vpn_provider_get_data(provider);
127 int state = VPN_STATE_FAILURE;
128 enum vpn_provider_error ret;
130 DBG("provider %p data %p", provider, data);
135 /* The task may die after we have already started the new one */
136 if (data->task != task)
142 vpn_provider_set_data(provider, NULL);
144 if (data->watch != 0) {
145 vpn_rtnl_remove_watch(data->watch);
147 vpn_provider_unref(provider);
151 if (state != VPN_STATE_READY && state != VPN_STATE_DISCONNECT) {
153 struct vpn_driver_data *vpn_data = NULL;
155 name = vpn_provider_get_driver_name(provider);
157 vpn_data = g_hash_table_lookup(driver_hash, name);
160 vpn_data->vpn_driver->error_code)
161 ret = vpn_data->vpn_driver->error_code(provider,
164 ret = VPN_PROVIDER_ERROR_UNKNOWN;
166 vpn_provider_indicate_error(provider, ret);
168 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE);
170 vpn_provider_set_index(provider, -1);
173 vpn_provider_unref(data->provider);
174 g_free(data->if_name);
179 connman_task_destroy(task);
182 int vpn_set_ifname(struct vpn_provider *provider, const char *ifname)
184 struct vpn_data *data = vpn_provider_get_data(provider);
187 if (!ifname || !data)
190 index = connman_inet_ifindex(ifname);
195 g_free(data->if_name);
197 data->if_name = (char *)g_strdup(ifname);
198 vpn_provider_set_index(provider, index);
203 static int vpn_set_state(struct vpn_provider *provider,
204 enum vpn_provider_state state)
206 struct vpn_data *data = vpn_provider_get_data(provider);
211 case VPN_PROVIDER_STATE_UNKNOWN:
213 case VPN_PROVIDER_STATE_IDLE:
214 data->state = VPN_STATE_IDLE;
216 case VPN_PROVIDER_STATE_CONNECT:
217 case VPN_PROVIDER_STATE_READY:
218 data->state = VPN_STATE_CONNECT;
220 case VPN_PROVIDER_STATE_DISCONNECT:
221 data->state = VPN_STATE_DISCONNECT;
223 case VPN_PROVIDER_STATE_FAILURE:
224 data->state = VPN_STATE_FAILURE;
231 static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
233 struct vpn_provider *provider = user_data;
234 struct vpn_data *data = vpn_provider_get_data(provider);
236 if ((data->flags & IFF_UP) != (flags & IFF_UP)) {
237 if (flags & IFF_UP) {
238 data->state = VPN_STATE_READY;
239 vpn_provider_set_state(provider,
240 VPN_PROVIDER_STATE_READY);
246 static DBusMessage *vpn_notify(struct connman_task *task,
247 DBusMessage *msg, void *user_data)
249 struct vpn_provider *provider = user_data;
250 struct vpn_data *data;
251 struct vpn_driver_data *vpn_driver_data;
253 int state, index, err;
255 data = vpn_provider_get_data(provider);
257 name = vpn_provider_get_driver_name(provider);
260 DBG("Cannot find VPN driver for provider %p", provider);
261 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
265 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
266 if (!vpn_driver_data) {
267 DBG("Cannot find VPN driver data for name %s", name);
268 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
272 state = vpn_driver_data->vpn_driver->notify(msg, provider);
274 DBG("provider %p driver %s state %d", provider, name, state);
277 case VPN_STATE_CONNECT:
278 case VPN_STATE_READY:
279 if (data->state == VPN_STATE_READY) {
281 * This is the restart case, in which case we must
282 * just set the IP address.
284 * We need to remove first the old address, just
285 * replacing the old address will not work as expected
286 * because the old address will linger in the interface
287 * and not disapper so the clearing is needed here.
289 * Also the state must change, otherwise the routes
290 * will not be set properly.
292 vpn_provider_set_state(provider,
293 VPN_PROVIDER_STATE_CONNECT);
295 vpn_provider_clear_address(provider, AF_INET);
296 vpn_provider_clear_address(provider, AF_INET6);
298 vpn_provider_change_address(provider);
299 vpn_provider_set_state(provider,
300 VPN_PROVIDER_STATE_READY);
304 index = vpn_provider_get_index(provider);
305 vpn_provider_ref(provider);
306 data->watch = vpn_rtnl_add_newlink_watch(index,
307 vpn_newlink, provider);
308 err = connman_inet_ifup(index);
310 if (err == -EALREADY) {
312 * So the interface is up already, that is just
313 * great. Unfortunately in this case the
314 * newlink watch might not have been called at
315 * all. We must manually call it here so that
316 * the provider can go to ready state and the
317 * routes are setup properly. Also reset flags
318 * so vpn_newlink() can handle the change.
321 vpn_newlink(IFF_UP, 0, provider);
323 DBG("Cannot take interface %d up err %d/%s",
324 index, -err, strerror(-err));
329 case VPN_STATE_UNKNOWN:
331 case VPN_STATE_DISCONNECT:
332 case VPN_STATE_FAILURE:
333 vpn_provider_set_state(provider,
334 VPN_PROVIDER_STATE_DISCONNECT);
337 case VPN_STATE_AUTH_FAILURE:
338 vpn_provider_indicate_error(provider,
339 VPN_PROVIDER_ERROR_AUTH_FAILED);
346 #if defined TIZEN_EXT
347 static void vpn_event(struct vpn_provider *provider, int state)
349 struct vpn_driver_data *vpn_driver_data;
352 name = vpn_provider_get_driver_name(provider);
354 DBG("Cannot find VPN driver for provider %p", provider);
355 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
359 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
360 if (!vpn_driver_data) {
361 DBG("Cannot find VPN driver data for name %s", name);
362 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
366 DBG("provider %p driver %s state %d", provider, name, state);
369 case VPN_STATE_CONNECT:
370 vpn_provider_set_state(provider,
371 VPN_PROVIDER_STATE_CONNECT);
373 case VPN_STATE_READY:
374 vpn_provider_set_state(provider,
375 VPN_PROVIDER_STATE_READY);
378 case VPN_STATE_UNKNOWN:
380 case VPN_STATE_DISCONNECT:
381 case VPN_STATE_FAILURE:
382 vpn_provider_set_state(provider,
383 VPN_PROVIDER_STATE_DISCONNECT);
386 case VPN_STATE_AUTH_FAILURE:
387 vpn_provider_indicate_error(provider,
388 VPN_PROVIDER_ERROR_AUTH_FAILED);
396 static int vpn_create_tun(struct vpn_provider *provider, int flags)
398 struct vpn_data *data = vpn_provider_get_data(provider);
406 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
409 connman_error("Failed to open /dev/net/tun: %s",
415 memset(&ifr, 0, sizeof(ifr));
416 ifr.ifr_flags = flags | IFF_NO_PI;
418 for (i = 0; i < 256; i++) {
419 sprintf(ifr.ifr_name, "vpn%d", i);
421 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
426 connman_error("Failed to find available tun device");
432 data->tun_flags = flags;
433 g_free(data->if_name);
434 data->if_name = (char *)g_strdup(ifr.ifr_name);
435 if (!data->if_name) {
436 connman_error("Failed to allocate memory");
442 if (ioctl(fd, TUNSETPERSIST, 1)) {
444 connman_error("Failed to set tun persistent: %s",
453 index = connman_inet_ifindex(data->if_name);
455 connman_error("Failed to get tun ifindex");
460 vpn_provider_set_index(provider, index);
468 static int vpn_connect(struct vpn_provider *provider,
469 vpn_provider_connect_cb_t cb,
470 const char *dbus_sender, void *user_data)
472 struct vpn_data *data = vpn_provider_get_data(provider);
473 struct vpn_driver_data *vpn_driver_data;
475 int ret = 0, tun_flags = IFF_TUN;
476 enum vpn_state state = VPN_STATE_UNKNOWN;
481 DBG("data %p state %d", data, state);
484 case VPN_STATE_UNKNOWN:
485 data = g_try_new0(struct vpn_data, 1);
489 data->provider = vpn_provider_ref(provider);
494 vpn_provider_set_data(provider, data);
497 case VPN_STATE_DISCONNECT:
499 case VPN_STATE_FAILURE:
500 case VPN_STATE_AUTH_FAILURE:
501 data->state = VPN_STATE_IDLE;
504 case VPN_STATE_CONNECT:
507 case VPN_STATE_READY:
511 name = vpn_provider_get_driver_name(provider);
515 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
517 if (!vpn_driver_data || !vpn_driver_data->vpn_driver) {
522 if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) {
523 if (vpn_driver_data->vpn_driver->device_flags) {
524 tun_flags = vpn_driver_data->vpn_driver->device_flags(provider);
526 ret = vpn_create_tun(provider, tun_flags);
531 data->task = connman_task_create(vpn_driver_data->program);
539 if (connman_task_set_notify(data->task, "notify",
540 vpn_notify, provider)) {
543 connman_task_destroy(data->task);
549 #if defined TIZEN_EXT
550 if(vpn_driver_data->vpn_driver->set_event_cb)
551 vpn_driver_data->vpn_driver->set_event_cb(vpn_event, provider);
554 ret = vpn_driver_data->vpn_driver->connect(provider, data->task,
555 data->if_name, cb, dbus_sender,
557 if (ret < 0 && ret != -EINPROGRESS) {
559 connman_task_destroy(data->task);
564 DBG("%s started with dev %s",
565 vpn_driver_data->provider_driver.name, data->if_name);
567 data->state = VPN_STATE_CONNECT;
572 vpn_provider_set_index(provider, -1);
573 vpn_provider_set_data(provider, NULL);
574 vpn_provider_unref(data->provider);
575 g_free(data->if_name);
581 static int vpn_probe(struct vpn_provider *provider)
586 static int vpn_disconnect(struct vpn_provider *provider)
588 struct vpn_data *data = vpn_provider_get_data(provider);
589 struct vpn_driver_data *vpn_driver_data;
592 DBG("disconnect provider %p:", provider);
597 name = vpn_provider_get_driver_name(provider);
601 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
602 if (vpn_driver_data->vpn_driver->disconnect)
603 vpn_driver_data->vpn_driver->disconnect(provider);
605 if (data->watch != 0) {
606 vpn_provider_unref(provider);
607 vpn_rtnl_remove_watch(data->watch);
611 data->state = VPN_STATE_DISCONNECT;
612 connman_task_stop(data->task);
617 static int vpn_remove(struct vpn_provider *provider)
619 struct vpn_data *data;
620 struct vpn_driver_data *driver_data;
624 data = vpn_provider_get_data(provider);
625 name = vpn_provider_get_driver_name(provider);
630 if (data->watch != 0) {
631 vpn_provider_unref(provider);
632 vpn_rtnl_remove_watch(data->watch);
636 connman_task_stop(data->task);
638 g_usleep(G_USEC_PER_SEC);
645 driver_data = g_hash_table_lookup(driver_hash, name);
647 if (driver_data && driver_data->vpn_driver->remove)
648 err = driver_data->vpn_driver->remove(provider);
651 DBG("%p vpn_driver->remove() returned %d", provider, err);
656 static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile)
658 struct vpn_driver_data *vpn_driver_data;
661 name = vpn_provider_get_driver_name(provider);
662 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
663 if (vpn_driver_data &&
664 vpn_driver_data->vpn_driver->save)
665 return vpn_driver_data->vpn_driver->save(provider, keyfile);
670 static int vpn_route_env_parse(struct vpn_provider *provider, const char *key,
671 int *family, unsigned long *idx,
672 enum vpn_provider_route_type *type)
674 struct vpn_driver_data *vpn_driver_data = NULL;
675 const char *name = NULL;
680 name = vpn_provider_get_driver_name(provider);
681 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
683 if (vpn_driver_data && vpn_driver_data->vpn_driver->route_env_parse)
684 return vpn_driver_data->vpn_driver->route_env_parse(provider, key,
690 int vpn_register(const char *name, struct vpn_driver *vpn_driver,
693 struct vpn_driver_data *data;
695 data = g_try_new0(struct vpn_driver_data, 1);
700 data->program = program;
702 data->vpn_driver = vpn_driver;
704 data->provider_driver.name = name;
705 data->provider_driver.disconnect = vpn_disconnect;
706 data->provider_driver.connect = vpn_connect;
707 data->provider_driver.probe = vpn_probe;
708 data->provider_driver.remove = vpn_remove;
709 data->provider_driver.save = vpn_save;
710 data->provider_driver.set_state = vpn_set_state;
711 data->provider_driver.route_env_parse = vpn_route_env_parse;
714 driver_hash = g_hash_table_new_full(g_str_hash,
719 connman_error("driver_hash not initialized for %s", name);
724 g_hash_table_replace(driver_hash, (char *)name, data);
726 vpn_provider_driver_register(&data->provider_driver);
731 void vpn_unregister(const char *name)
733 struct vpn_driver_data *data;
735 data = g_hash_table_lookup(driver_hash, name);
739 vpn_provider_driver_unregister(&data->provider_driver);
741 g_hash_table_remove(driver_hash, name);
743 if (g_hash_table_size(driver_hash) == 0)
744 g_hash_table_destroy(driver_hash);