5 * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
6 * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
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;
52 connman_bool_t default_checked;
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) == TRUE) {
68 struct gateway_data *data = value;
70 if (data->ipv4_gateway != NULL && data->index == index &&
71 g_str_equal(data->ipv4_gateway->gateway,
73 return data->ipv4_gateway;
75 if (data->ipv6_gateway != NULL && 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) == TRUE) {
95 struct gateway_data *data = value;
97 if (data->ipv4_gateway != NULL &&
98 data->ipv4_gateway == config)
101 if (data->ipv6_gateway != NULL &&
102 data->ipv6_gateway == config)
110 * Find the gateway that is serving the VPN link
112 static struct gateway_data *find_phy_gateway(int index, const char *gateway)
120 g_hash_table_iter_init(&iter, gateway_hash);
122 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
123 struct gateway_data *data = value;
125 if (data->ipv4_gateway != NULL && data->index != index &&
126 g_str_equal(data->ipv4_gateway->gateway,
130 if (data->ipv6_gateway != NULL && data->index != index &&
131 g_str_equal(data->ipv6_gateway->gateway,
139 static void set_vpn_routes(struct gateway_data *new_gateway,
140 struct connman_service *service,
142 enum connman_ipconfig_type type,
144 struct gateway_data *active_gateway)
146 struct gateway_config *config;
147 struct gateway_data *data;
148 struct connman_ipconfig *ipconfig;
152 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
153 ipconfig = __connman_service_get_ip4config(service);
154 config = new_gateway->ipv4_gateway;
155 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
156 ipconfig = __connman_service_get_ip6config(service);
157 config = new_gateway->ipv6_gateway;
166 config->vpn_ip = g_strdup(peer);
167 else if (gateway != NULL)
168 config->vpn_ip = g_strdup(gateway);
170 index = __connman_ipconfig_get_index(ipconfig);
171 data = find_phy_gateway(index, gateway);
177 * data->service points now to original
178 * service that is serving the VPN link
180 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
181 ipconfig = __connman_service_get_ip4config(data->service);
182 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
183 ipconfig = __connman_service_get_ip6config(data->service);
187 if (ipconfig != NULL) {
190 address = __connman_ipconfig_get_local(ipconfig);
191 config->vpn_phy_ip = g_strdup(address);
194 config->vpn_phy_index = data->index;
196 DBG("vpn %s phy %s index %d", config->vpn_ip,
197 config->vpn_phy_ip, config->vpn_phy_index);
200 if (active_gateway == NULL)
203 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
205 * Special route to VPN server via gateway. This
206 * is needed so that we can access hosts behind
207 * the VPN. The route might already exist depending
208 * on network topology.
210 if (active_gateway->ipv4_gateway == NULL)
213 if (g_strcmp0(active_gateway->ipv4_gateway->gateway,
215 dest = active_gateway->ipv4_gateway->gateway;
219 connman_inet_add_host_route(active_gateway->index, gateway,
222 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
224 if (active_gateway->ipv6_gateway == NULL)
227 if (g_strcmp0(active_gateway->ipv6_gateway->gateway,
229 dest = active_gateway->ipv6_gateway->gateway;
233 connman_inet_add_ipv6_host_route(active_gateway->index,
238 static int del_routes(struct gateway_data *data,
239 enum connman_ipconfig_type type)
241 int status4 = 0, status6 = 0;
242 int do_ipv4 = FALSE, do_ipv6 = FALSE;
244 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
246 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
249 do_ipv4 = do_ipv6 = TRUE;
251 if (do_ipv4 == TRUE && data->ipv4_gateway != NULL) {
252 if (data->ipv4_gateway->vpn == TRUE) {
253 status4 = connman_inet_clear_gateway_address(
255 data->ipv4_gateway->vpn_ip);
257 } else if (g_strcmp0(data->ipv4_gateway->gateway,
259 status4 = connman_inet_clear_gateway_interface(
262 connman_inet_del_host_route(data->index,
263 data->ipv4_gateway->gateway);
264 status4 = connman_inet_clear_gateway_address(
266 data->ipv4_gateway->gateway);
270 if (do_ipv6 == TRUE && data->ipv6_gateway != NULL) {
271 if (data->ipv6_gateway->vpn == TRUE) {
272 status6 = connman_inet_clear_ipv6_gateway_address(
274 data->ipv6_gateway->vpn_ip);
276 } else if (g_strcmp0(data->ipv6_gateway->gateway, "::") == 0) {
277 status6 = connman_inet_clear_ipv6_gateway_interface(
280 connman_inet_del_ipv6_host_route(data->index,
281 data->ipv6_gateway->gateway);
282 status6 = connman_inet_clear_ipv6_gateway_address(
284 data->ipv6_gateway->gateway);
288 return (status4 < 0 ? status4 : status6);
291 static int disable_gateway(struct gateway_data *data,
292 enum connman_ipconfig_type type)
294 gboolean active = FALSE;
296 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
297 if (data->ipv4_gateway != NULL)
298 active = data->ipv4_gateway->active;
299 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
300 if (data->ipv6_gateway != NULL)
301 active = data->ipv6_gateway->active;
305 DBG("type %d active %d", type, active);
308 return del_routes(data, type);
313 static struct gateway_data *add_gateway(struct connman_service *service,
314 int index, const char *gateway,
315 enum connman_ipconfig_type type)
317 struct gateway_data *data, *old;
318 struct gateway_config *config;
320 if (gateway == NULL || strlen(gateway) == 0)
323 data = g_try_new0(struct gateway_data, 1);
329 config = g_try_new0(struct gateway_config, 1);
330 if (config == NULL) {
335 config->gateway = g_strdup(gateway);
336 config->vpn_ip = NULL;
337 config->vpn_phy_ip = NULL;
339 config->vpn_phy_index = -1;
340 config->active = FALSE;
342 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
343 data->ipv4_gateway = config;
344 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
345 data->ipv6_gateway = config;
347 g_free(config->gateway);
353 data->service = service;
355 data->order = __connman_service_get_order(service);
358 * If the service is already in the hash, then we
359 * must not replace it blindly but disable the gateway
360 * of the type we are replacing and take the other type
361 * from old gateway settings.
363 old = g_hash_table_lookup(gateway_hash, service);
365 DBG("Replacing gw %p ipv4 %p ipv6 %p", old,
366 old->ipv4_gateway, old->ipv6_gateway);
367 disable_gateway(old, type);
368 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
369 data->ipv6_gateway = old->ipv6_gateway;
370 old->ipv6_gateway = NULL;
371 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
372 data->ipv4_gateway = old->ipv4_gateway;
373 old->ipv4_gateway = NULL;
377 * Only take a ref if we are adding new stuff to hash.
379 connman_service_ref(service);
382 g_hash_table_replace(gateway_hash, service, data);
387 static void set_default_gateway(struct gateway_data *data,
388 enum connman_ipconfig_type type)
391 int status4 = 0, status6 = 0;
392 int do_ipv4 = FALSE, do_ipv6 = FALSE;
394 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
396 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
399 do_ipv4 = do_ipv6 = TRUE;
401 DBG("type %d gateway ipv4 %p ipv6 %p", type, data->ipv4_gateway,
404 if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
405 data->ipv4_gateway->vpn == TRUE) {
406 connman_inet_set_gateway_address(data->index,
407 data->ipv4_gateway->vpn_ip);
408 connman_inet_add_host_route(data->index,
409 data->ipv4_gateway->vpn_ip, NULL);
410 data->ipv4_gateway->active = TRUE;
412 DBG("set %p index %d vpn %s index %d phy %s",
413 data, data->index, data->ipv4_gateway->vpn_ip,
414 data->ipv4_gateway->vpn_phy_index,
415 data->ipv4_gateway->vpn_phy_ip);
417 __connman_service_indicate_default(data->service);
422 if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
423 data->ipv6_gateway->vpn == TRUE) {
424 connman_inet_set_ipv6_gateway_address(data->index,
425 data->ipv6_gateway->vpn_ip);
426 connman_inet_add_ipv6_host_route(data->index,
427 data->ipv6_gateway->vpn_ip, NULL);
428 data->ipv6_gateway->active = TRUE;
430 DBG("set %p index %d vpn %s index %d phy %s",
431 data, data->index, data->ipv6_gateway->vpn_ip,
432 data->ipv6_gateway->vpn_phy_index,
433 data->ipv6_gateway->vpn_phy_ip);
435 __connman_service_indicate_default(data->service);
440 index = __connman_service_get_index(data->service);
442 if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
443 g_strcmp0(data->ipv4_gateway->gateway,
445 if (connman_inet_set_gateway_interface(index) < 0)
450 if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
451 g_strcmp0(data->ipv6_gateway->gateway,
453 if (connman_inet_set_ipv6_gateway_interface(index) < 0)
458 if (do_ipv6 == TRUE && data->ipv6_gateway != NULL)
459 status6 = connman_inet_set_ipv6_gateway_address(index,
460 data->ipv6_gateway->gateway);
462 if (do_ipv4 == TRUE && data->ipv4_gateway != NULL)
463 status4 = connman_inet_set_gateway_address(index,
464 data->ipv4_gateway->gateway);
466 if (status4 < 0 || status6 < 0)
470 __connman_service_indicate_default(data->service);
473 static void unset_default_gateway(struct gateway_data *data,
474 enum connman_ipconfig_type type)
477 int do_ipv4 = FALSE, do_ipv6 = FALSE;
479 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
481 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
484 do_ipv4 = do_ipv6 = TRUE;
486 DBG("type %d gateway ipv4 %p ipv6 %p", type, data->ipv4_gateway,
489 if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
490 data->ipv4_gateway->vpn == TRUE) {
491 connman_inet_del_host_route(data->index,
492 data->ipv4_gateway->vpn_ip);
493 connman_inet_clear_gateway_address(data->index,
494 data->ipv4_gateway->vpn_ip);
495 data->ipv4_gateway->active = FALSE;
497 DBG("unset %p index %d vpn %s index %d phy %s",
498 data, data->index, data->ipv4_gateway->vpn_ip,
499 data->ipv4_gateway->vpn_phy_index,
500 data->ipv4_gateway->vpn_phy_ip);
505 if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
506 data->ipv6_gateway->vpn == TRUE) {
507 connman_inet_del_ipv6_host_route(data->index,
508 data->ipv6_gateway->vpn_ip);
509 connman_inet_clear_ipv6_gateway_address(data->index,
510 data->ipv6_gateway->vpn_ip);
511 data->ipv6_gateway->active = FALSE;
513 DBG("unset %p index %d vpn %s index %d phy %s",
514 data, data->index, data->ipv6_gateway->vpn_ip,
515 data->ipv6_gateway->vpn_phy_index,
516 data->ipv6_gateway->vpn_phy_ip);
521 index = __connman_service_get_index(data->service);
523 if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
524 g_strcmp0(data->ipv4_gateway->gateway,
526 connman_inet_clear_gateway_interface(index);
530 if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
531 g_strcmp0(data->ipv6_gateway->gateway,
533 connman_inet_clear_ipv6_gateway_interface(index);
537 if (do_ipv6 == TRUE && data->ipv6_gateway != NULL)
538 connman_inet_clear_ipv6_gateway_address(index,
539 data->ipv6_gateway->gateway);
541 if (do_ipv4 == TRUE && data->ipv4_gateway != NULL)
542 connman_inet_clear_gateway_address(index,
543 data->ipv4_gateway->gateway);
546 static struct gateway_data *find_default_gateway(void)
548 struct gateway_data *found = NULL;
549 unsigned int order = 0;
553 g_hash_table_iter_init(&iter, gateway_hash);
555 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
556 struct gateway_data *data = value;
558 if (found == NULL || data->order > order) {
562 DBG("default %p order %d", found, order);
569 static gboolean choose_default_gateway(struct gateway_data *data,
570 struct gateway_data *candidate)
572 gboolean downgraded = FALSE;
575 * If the current default is not active, then we mark
576 * this one as default. If the other one is already active
577 * we mark this one as non default.
579 if (data->ipv4_gateway != NULL) {
580 if (candidate->ipv4_gateway != NULL &&
581 candidate->ipv4_gateway->active == FALSE) {
582 DBG("ipv4 downgrading %p", candidate);
583 unset_default_gateway(candidate,
584 CONNMAN_IPCONFIG_TYPE_IPV4);
586 if (candidate->ipv4_gateway != NULL &&
587 candidate->ipv4_gateway->active == TRUE &&
588 candidate->order > data->order) {
589 DBG("ipv4 downgrading this %p", data);
590 unset_default_gateway(data,
591 CONNMAN_IPCONFIG_TYPE_IPV4);
596 if (data->ipv6_gateway != NULL) {
597 if (candidate->ipv6_gateway != NULL &&
598 candidate->ipv6_gateway->active == FALSE) {
599 DBG("ipv6 downgrading %p", candidate);
600 unset_default_gateway(candidate,
601 CONNMAN_IPCONFIG_TYPE_IPV6);
604 if (candidate->ipv6_gateway != NULL &&
605 candidate->ipv6_gateway->active == TRUE &&
606 candidate->order > data->order) {
607 DBG("ipv6 downgrading this %p", data);
608 unset_default_gateway(data,
609 CONNMAN_IPCONFIG_TYPE_IPV6);
617 static void connection_newgateway(int index, const char *gateway)
619 struct gateway_config *config;
620 struct gateway_data *data;
623 gboolean found = FALSE;
625 DBG("index %d gateway %s", index, gateway);
627 config = find_gateway(index, gateway);
631 config->active = TRUE;
634 * It is possible that we have two default routes atm
635 * if there are two gateways waiting rtnl activation at the
638 data = lookup_gateway_data(config);
642 if (data->default_checked == TRUE)
646 * The next checks are only done once, otherwise setting
647 * the default gateway could lead into rtnl forever loop.
650 g_hash_table_iter_init(&iter, gateway_hash);
652 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
653 struct gateway_data *candidate = value;
655 if (candidate == data)
658 found = choose_default_gateway(data, candidate);
663 if (found == FALSE) {
664 if (data->ipv4_gateway != NULL)
665 set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
667 if (data->ipv6_gateway != NULL)
668 set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6);
671 data->default_checked = TRUE;
674 static void remove_gateway(gpointer user_data)
676 struct gateway_data *data = user_data;
678 DBG("gateway ipv4 %p ipv6 %p", data->ipv4_gateway, data->ipv6_gateway);
680 if (data->ipv4_gateway != NULL) {
681 g_free(data->ipv4_gateway->gateway);
682 g_free(data->ipv4_gateway->vpn_ip);
683 g_free(data->ipv4_gateway->vpn_phy_ip);
684 g_free(data->ipv4_gateway);
687 if (data->ipv6_gateway != NULL) {
688 g_free(data->ipv6_gateway->gateway);
689 g_free(data->ipv6_gateway->vpn_ip);
690 g_free(data->ipv6_gateway->vpn_phy_ip);
691 g_free(data->ipv6_gateway);
697 static void connection_delgateway(int index, const char *gateway)
699 struct gateway_config *config;
700 struct gateway_data *data;
702 DBG("index %d gateway %s", index, gateway);
704 config = find_gateway(index, gateway);
706 config->active = FALSE;
708 data = find_default_gateway();
710 set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_ALL);
713 static struct connman_rtnl connection_rtnl = {
714 .name = "connection",
715 .newgateway = connection_newgateway,
716 .delgateway = connection_delgateway,
719 static struct gateway_data *find_active_gateway(void)
726 g_hash_table_iter_init(&iter, gateway_hash);
728 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
729 struct gateway_data *data = value;
731 if (data->ipv4_gateway != NULL &&
732 data->ipv4_gateway->active == TRUE)
735 if (data->ipv6_gateway != NULL &&
736 data->ipv6_gateway->active == TRUE)
743 static void update_order(void)
750 g_hash_table_iter_init(&iter, gateway_hash);
752 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
753 struct gateway_data *data = value;
755 data->order = __connman_service_get_order(data->service);
759 void __connman_connection_gateway_activate(struct connman_service *service,
760 enum connman_ipconfig_type type)
762 struct gateway_data *data = NULL;
764 data = g_hash_table_lookup(gateway_hash, service);
768 DBG("gateway %p/%p type %d", data->ipv4_gateway,
769 data->ipv6_gateway, type);
771 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
772 data->ipv4_gateway->active = TRUE;
773 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
774 data->ipv6_gateway->active = TRUE;
777 static void add_host_route(int family, int index, const char *gateway,
778 enum connman_service_type service_type)
782 if (g_strcmp0(gateway, "0.0.0.0") != 0) {
784 * We must not set route to the phy dev gateway in
785 * VPN link. The packets to VPN link might be routed
786 * back to itself and not routed into phy link gateway.
788 if (service_type != CONNMAN_SERVICE_TYPE_VPN)
789 connman_inet_add_host_route(index, gateway,
793 * Add host route to P-t-P link so that services can
794 * be moved around and we can have some link to P-t-P
795 * network (although those P-t-P links have limited
796 * usage if default route is not directed to them)
799 if (connman_inet_get_dest_addr(index, &dest) == 0) {
800 connman_inet_add_host_route(index, dest, NULL);
807 if (g_strcmp0(gateway, "::") != 0) {
808 if (service_type != CONNMAN_SERVICE_TYPE_VPN)
809 connman_inet_add_ipv6_host_route(index,
812 /* P-t-P link, add route to destination */
814 if (connman_inet_ipv6_get_dest_addr(index,
816 connman_inet_add_ipv6_host_route(index, dest,
825 int __connman_connection_gateway_add(struct connman_service *service,
827 enum connman_ipconfig_type type,
830 struct gateway_data *active_gateway = NULL;
831 struct gateway_data *new_gateway = NULL;
832 enum connman_ipconfig_type type4 = CONNMAN_IPCONFIG_TYPE_UNKNOWN,
833 type6 = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
834 enum connman_service_type service_type =
835 connman_service_get_type(service);
838 index = __connman_service_get_index(service);
841 * If gateway is NULL, it's a point to point link and the default
842 * gateway for ipv4 is 0.0.0.0 and for ipv6 is ::, meaning the
845 if (gateway == NULL && type == CONNMAN_IPCONFIG_TYPE_IPV4)
848 if (gateway == NULL && type == CONNMAN_IPCONFIG_TYPE_IPV6)
851 DBG("service %p index %d gateway %s vpn ip %s type %d",
852 service, index, gateway, peer, type);
854 new_gateway = add_gateway(service, index, gateway, type);
855 if (new_gateway == NULL)
858 active_gateway = find_active_gateway();
860 DBG("active %p index %d new %p", active_gateway,
861 active_gateway ? active_gateway->index : -1, new_gateway);
863 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
864 new_gateway->ipv4_gateway != NULL) {
865 add_host_route(AF_INET, index, gateway, service_type);
866 __connman_service_nameserver_add_routes(service,
867 new_gateway->ipv4_gateway->gateway);
868 type4 = CONNMAN_IPCONFIG_TYPE_IPV4;
871 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
872 new_gateway->ipv6_gateway != NULL) {
873 add_host_route(AF_INET6, index, gateway, service_type);
874 __connman_service_nameserver_add_routes(service,
875 new_gateway->ipv6_gateway->gateway);
876 type6 = CONNMAN_IPCONFIG_TYPE_IPV6;
879 if (service_type == CONNMAN_SERVICE_TYPE_VPN) {
881 set_vpn_routes(new_gateway, service, gateway, type, peer,
885 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
886 new_gateway->ipv4_gateway != NULL)
887 new_gateway->ipv4_gateway->vpn = FALSE;
889 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
890 new_gateway->ipv6_gateway != NULL)
891 new_gateway->ipv6_gateway->vpn = FALSE;
894 if (active_gateway == NULL) {
895 set_default_gateway(new_gateway, type);
899 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
900 new_gateway->ipv4_gateway != NULL &&
901 new_gateway->ipv4_gateway->vpn == TRUE) {
902 if (__connman_service_is_split_routing(new_gateway->service) ==
904 connman_inet_clear_gateway_address(
905 active_gateway->index,
906 active_gateway->ipv4_gateway->gateway);
909 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
910 new_gateway->ipv6_gateway != NULL &&
911 new_gateway->ipv6_gateway->vpn == TRUE) {
912 if (__connman_service_is_split_routing(new_gateway->service) ==
914 connman_inet_clear_ipv6_gateway_address(
915 active_gateway->index,
916 active_gateway->ipv6_gateway->gateway);
920 if (type4 == CONNMAN_IPCONFIG_TYPE_IPV4)
921 __connman_service_ipconfig_indicate_state(service,
922 CONNMAN_SERVICE_STATE_READY,
923 CONNMAN_IPCONFIG_TYPE_IPV4);
925 if (type6 == CONNMAN_IPCONFIG_TYPE_IPV6)
926 __connman_service_ipconfig_indicate_state(service,
927 CONNMAN_SERVICE_STATE_READY,
928 CONNMAN_IPCONFIG_TYPE_IPV6);
932 void __connman_connection_gateway_remove(struct connman_service *service,
933 enum connman_ipconfig_type type)
935 struct gateway_data *data = NULL;
936 gboolean set_default4 = FALSE, set_default6 = FALSE;
937 int do_ipv4 = FALSE, do_ipv6 = FALSE;
940 DBG("service %p type %d", service, type);
942 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
944 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
947 do_ipv4 = do_ipv6 = TRUE;
949 __connman_service_nameserver_del_routes(service, type);
951 data = g_hash_table_lookup(gateway_hash, service);
955 if (do_ipv4 == TRUE && data->ipv4_gateway != NULL)
956 set_default4 = data->ipv4_gateway->vpn;
958 if (do_ipv6 == TRUE && data->ipv6_gateway != NULL)
959 set_default6 = data->ipv6_gateway->vpn;
961 DBG("ipv4 gateway %s ipv6 gateway %s vpn %d/%d",
962 data->ipv4_gateway ? data->ipv4_gateway->gateway : "<null>",
963 data->ipv6_gateway ? data->ipv6_gateway->gateway : "<null>",
964 set_default4, set_default6);
966 if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
967 data->ipv4_gateway->vpn == TRUE && data->index >= 0)
968 connman_inet_del_host_route(data->index,
969 data->ipv4_gateway->gateway);
971 if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
972 data->ipv6_gateway->vpn == TRUE && data->index >= 0)
973 connman_inet_del_ipv6_host_route(data->index,
974 data->ipv6_gateway->gateway);
976 err = disable_gateway(data, type);
979 * We remove the service from the hash only if all the gateway
980 * settings are to be removed.
982 if (do_ipv4 == do_ipv6 ||
983 (data->ipv4_gateway != NULL && data->ipv6_gateway == NULL
984 && do_ipv4 == TRUE) ||
985 (data->ipv6_gateway != NULL && data->ipv4_gateway == NULL
988 connman_service_unref(service);
989 g_hash_table_remove(gateway_hash, service);
991 DBG("Not yet removing gw ipv4 %p/%d ipv6 %p/%d",
992 data->ipv4_gateway, do_ipv4,
993 data->ipv6_gateway, do_ipv6);
995 /* with vpn this will be called after the network was deleted,
996 * we need to call set_default here because we will not recieve any
997 * gateway delete notification.
998 * We hit the same issue if remove_gateway() fails.
1000 if (set_default4 || set_default6 || err < 0) {
1001 data = find_default_gateway();
1003 set_default_gateway(data, type);
1007 gboolean __connman_connection_update_gateway(void)
1009 struct gateway_data *default_gateway;
1010 gboolean updated = FALSE;
1011 GHashTableIter iter;
1012 gpointer value, key;
1014 if (gateway_hash == NULL)
1019 default_gateway = find_default_gateway();
1021 __connman_service_update_ordering();
1023 DBG("default %p", default_gateway);
1026 * There can be multiple active gateways so we need to
1029 g_hash_table_iter_init(&iter, gateway_hash);
1031 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1032 struct gateway_data *active_gateway = value;
1034 if (active_gateway == default_gateway)
1037 if (active_gateway->ipv4_gateway != NULL &&
1038 active_gateway->ipv4_gateway->active == TRUE) {
1040 unset_default_gateway(active_gateway,
1041 CONNMAN_IPCONFIG_TYPE_IPV4);
1045 if (active_gateway->ipv6_gateway != NULL &&
1046 active_gateway->ipv6_gateway->active == TRUE) {
1048 unset_default_gateway(active_gateway,
1049 CONNMAN_IPCONFIG_TYPE_IPV6);
1054 if (updated && default_gateway != NULL) {
1055 if (default_gateway->ipv4_gateway)
1056 set_default_gateway(default_gateway,
1057 CONNMAN_IPCONFIG_TYPE_IPV4);
1059 if (default_gateway->ipv6_gateway)
1060 set_default_gateway(default_gateway,
1061 CONNMAN_IPCONFIG_TYPE_IPV6);
1067 int __connman_connection_get_vpn_index(int phy_index)
1069 GHashTableIter iter;
1070 gpointer value, key;
1072 g_hash_table_iter_init(&iter, gateway_hash);
1074 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1075 struct gateway_data *data = value;
1077 if (data->ipv4_gateway != NULL &&
1078 data->ipv4_gateway->vpn_phy_index == phy_index)
1081 if (data->ipv6_gateway != NULL &&
1082 data->ipv6_gateway->vpn_phy_index == phy_index)
1089 int __connman_connection_init(void)
1095 gateway_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1096 NULL, remove_gateway);
1098 err = connman_rtnl_register(&connection_rtnl);
1100 connman_error("Failed to setup RTNL gateway driver");
1105 void __connman_connection_cleanup(void)
1107 GHashTableIter iter;
1108 gpointer value, key;
1112 connman_rtnl_unregister(&connection_rtnl);
1114 g_hash_table_iter_init(&iter, gateway_hash);
1116 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1117 struct gateway_data *data = value;
1119 disable_gateway(data, CONNMAN_IPCONFIG_TYPE_ALL);
1122 g_hash_table_destroy(gateway_hash);
1123 gateway_hash = NULL;