diff options
Diffstat (limited to 'src/provider.c')
-rwxr-xr-x | src/provider.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/provider.c b/src/provider.c index c437c91b..195ae226 100755 --- a/src/provider.c +++ b/src/provider.c @@ -53,6 +53,7 @@ void __connman_provider_append_properties(struct connman_provider *provider, DBusMessageIter *iter) { const char *host, *domain, *type; + dbus_bool_t split_routing; if (!provider->driver || !provider->driver->get_property) return; @@ -72,6 +73,12 @@ void __connman_provider_append_properties(struct connman_provider *provider, if (type) connman_dbus_dict_append_basic(iter, "Type", DBUS_TYPE_STRING, &type); + + if (provider->vpn_service) { + split_routing = connman_provider_is_split_routing(provider); + connman_dbus_dict_append_basic(iter, "SplitRouting", + DBUS_TYPE_BOOLEAN, &split_routing); + } } struct connman_provider * @@ -439,6 +446,15 @@ const char *__connman_provider_get_ident(struct connman_provider *provider) return provider->identifier; } +const char * __connman_provider_get_transport_ident( + struct connman_provider *provider) +{ + if (provider && provider && provider->driver && provider->driver->get_property) + return provider->driver->get_property(provider, "Transport"); + + return NULL; +} + int connman_provider_set_string(struct connman_provider *provider, const char *key, const char *value) { @@ -607,6 +623,100 @@ void connman_provider_set_autoconnect(struct connman_provider *provider, __connman_service_save(provider->vpn_service); } +bool connman_provider_is_split_routing(struct connman_provider *provider) +{ + if (!provider || !provider->vpn_service) + return false; + + return __connman_service_is_split_routing(provider->vpn_service); +} + +int connman_provider_set_split_routing(struct connman_provider *provider, + bool split_routing) +{ + struct connman_service *service; + enum connman_ipconfig_type type; + int service_index; + int vpn_index; + bool service_split_routing; + int err = 0; + + DBG(""); + + if (!provider || !provider->vpn_service) + return -EINVAL; + + service_split_routing = __connman_service_is_split_routing( + provider->vpn_service); + + if (service_split_routing == split_routing) { + DBG("split_routing already set %s", + split_routing ? "true" : "false"); + return -EALREADY; + } + + switch (provider->family) { + case AF_INET: + type = CONNMAN_IPCONFIG_TYPE_IPV4; + break; + case AF_INET6: + type = CONNMAN_IPCONFIG_TYPE_IPV6; + break; + case AF_UNSPEC: + type = CONNMAN_IPCONFIG_TYPE_ALL; + break; + default: + type = CONNMAN_IPCONFIG_TYPE_UNKNOWN; + } + + if (!__connman_service_is_connected_state(provider->vpn_service, + type)) { + DBG("%p VPN not connected", provider->vpn_service); + goto save; + } + + vpn_index = __connman_service_get_index(provider->vpn_service); + service_index = __connman_connection_get_vpn_phy_index(vpn_index); + service = __connman_service_lookup_from_index(service_index); + if (!service) + goto save; + + if (split_routing) + err = __connman_service_move(service, provider->vpn_service, + true); + else + err = __connman_service_move(provider->vpn_service, service, + true); + + if (err) { + connman_warn("cannot move service %p and VPN %p error %d", + service, provider->vpn_service, err); + + /* + * In case of error notify vpnd about the current split routing + * state. + */ + __connman_service_split_routing_changed(provider->vpn_service); + goto out; + } + +save: + __connman_service_set_split_routing(provider->vpn_service, + split_routing); + __connman_service_save(provider->vpn_service); + +out: + return err; +} + +int connman_provider_get_family(struct connman_provider *provider) +{ + if (!provider) + return AF_UNSPEC; + + return provider->family; +} + static void unregister_provider(gpointer data) { struct connman_provider *provider = data; |