static void add_host_route(int family, int index, const char *gateway, enum connman_service_type service_type) { switch (family) { case AF_INET: if (g_strcmp0(gateway, "0.0.0.0") != 0) { /* * We must not set route to the phy dev gateway in * VPN link. The packets to VPN link might be routed * back to itself and not routed into phy link gateway. */ if (service_type != CONNMAN_SERVICE_TYPE_VPN) connman_inet_add_host_route(index, gateway, NULL); } else { /* * Add host route to P-t-P link so that services can * be moved around and we can have some link to P-t-P * network (although those P-t-P links have limited * usage if default route is not directed to them) */ char *dest; if (connman_inet_get_dest_addr(index, &dest) == 0) { connman_inet_add_host_route(index, dest, NULL); g_free(dest); } } break; case AF_INET6: if (g_strcmp0(gateway, "::") != 0) { if (service_type != CONNMAN_SERVICE_TYPE_VPN) connman_inet_add_ipv6_host_route(index, gateway, NULL); } else { /* P-t-P link, add route to destination */ char *dest; if (connman_inet_ipv6_get_dest_addr(index, &dest) == 0) { connman_inet_add_ipv6_host_route(index, dest, NULL); g_free(dest); } } break; } }
static bool wispr_route_request(const char *address, int ai_family, int if_index, gpointer user_data) { int result = -1; struct connman_wispr_portal_context *wp_context = user_data; const char *gateway; struct wispr_route *route; gateway = __connman_ipconfig_get_gateway_from_index(if_index, wp_context->type); DBG("address %s if %d gw %s", address, if_index, gateway); if (!gateway) return false; route = g_try_new0(struct wispr_route, 1); if (route == 0) { DBG("could not create struct"); return false; } switch (wp_context->type) { case CONNMAN_IPCONFIG_TYPE_IPV4: result = connman_inet_add_host_route(if_index, address, gateway); break; case CONNMAN_IPCONFIG_TYPE_IPV6: result = connman_inet_add_ipv6_host_route(if_index, address, gateway); break; case CONNMAN_IPCONFIG_TYPE_UNKNOWN: case CONNMAN_IPCONFIG_TYPE_ALL: break; } if (result < 0) { g_free(route); return false; } route->address = g_strdup(address); route->if_index = if_index; wp_context->route_list = g_slist_prepend(wp_context->route_list, route); return true; }
int __vpn_ipconfig_gateway_add(struct vpn_ipconfig *ipconfig, int family) { DBG("ipconfig %p family %d", ipconfig, family); if (!ipconfig || !ipconfig->address) return -EINVAL; DBG("family %d gw %s peer %s", family, ipconfig->address->gateway, ipconfig->address->peer); if (family == AF_INET) connman_inet_add_host_route(ipconfig->index, ipconfig->address->gateway, ipconfig->address->peer); else if (family == AF_INET6) connman_inet_add_ipv6_host_route(ipconfig->index, ipconfig->address->gateway, ipconfig->address->peer); else return -EINVAL; return 0; }
static void set_vpn_routes(struct gateway_data *new_gateway, struct connman_service *service, const char *gateway, enum connman_ipconfig_type type, const char *peer, struct gateway_data *active_gateway) { struct gateway_config *config; struct connman_ipconfig *ipconfig; char *dest; DBG("new %p service %p gw %s type %d peer %s active %p", new_gateway, service, gateway, type, peer, active_gateway); if (type == CONNMAN_IPCONFIG_TYPE_IPV4) { ipconfig = __connman_service_get_ip4config(service); config = new_gateway->ipv4_gateway; } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) { ipconfig = __connman_service_get_ip6config(service); config = new_gateway->ipv6_gateway; } else return; if (config) { int index = __connman_ipconfig_get_index(ipconfig); struct get_gateway_params *params; config->vpn = true; if (peer) config->vpn_ip = g_strdup(peer); else if (gateway) config->vpn_ip = g_strdup(gateway); params = g_try_malloc(sizeof(struct get_gateway_params)); if (!params) return; params->vpn_index = index; params->vpn_gateway = g_strdup(gateway); /* * Find the gateway that is serving the VPN link */ __connman_inet_get_route(gateway, get_gateway_cb, params); } if (!active_gateway) return; if (type == CONNMAN_IPCONFIG_TYPE_IPV4) { /* * Special route to VPN server via gateway. This * is needed so that we can access hosts behind * the VPN. The route might already exist depending * on network topology. */ if (!active_gateway->ipv4_gateway) return; DBG("active gw %s", active_gateway->ipv4_gateway->gateway); if (g_strcmp0(active_gateway->ipv4_gateway->gateway, "0.0.0.0") != 0) dest = active_gateway->ipv4_gateway->gateway; else dest = NULL; connman_inet_add_host_route(active_gateway->index, gateway, dest); } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) { if (!active_gateway->ipv6_gateway) return; DBG("active gw %s", active_gateway->ipv6_gateway->gateway); if (g_strcmp0(active_gateway->ipv6_gateway->gateway, "::") != 0) dest = active_gateway->ipv6_gateway->gateway; else dest = NULL; connman_inet_add_ipv6_host_route(active_gateway->index, gateway, dest); } }