5 * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
6 * Copyright (C) 2011-2014 BMW Car IT GmbH.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
35 struct gateway_config {
48 struct connman_service *service;
50 struct gateway_config *ipv4_gateway;
51 struct gateway_config *ipv6_gateway;
55 static GHashTable *gateway_hash = NULL;
57 static struct gateway_config *find_gateway(int index, const char *gateway)
65 g_hash_table_iter_init(&iter, gateway_hash);
67 while (g_hash_table_iter_next(&iter, &key, &value)) {
68 struct gateway_data *data = value;
70 if (data->ipv4_gateway && data->index == index &&
71 g_str_equal(data->ipv4_gateway->gateway,
73 return data->ipv4_gateway;
75 if (data->ipv6_gateway && data->index == index &&
76 g_str_equal(data->ipv6_gateway->gateway,
78 return data->ipv6_gateway;
84 static struct gateway_data *lookup_gateway_data(struct gateway_config *config)
92 g_hash_table_iter_init(&iter, gateway_hash);
94 while (g_hash_table_iter_next(&iter, &key, &value)) {
95 struct gateway_data *data = value;
97 if (data->ipv4_gateway &&
98 data->ipv4_gateway == config)
101 if (data->ipv6_gateway &&
102 data->ipv6_gateway == config)
109 static struct gateway_data *find_vpn_gateway(int index, const char *gateway)
117 g_hash_table_iter_init(&iter, gateway_hash);
119 while (g_hash_table_iter_next(&iter, &key, &value)) {
120 struct gateway_data *data = value;
122 if (data->ipv4_gateway && data->index == index &&
123 g_str_equal(data->ipv4_gateway->gateway,
127 if (data->ipv6_gateway && data->index == index &&
128 g_str_equal(data->ipv6_gateway->gateway,
136 struct get_gateway_params {
141 static void get_gateway_cb(const char *gateway, int index, void *user_data)
143 struct gateway_config *config;
144 struct gateway_data *data;
145 struct get_gateway_params *params = user_data;
151 DBG("phy index %d phy gw %s vpn index %d vpn gw %s", index, gateway,
152 params->vpn_index, params->vpn_gateway);
154 data = find_vpn_gateway(params->vpn_index, params->vpn_gateway);
156 DBG("Cannot find VPN link route, index %d addr %s",
157 params->vpn_index, params->vpn_gateway);
161 family = connman_inet_check_ipaddress(params->vpn_gateway);
163 if (family == AF_INET)
164 config = data->ipv4_gateway;
165 else if (family == AF_INET6)
166 config = data->ipv6_gateway;
170 config->vpn_phy_index = index;
172 DBG("vpn %s phy index %d", config->vpn_ip, config->vpn_phy_index);
175 g_free(params->vpn_gateway);
179 static void set_vpn_routes(struct gateway_data *new_gateway,
180 struct connman_service *service,
182 enum connman_ipconfig_type type,
184 struct gateway_data *active_gateway)
186 struct gateway_config *config;
187 struct connman_ipconfig *ipconfig;
190 DBG("new %p service %p gw %s type %d peer %s active %p",
191 new_gateway, service, gateway, type, peer, active_gateway);
193 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
194 ipconfig = __connman_service_get_ip4config(service);
195 config = new_gateway->ipv4_gateway;
196 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
197 ipconfig = __connman_service_get_ip6config(service);
198 config = new_gateway->ipv6_gateway;
203 int index = __connman_ipconfig_get_index(ipconfig);
204 struct get_gateway_params *params;
208 config->vpn_ip = g_strdup(peer);
210 config->vpn_ip = g_strdup(gateway);
212 params = g_try_malloc(sizeof(struct get_gateway_params));
216 params->vpn_index = index;
217 params->vpn_gateway = g_strdup(gateway);
220 * Find the gateway that is serving the VPN link
222 __connman_inet_get_route(gateway, get_gateway_cb, params);
228 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
230 * Special route to VPN server via gateway. This
231 * is needed so that we can access hosts behind
232 * the VPN. The route might already exist depending
233 * on network topology.
235 if (!active_gateway->ipv4_gateway)
238 DBG("active gw %s", active_gateway->ipv4_gateway->gateway);
240 if (g_strcmp0(active_gateway->ipv4_gateway->gateway,
242 dest = active_gateway->ipv4_gateway->gateway;
246 connman_inet_add_host_route(active_gateway->index, gateway,
249 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
251 if (!active_gateway->ipv6_gateway)
254 DBG("active gw %s", active_gateway->ipv6_gateway->gateway);
256 if (g_strcmp0(active_gateway->ipv6_gateway->gateway,
258 dest = active_gateway->ipv6_gateway->gateway;
262 connman_inet_add_ipv6_host_route(active_gateway->index,
267 static int del_routes(struct gateway_data *data,
268 enum connman_ipconfig_type type)
270 int status4 = 0, status6 = 0;
271 bool do_ipv4 = false, do_ipv6 = false;
273 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
275 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
278 do_ipv4 = do_ipv6 = true;
280 if (do_ipv4 && data->ipv4_gateway) {
281 if (data->ipv4_gateway->vpn) {
282 status4 = connman_inet_clear_gateway_address(
284 data->ipv4_gateway->vpn_ip);
286 } else if (g_strcmp0(data->ipv4_gateway->gateway,
288 status4 = connman_inet_clear_gateway_interface(
291 connman_inet_del_host_route(data->index,
292 data->ipv4_gateway->gateway);
293 status4 = connman_inet_clear_gateway_address(
295 data->ipv4_gateway->gateway);
299 if (do_ipv6 && data->ipv6_gateway) {
300 if (data->ipv6_gateway->vpn) {
301 status6 = connman_inet_clear_ipv6_gateway_address(
303 data->ipv6_gateway->vpn_ip);
305 } else if (g_strcmp0(data->ipv6_gateway->gateway, "::") == 0) {
306 status6 = connman_inet_clear_ipv6_gateway_interface(
309 connman_inet_del_ipv6_host_route(data->index,
310 data->ipv6_gateway->gateway);
311 status6 = connman_inet_clear_ipv6_gateway_address(
313 data->ipv6_gateway->gateway);
317 return (status4 < 0 ? status4 : status6);
320 static int disable_gateway(struct gateway_data *data,
321 enum connman_ipconfig_type type)
325 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
326 if (data->ipv4_gateway)
327 active = data->ipv4_gateway->active;
328 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
329 if (data->ipv6_gateway)
330 active = data->ipv6_gateway->active;
334 DBG("type %d active %d", type, active);
337 return del_routes(data, type);
342 static struct gateway_data *add_gateway(struct connman_service *service,
343 int index, const char *gateway,
344 enum connman_ipconfig_type type)
346 struct gateway_data *data, *old;
347 struct gateway_config *config;
349 if (!gateway || strlen(gateway) == 0)
352 data = g_try_new0(struct gateway_data, 1);
358 config = g_try_new0(struct gateway_config, 1);
364 config->gateway = g_strdup(gateway);
365 config->vpn_ip = NULL;
366 config->vpn_phy_ip = NULL;
368 config->vpn_phy_index = -1;
369 config->active = false;
371 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
372 data->ipv4_gateway = config;
373 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
374 data->ipv6_gateway = config;
376 g_free(config->gateway);
382 data->service = service;
384 data->order = __connman_service_get_order(service);
387 * If the service is already in the hash, then we
388 * must not replace it blindly but disable the gateway
389 * of the type we are replacing and take the other type
390 * from old gateway settings.
392 old = g_hash_table_lookup(gateway_hash, service);
394 DBG("Replacing gw %p ipv4 %p ipv6 %p", old,
395 old->ipv4_gateway, old->ipv6_gateway);
396 disable_gateway(old, type);
397 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
398 data->ipv6_gateway = old->ipv6_gateway;
399 old->ipv6_gateway = NULL;
400 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
401 data->ipv4_gateway = old->ipv4_gateway;
402 old->ipv4_gateway = NULL;
406 connman_service_ref(data->service);
407 g_hash_table_replace(gateway_hash, service, data);
412 static void set_default_gateway(struct gateway_data *data,
413 enum connman_ipconfig_type type)
416 int status4 = 0, status6 = 0;
417 bool do_ipv4 = false, do_ipv6 = false;
419 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
421 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
424 do_ipv4 = do_ipv6 = true;
426 DBG("type %d gateway ipv4 %p ipv6 %p", type, data->ipv4_gateway,
429 if (do_ipv4 && data->ipv4_gateway &&
430 data->ipv4_gateway->vpn) {
431 connman_inet_set_gateway_interface(data->index);
432 data->ipv4_gateway->active = true;
434 DBG("set %p index %d vpn %s index %d phy %s",
435 data, data->index, data->ipv4_gateway->vpn_ip,
436 data->ipv4_gateway->vpn_phy_index,
437 data->ipv4_gateway->vpn_phy_ip);
439 __connman_service_indicate_default(data->service);
444 if (do_ipv6 && data->ipv6_gateway &&
445 data->ipv6_gateway->vpn) {
446 connman_inet_set_ipv6_gateway_interface(data->index);
447 data->ipv6_gateway->active = true;
449 DBG("set %p index %d vpn %s index %d phy %s",
450 data, data->index, data->ipv6_gateway->vpn_ip,
451 data->ipv6_gateway->vpn_phy_index,
452 data->ipv6_gateway->vpn_phy_ip);
454 __connman_service_indicate_default(data->service);
459 index = __connman_service_get_index(data->service);
461 if (do_ipv4 && data->ipv4_gateway &&
462 g_strcmp0(data->ipv4_gateway->gateway,
464 if (connman_inet_set_gateway_interface(index) < 0)
469 if (do_ipv6 && data->ipv6_gateway &&
470 g_strcmp0(data->ipv6_gateway->gateway,
472 if (connman_inet_set_ipv6_gateway_interface(index) < 0)
477 if (do_ipv6 && data->ipv6_gateway)
478 status6 = __connman_inet_add_default_to_table(RT_TABLE_MAIN,
479 index, data->ipv6_gateway->gateway);
481 if (do_ipv4 && data->ipv4_gateway)
482 status4 = __connman_inet_add_default_to_table(RT_TABLE_MAIN,
483 index, data->ipv4_gateway->gateway);
485 if (status4 < 0 || status6 < 0)
489 __connman_service_indicate_default(data->service);
492 static void unset_default_gateway(struct gateway_data *data,
493 enum connman_ipconfig_type type)
496 bool do_ipv4 = false, do_ipv6 = false;
498 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
500 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
503 do_ipv4 = do_ipv6 = true;
505 DBG("type %d gateway ipv4 %p ipv6 %p", type, data->ipv4_gateway,
508 if (do_ipv4 && data->ipv4_gateway &&
509 data->ipv4_gateway->vpn) {
510 connman_inet_clear_gateway_interface(data->index);
511 data->ipv4_gateway->active = false;
513 DBG("unset %p index %d vpn %s index %d phy %s",
514 data, data->index, data->ipv4_gateway->vpn_ip,
515 data->ipv4_gateway->vpn_phy_index,
516 data->ipv4_gateway->vpn_phy_ip);
521 if (do_ipv6 && data->ipv6_gateway &&
522 data->ipv6_gateway->vpn) {
523 connman_inet_clear_ipv6_gateway_interface(data->index);
524 data->ipv6_gateway->active = false;
526 DBG("unset %p index %d vpn %s index %d phy %s",
527 data, data->index, data->ipv6_gateway->vpn_ip,
528 data->ipv6_gateway->vpn_phy_index,
529 data->ipv6_gateway->vpn_phy_ip);
534 index = __connman_service_get_index(data->service);
536 if (do_ipv4 && data->ipv4_gateway &&
537 g_strcmp0(data->ipv4_gateway->gateway,
539 connman_inet_clear_gateway_interface(index);
543 if (do_ipv6 && data->ipv6_gateway &&
544 g_strcmp0(data->ipv6_gateway->gateway,
546 connman_inet_clear_ipv6_gateway_interface(index);
550 if (do_ipv6 && data->ipv6_gateway)
551 connman_inet_clear_ipv6_gateway_address(index,
552 data->ipv6_gateway->gateway);
554 if (do_ipv4 && data->ipv4_gateway)
555 connman_inet_clear_gateway_address(index,
556 data->ipv4_gateway->gateway);
559 static struct gateway_data *find_default_gateway(void)
561 struct gateway_data *found = NULL;
562 unsigned int order = 0;
566 g_hash_table_iter_init(&iter, gateway_hash);
568 while (g_hash_table_iter_next(&iter, &key, &value)) {
569 struct gateway_data *data = value;
571 if (!found || data->order > order) {
575 DBG("default %p order %d", found, order);
582 static bool choose_default_gateway(struct gateway_data *data,
583 struct gateway_data *candidate)
585 bool downgraded = false;
588 * If the current default is not active, then we mark
589 * this one as default. If the other one is already active
590 * we mark this one as non default.
592 if (data->ipv4_gateway) {
593 if (candidate->ipv4_gateway &&
594 !candidate->ipv4_gateway->active) {
595 DBG("ipv4 downgrading %p", candidate);
596 unset_default_gateway(candidate,
597 CONNMAN_IPCONFIG_TYPE_IPV4);
599 if (candidate->ipv4_gateway &&
600 candidate->ipv4_gateway->active &&
601 candidate->order > data->order) {
602 DBG("ipv4 downgrading this %p", data);
603 unset_default_gateway(data,
604 CONNMAN_IPCONFIG_TYPE_IPV4);
609 if (data->ipv6_gateway) {
610 if (candidate->ipv6_gateway &&
611 !candidate->ipv6_gateway->active) {
612 DBG("ipv6 downgrading %p", candidate);
613 unset_default_gateway(candidate,
614 CONNMAN_IPCONFIG_TYPE_IPV6);
617 if (candidate->ipv6_gateway &&
618 candidate->ipv6_gateway->active &&
619 candidate->order > data->order) {
620 DBG("ipv6 downgrading this %p", data);
621 unset_default_gateway(data,
622 CONNMAN_IPCONFIG_TYPE_IPV6);
630 static void connection_newgateway(int index, const char *gateway)
632 struct gateway_config *config;
633 struct gateway_data *data;
638 DBG("index %d gateway %s", index, gateway);
640 config = find_gateway(index, gateway);
644 config->active = true;
647 * It is possible that we have two default routes atm
648 * if there are two gateways waiting rtnl activation at the
651 data = lookup_gateway_data(config);
655 if (data->default_checked)
659 * The next checks are only done once, otherwise setting
660 * the default gateway could lead into rtnl forever loop.
663 g_hash_table_iter_init(&iter, gateway_hash);
665 while (g_hash_table_iter_next(&iter, &key, &value)) {
666 struct gateway_data *candidate = value;
668 if (candidate == data)
671 found = choose_default_gateway(data, candidate);
677 #if defined TIZEN_EXT
678 if (data->ipv4_gateway != NULL){
679 set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
680 connman_check_proxy_setup_and_wispr_start(data->service);
683 if (data->ipv4_gateway)
684 set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
687 if (data->ipv6_gateway)
688 set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6);
691 data->default_checked = true;
694 static void remove_gateway(gpointer user_data)
696 struct gateway_data *data = user_data;
698 DBG("gateway ipv4 %p ipv6 %p", data->ipv4_gateway, data->ipv6_gateway);
700 if (data->ipv4_gateway) {
701 g_free(data->ipv4_gateway->gateway);
702 g_free(data->ipv4_gateway->vpn_ip);
703 g_free(data->ipv4_gateway->vpn_phy_ip);
704 g_free(data->ipv4_gateway);
707 if (data->ipv6_gateway) {
708 g_free(data->ipv6_gateway->gateway);
709 g_free(data->ipv6_gateway->vpn_ip);
710 g_free(data->ipv6_gateway->vpn_phy_ip);
711 g_free(data->ipv6_gateway);
714 connman_service_unref(data->service);
719 static void connection_delgateway(int index, const char *gateway)
721 struct gateway_config *config;
722 struct gateway_data *data;
724 DBG("index %d gateway %s", index, gateway);
726 config = find_gateway(index, gateway);
728 config->active = false;
730 data = find_default_gateway();
732 set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_ALL);
735 static struct connman_rtnl connection_rtnl = {
736 .name = "connection",
737 .newgateway = connection_newgateway,
738 .delgateway = connection_delgateway,
741 static struct gateway_data *find_active_gateway(void)
748 g_hash_table_iter_init(&iter, gateway_hash);
750 while (g_hash_table_iter_next(&iter, &key, &value)) {
751 struct gateway_data *data = value;
753 if (data->ipv4_gateway &&
754 data->ipv4_gateway->active)
757 if (data->ipv6_gateway &&
758 data->ipv6_gateway->active)
765 static void update_order(void)
772 g_hash_table_iter_init(&iter, gateway_hash);
774 while (g_hash_table_iter_next(&iter, &key, &value)) {
775 struct gateway_data *data = value;
777 data->order = __connman_service_get_order(data->service);
781 void __connman_connection_gateway_activate(struct connman_service *service,
782 enum connman_ipconfig_type type)
784 struct gateway_data *data = NULL;
786 data = g_hash_table_lookup(gateway_hash, service);
790 DBG("gateway %p/%p type %d", data->ipv4_gateway,
791 data->ipv6_gateway, type);
793 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
794 data->ipv4_gateway->active = true;
795 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
796 data->ipv6_gateway->active = true;
799 static void add_host_route(int family, int index, const char *gateway,
800 enum connman_service_type service_type)
804 if (g_strcmp0(gateway, "0.0.0.0") != 0) {
806 * We must not set route to the phy dev gateway in
807 * VPN link. The packets to VPN link might be routed
808 * back to itself and not routed into phy link gateway.
810 if (service_type != CONNMAN_SERVICE_TYPE_VPN)
811 connman_inet_add_host_route(index, gateway,
815 * Add host route to P-t-P link so that services can
816 * be moved around and we can have some link to P-t-P
817 * network (although those P-t-P links have limited
818 * usage if default route is not directed to them)
821 if (connman_inet_get_dest_addr(index, &dest) == 0) {
822 connman_inet_add_host_route(index, dest, NULL);
829 if (g_strcmp0(gateway, "::") != 0) {
830 if (service_type != CONNMAN_SERVICE_TYPE_VPN)
831 connman_inet_add_ipv6_host_route(index,
834 /* P-t-P link, add route to destination */
836 if (connman_inet_ipv6_get_dest_addr(index,
838 connman_inet_add_ipv6_host_route(index, dest,
847 #if defined TIZEN_EXT
848 static bool __connman_service_is_not_cellular_internet_profile(
849 struct connman_service *cellular)
853 const char internet_suffix[] = "_1";
854 const char prepaid_internet_suffix[] = "_3";
856 if (connman_service_get_type(cellular) != CONNMAN_SERVICE_TYPE_CELLULAR)
859 path = __connman_service_get_path(cellular);
861 suffix = strrchr(path, '_');
863 if (g_strcmp0(suffix, internet_suffix) != 0 &&
864 g_strcmp0(suffix, prepaid_internet_suffix) != 0) {
865 DBG("not internet service profile: %s", path);
873 int __connman_connection_gateway_add(struct connman_service *service,
875 enum connman_ipconfig_type type,
878 struct gateway_data *active_gateway = NULL;
879 struct gateway_data *new_gateway = NULL;
880 enum connman_ipconfig_type type4 = CONNMAN_IPCONFIG_TYPE_UNKNOWN,
881 type6 = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
882 enum connman_service_type service_type =
883 connman_service_get_type(service);
886 index = __connman_service_get_index(service);
889 * If gateway is NULL, it's a point to point link and the default
890 * gateway for ipv4 is 0.0.0.0 and for ipv6 is ::, meaning the
893 if (!gateway && type == CONNMAN_IPCONFIG_TYPE_IPV4)
896 if (!gateway && type == CONNMAN_IPCONFIG_TYPE_IPV6)
899 #if defined TIZEN_EXT
900 if (__connman_service_is_not_cellular_internet_profile(service) == TRUE) {
901 /* not internet service should not be default gateway */
903 DBG("no internet service %p index %d gateway %s vpn ip %s type %d",
904 service, index, gateway, peer, type);
906 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
907 add_host_route(AF_INET, index, gateway, service_type);
908 __connman_service_nameserver_add_routes(service, gateway);
909 type4 = CONNMAN_IPCONFIG_TYPE_IPV4;
912 if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
913 add_host_route(AF_INET6, index, gateway, service_type);
914 __connman_service_nameserver_add_routes(service, gateway);
915 type6 = CONNMAN_IPCONFIG_TYPE_IPV6;
921 DBG("service %p index %d gateway %s vpn ip %s type %d",
922 service, index, gateway, peer, type);
924 new_gateway = add_gateway(service, index, gateway, type);
928 active_gateway = find_active_gateway();
930 DBG("active %p index %d new %p", active_gateway,
931 active_gateway ? active_gateway->index : -1, new_gateway);
933 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
934 new_gateway->ipv4_gateway) {
935 add_host_route(AF_INET, index, gateway, service_type);
936 __connman_service_nameserver_add_routes(service,
937 new_gateway->ipv4_gateway->gateway);
938 type4 = CONNMAN_IPCONFIG_TYPE_IPV4;
941 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
942 new_gateway->ipv6_gateway) {
943 add_host_route(AF_INET6, index, gateway, service_type);
944 __connman_service_nameserver_add_routes(service,
945 new_gateway->ipv6_gateway->gateway);
946 type6 = CONNMAN_IPCONFIG_TYPE_IPV6;
949 if (service_type == CONNMAN_SERVICE_TYPE_VPN) {
951 set_vpn_routes(new_gateway, service, gateway, type, peer,
955 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
956 new_gateway->ipv4_gateway)
957 new_gateway->ipv4_gateway->vpn = false;
959 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
960 new_gateway->ipv6_gateway)
961 new_gateway->ipv6_gateway->vpn = false;
964 if (!active_gateway) {
965 #if defined TIZEN_EXT
966 if(new_gateway->ipv4_gateway)
967 DBG("ConnMan, Set default gateway[%s], active[%d]",
968 new_gateway->ipv4_gateway->gateway,
969 new_gateway->ipv4_gateway->active);
971 set_default_gateway(new_gateway, type);
975 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
976 new_gateway->ipv4_gateway &&
977 new_gateway->ipv4_gateway->vpn) {
978 if (!__connman_service_is_split_routing(new_gateway->service))
979 connman_inet_clear_gateway_address(
980 active_gateway->index,
981 active_gateway->ipv4_gateway->gateway);
984 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
985 new_gateway->ipv6_gateway &&
986 new_gateway->ipv6_gateway->vpn) {
987 if (!__connman_service_is_split_routing(new_gateway->service))
988 connman_inet_clear_ipv6_gateway_address(
989 active_gateway->index,
990 active_gateway->ipv6_gateway->gateway);
994 if (type4 == CONNMAN_IPCONFIG_TYPE_IPV4)
995 __connman_service_ipconfig_indicate_state(service,
996 CONNMAN_SERVICE_STATE_READY,
997 CONNMAN_IPCONFIG_TYPE_IPV4);
999 if (type6 == CONNMAN_IPCONFIG_TYPE_IPV6)
1000 __connman_service_ipconfig_indicate_state(service,
1001 CONNMAN_SERVICE_STATE_READY,
1002 CONNMAN_IPCONFIG_TYPE_IPV6);
1006 void __connman_connection_gateway_remove(struct connman_service *service,
1007 enum connman_ipconfig_type type)
1009 struct gateway_data *data = NULL;
1010 bool set_default4 = false, set_default6 = false;
1011 bool do_ipv4 = false, do_ipv6 = false;
1014 DBG("service %p type %d", service, type);
1016 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1018 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1021 do_ipv4 = do_ipv6 = true;
1023 __connman_service_nameserver_del_routes(service, type);
1025 data = g_hash_table_lookup(gateway_hash, service);
1029 if (do_ipv4 && data->ipv4_gateway)
1030 set_default4 = data->ipv4_gateway->vpn;
1032 if (do_ipv6 && data->ipv6_gateway)
1033 set_default6 = data->ipv6_gateway->vpn;
1035 DBG("ipv4 gateway %s ipv6 gateway %s vpn %d/%d",
1036 data->ipv4_gateway ? data->ipv4_gateway->gateway : "<null>",
1037 data->ipv6_gateway ? data->ipv6_gateway->gateway : "<null>",
1038 set_default4, set_default6);
1040 if (do_ipv4 && data->ipv4_gateway &&
1041 data->ipv4_gateway->vpn && data->index >= 0)
1042 connman_inet_del_host_route(data->ipv4_gateway->vpn_phy_index,
1043 data->ipv4_gateway->gateway);
1045 if (do_ipv6 && data->ipv6_gateway &&
1046 data->ipv6_gateway->vpn && data->index >= 0)
1047 connman_inet_del_ipv6_host_route(
1048 data->ipv6_gateway->vpn_phy_index,
1049 data->ipv6_gateway->gateway);
1051 err = disable_gateway(data, type);
1054 * We remove the service from the hash only if all the gateway
1055 * settings are to be removed.
1057 if (do_ipv4 == do_ipv6 ||
1058 (data->ipv4_gateway && !data->ipv6_gateway
1060 (data->ipv6_gateway && !data->ipv4_gateway
1062 g_hash_table_remove(gateway_hash, service);
1064 DBG("Not yet removing gw ipv4 %p/%d ipv6 %p/%d",
1065 data->ipv4_gateway, do_ipv4,
1066 data->ipv6_gateway, do_ipv6);
1068 /* with vpn this will be called after the network was deleted,
1069 * we need to call set_default here because we will not recieve any
1070 * gateway delete notification.
1071 * We hit the same issue if remove_gateway() fails.
1073 if (set_default4 || set_default6 || err < 0) {
1074 data = find_default_gateway();
1076 set_default_gateway(data, type);
1080 bool __connman_connection_update_gateway(void)
1082 struct gateway_data *default_gateway;
1083 bool updated = false;
1084 GHashTableIter iter;
1085 gpointer value, key;
1086 #if defined TIZEN_EXT
1087 static struct gateway_data *old_default = NULL;
1095 default_gateway = find_default_gateway();
1097 __connman_service_update_ordering();
1099 DBG("default %p", default_gateway);
1102 * There can be multiple active gateways so we need to
1105 g_hash_table_iter_init(&iter, gateway_hash);
1107 while (g_hash_table_iter_next(&iter, &key, &value)) {
1108 struct gateway_data *active_gateway = value;
1110 if (active_gateway == default_gateway)
1113 if (active_gateway->ipv4_gateway &&
1114 active_gateway->ipv4_gateway->active) {
1116 unset_default_gateway(active_gateway,
1117 CONNMAN_IPCONFIG_TYPE_IPV4);
1121 if (active_gateway->ipv6_gateway &&
1122 active_gateway->ipv6_gateway->active) {
1124 unset_default_gateway(active_gateway,
1125 CONNMAN_IPCONFIG_TYPE_IPV6);
1130 #if defined TIZEN_EXT
1131 if (updated == false && old_default != default_gateway) {
1133 old_default = default_gateway;
1136 if (updated && default_gateway) {
1137 if (default_gateway->ipv4_gateway)
1138 set_default_gateway(default_gateway,
1139 CONNMAN_IPCONFIG_TYPE_IPV4);
1141 if (default_gateway->ipv6_gateway)
1142 set_default_gateway(default_gateway,
1143 CONNMAN_IPCONFIG_TYPE_IPV6);
1149 int __connman_connection_get_vpn_index(int phy_index)
1151 GHashTableIter iter;
1152 gpointer value, key;
1154 g_hash_table_iter_init(&iter, gateway_hash);
1156 while (g_hash_table_iter_next(&iter, &key, &value)) {
1157 struct gateway_data *data = value;
1159 if (data->ipv4_gateway &&
1160 data->ipv4_gateway->vpn_phy_index == phy_index)
1163 if (data->ipv6_gateway &&
1164 data->ipv6_gateway->vpn_phy_index == phy_index)
1171 int __connman_connection_init(void)
1177 gateway_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1178 NULL, remove_gateway);
1180 err = connman_rtnl_register(&connection_rtnl);
1182 connman_error("Failed to setup RTNL gateway driver");
1187 void __connman_connection_cleanup(void)
1189 GHashTableIter iter;
1190 gpointer value, key;
1194 connman_rtnl_unregister(&connection_rtnl);
1196 g_hash_table_iter_init(&iter, gateway_hash);
1198 while (g_hash_table_iter_next(&iter, &key, &value)) {
1199 struct gateway_data *data = value;
1201 disable_gateway(data, CONNMAN_IPCONFIG_TYPE_ALL);
1204 g_hash_table_destroy(gateway_hash);
1205 gateway_hash = NULL;