Send connman mailing list submissions to
        connman@lists.01.org

To subscribe or unsubscribe via email, send a message with subject or
body 'help' to
        connman-requ...@lists.01.org

You can reach the person managing the list at
        connman-ow...@lists.01.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."

Today's Topics:

   1. [PATCH 4/6] vpn-config: Implement function to get boolean from keyfile
      (Jussi Laakkonen)
   2. [PATCH 5/6] vpn-provider: Support split routing option for VPN providers
      (Jussi Laakkonen)
   3. [PATCH 6/6] doc: Document VPN connection SplitRouting boolean
      (Jussi Laakkonen)
   4. Re: Associating with AP without obtaining an address
      (Daniel Wagner)
   5. Re: Default route per interface (Daniel Wagner)
   6. Re: [PATCH] iptables: Fix incorrect code (Daniel Wagner)


----------------------------------------------------------------------

Date: Thu, 17 Sep 2020 18:37:14 +0300
From: Jussi Laakkonen <jussi.laakko...@jolla.com>
Subject: [PATCH 4/6] vpn-config: Implement function to get boolean
        from keyfile
To: connman@lists.01.org
Message-ID: <20200917153716.26799-5-jussi.laakko...@jolla.com>

Simple boolean getter for VPN keyfiles. In case of error (key missing or
invalid boolean) the default value given is returned.
---
 vpn/vpn-config.c | 15 +++++++++++++++
 vpn/vpn.h        | 10 ++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/vpn/vpn-config.c b/vpn/vpn-config.c
index 34a1144d..a4e2e0e5 100644
--- a/vpn/vpn-config.c
+++ b/vpn/vpn-config.c
@@ -580,3 +580,18 @@ char **__vpn_config_get_string_list(GKeyFile *key_file,
 
        return strlist;
 }
+
+bool __vpn_config_get_boolean(GKeyFile *key_file, const char *group_name,
+                       const char *key, bool default_value)
+{
+       GError *error = NULL;
+       bool val;
+
+       val = g_key_file_get_boolean(key_file, group_name, key, &error);
+       if (error) {
+               g_error_free(error);
+               return default_value;
+       }
+
+       return val;
+}
diff --git a/vpn/vpn.h b/vpn/vpn.h
index 45cf46dc..994dcf31 100644
--- a/vpn/vpn.h
+++ b/vpn/vpn.h
@@ -112,10 +112,12 @@ int __vpn_rtnl_send(const void *buf, size_t len);
 
 int __vpn_config_init(void);
 void __vpn_config_cleanup(void);
-char *__vpn_config_get_string(GKeyFile *key_file,
-        const char *group_name, const char *key, GError **error);
-char **__vpn_config_get_string_list(GKeyFile *key_file,
-        const char *group_name, const char *key, gsize *length, GError 
**error);
+char *__vpn_config_get_string(GKeyFile *key_file, const char *group_name,
+                                       const char *key, GError **error);
+char **__vpn_config_get_string_list(GKeyFile *key_file, const char *group_name,
+                       const char *key, gsize *length, GError **error);
+bool __vpn_config_get_boolean(GKeyFile *key_file, const char *group_name,
+                       const char *key, bool default_value);
 
 int __vpn_settings_init(const char *file);
 void __vpn_settings_cleanup(void);
-- 
2.20.1

------------------------------

Date: Thu, 17 Sep 2020 18:37:15 +0300
From: Jussi Laakkonen <jussi.laakko...@jolla.com>
Subject: [PATCH 5/6] vpn-provider: Support split routing option for
        VPN providers
To: connman@lists.01.org
Message-ID: <20200917153716.26799-6-jussi.laakko...@jolla.com>

Support SplitRouting option in vpnd as well. The value is passed as
boolean, and read from the settings file as boolean. A warning is
printed with invalid error if attempted to be set as string. For this,
vpn_provider_set_boolean() is added.

In addition handling of default route for VPNs is improved with checks
for split routing and already set route. This is to ensure that if a
non-split routed VPN does not have default route set in the routes it
should be added in order to guarantee that traffic is routed over the
VPN. This check is done also in provider_append_routes() to track if the
default route is included in the provided routes.
---
 vpn/vpn-provider.c | 182 +++++++++++++++++++++++++++++++++++++++------
 vpn/vpn-provider.h |   2 +
 2 files changed, 161 insertions(+), 23 deletions(-)

diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index bf20ed6e..2141a62b 100644
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -45,6 +45,7 @@ static GHashTable *provider_hash;
 static GSList *driver_list;
 static int configuration_count;
 static bool handle_routes;
+static bool default_route_set = false;
 
 struct vpn_route {
        int family;
@@ -71,6 +72,7 @@ struct vpn_provider {
        char *host;
        char *domain;
        int family;
+       bool do_split_routing;
        GHashTable *routes;
        struct vpn_provider_driver *driver;
        void *driver_data;
@@ -116,6 +118,24 @@ static void free_setting(gpointer data)
        g_free(setting);
 }
 
+#define BOOLSTR_TRUE "true"
+#define BOOLSTR_FALSE "false"
+
+static const char *bool2str(bool value)
+{
+       return value ? BOOLSTR_TRUE : BOOLSTR_FALSE;
+}
+
+static bool provider_is_split_routing(struct vpn_provider *provider)
+{
+       if (!provider)
+               return false;
+
+       DBG("%s", bool2str(provider->do_split_routing));
+
+       return provider->do_split_routing;
+}
+
 static void append_route(DBusMessageIter *iter, void *user_data)
 {
        struct vpn_route *route = user_data;
@@ -404,6 +424,16 @@ static void send_value(const char *path, const char *key, 
const char *value)
                                        &str);
 }
 
+static void send_value_boolean(const char *path, const char *key,
+                                                       dbus_bool_t value)
+{
+       connman_dbus_property_changed_basic(path,
+                                       VPN_CONNECTION_INTERFACE,
+                                       key,
+                                       DBUS_TYPE_BOOLEAN,
+                                       &value);
+}
+
 static gboolean provider_send_changed(gpointer data)
 {
        struct vpn_provider *provider = data;
@@ -504,6 +534,16 @@ static int set_provider_property(struct vpn_provider 
*provider,
                if (!handle_routes)
                        send_routes(provider, provider->user_routes,
                                                "UserRoutes");
+       } else if (g_str_equal(name, "SplitRouting")) {
+               dbus_bool_t split_routing;
+
+               if (type != DBUS_TYPE_BOOLEAN)
+                       return -EINVAL;
+
+               dbus_message_iter_get_basic(value, &split_routing);
+
+               DBG("property %s value %s ", name, bool2str(split_routing));
+               vpn_provider_set_boolean(provider, name, split_routing);
        } else {
                const char *str;
 
@@ -576,8 +616,13 @@ static DBusMessage *set_properties(DBusMessageIter *iter, 
DBusMessage *msg,
                dbus_message_iter_recurse(&entry, &value);
 
                type = dbus_message_iter_get_arg_type(&value);
-               /* Ignore and report back all invalid property types */
-               if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_ARRAY) {
+               switch (type) {
+               case DBUS_TYPE_STRING:
+               case DBUS_TYPE_ARRAY:
+               case DBUS_TYPE_BOOLEAN:
+                       break;
+               default:
+                       /* Ignore and report back all invalid property types */
                        invalid = append_to_gstring(invalid, key);
                        continue;
                }
@@ -841,6 +886,8 @@ static void provider_resolv_host_addr(struct vpn_provider 
*provider)
 void __vpn_provider_append_properties(struct vpn_provider *provider,
                                                        DBusMessageIter *iter)
 {
+       dbus_bool_t split_routing;
+
        if (provider->host)
                connman_dbus_dict_append_basic(iter, "Host",
                                        DBUS_TYPE_STRING, &provider->host);
@@ -852,6 +899,10 @@ void __vpn_provider_append_properties(struct vpn_provider 
*provider,
        if (provider->type)
                connman_dbus_dict_append_basic(iter, "Type", DBUS_TYPE_STRING,
                                                 &provider->type);
+
+       split_routing = provider->do_split_routing;
+       connman_dbus_dict_append_basic(iter, "SplitRouting", DBUS_TYPE_BOOLEAN,
+                                                       &split_routing);
 }
 
 int __vpn_provider_append_user_route(struct vpn_provider *provider,
@@ -984,7 +1035,7 @@ static GSList *get_routes(gchar **networks)
 static int provider_load_from_keyfile(struct vpn_provider *provider,
                GKeyFile *keyfile)
 {
-       gsize idx = 0;
+       gsize idx;
        gchar **settings;
        gchar *key, *value;
        gsize length, num_user_networks;
@@ -997,28 +1048,32 @@ static int provider_load_from_keyfile(struct 
vpn_provider *provider,
                return -ENOENT;
        }
 
-       while (idx < length) {
+       for (idx = 0; idx < length; idx++) {
                key = settings[idx];
-               if (key) {
-                       if (g_str_equal(key, "Networks")) {
-                               networks = __vpn_config_get_string_list(keyfile,
-                                               provider->identifier,
-                                               key,
-                                               &num_user_networks,
+               if (!key)
+                       continue;
+
+               if (g_str_equal(key, "Networks")) {
+                       networks = __vpn_config_get_string_list(keyfile,
+                                               provider->identifier,key,
+                                               &num_user_networks, NULL);
+                       provider->user_networks = get_routes(networks);
+               } else if (g_str_equal(key, "SplitRouting")) {
+                       bool value = __vpn_config_get_boolean(keyfile,
+                                               provider->identifier, key,
+                                               false);
+                       vpn_provider_set_boolean(provider, key, value);
+                       DBG("%s SplitRouting %s", provider->identifier,
+                                               bool2str(value));
+               } else {
+                       value = __vpn_config_get_string(keyfile,
+                                               provider->identifier, key,
                                                NULL);
-                               provider->user_networks = get_routes(networks);
-
-                       } else {
-                               value = __vpn_config_get_string(keyfile,
-                                                       provider->identifier,
-                                                       key, NULL);
-                               vpn_provider_set_string(provider, key,
-                                                       value);
-                               g_free(value);
-                       }
+                       vpn_provider_set_string(provider, key, value);
+                       g_free(value);
                }
-               idx += 1;
        }
+
        g_strfreev(settings);
        g_strfreev(networks);
 
@@ -1135,6 +1190,9 @@ static int vpn_provider_save(struct vpn_provider 
*provider)
                        "Host", provider->host);
        g_key_file_set_string(keyfile, provider->identifier,
                        "VPN.Domain", provider->domain);
+       g_key_file_set_boolean(keyfile, provider->identifier,
+                       "SplitRouting", provider->do_split_routing);
+
        if (provider->user_networks) {
                gchar **networks;
                gsize network_count;
@@ -1725,6 +1783,7 @@ static void append_properties(DBusMessageIter *iter,
        GHashTableIter hash;
        gpointer value, key;
        dbus_bool_t immutable;
+       dbus_bool_t split_routing;
 
        connman_dbus_dict_open(iter, &dict);
 
@@ -1752,6 +1811,10 @@ static void append_properties(DBusMessageIter *iter,
        connman_dbus_dict_append_basic(&dict, "Immutable", DBUS_TYPE_BOOLEAN,
                                        &immutable);
 
+       split_routing = provider->do_split_routing;
+       connman_dbus_dict_append_basic(&dict, "SplitRouting",
+                                       DBUS_TYPE_BOOLEAN, &split_routing);
+
        if (provider->family == AF_INET)
                connman_dbus_dict_append_dict(&dict, "IPv4", append_ipv4,
                                                provider);
@@ -1776,8 +1839,7 @@ static void append_properties(DBusMessageIter *iter,
                while (g_hash_table_iter_next(&hash, &key, &value)) {
                        struct vpn_setting *setting = value;
 
-                       if (!setting->hide_value &&
-                                                       setting->value)
+                       if (!setting->hide_value && setting->value)
                                connman_dbus_dict_append_basic(&dict, key,
                                                        DBUS_TYPE_STRING,
                                                        &setting->value);
@@ -1842,6 +1904,21 @@ static void provider_append_routes(gpointer key, 
gpointer value,
                return;
        }
 
+       /*
+        * Default route is being added only when network and netmask are
+        * INADDR_ANY and gateway is NULL. Split routed providers do not have
+        * a default route set.
+        */
+       if (__connman_inet_is_any_addr(route->network, provider->family) &&
+                               __connman_inet_is_any_addr(
+                                       route->netmask, provider->family) &&
+                               !route->gateway) {
+               if (provider_is_split_routing(provider))
+                       return;
+
+               default_route_set = true;
+       }
+
        if (route->family == AF_INET6) {
                unsigned char prefix_len = atoi(route->netmask);
 
@@ -1859,10 +1936,14 @@ static int set_connected(struct vpn_provider *provider,
                                        bool connected)
 {
        struct vpn_ipconfig *ipconfig;
+       const gchar *ipaddr_any = provider->family == AF_INET6 ?
+                                                       "::" : "0.0.0.0";
 
        DBG("provider %p id %s connected %d", provider,
                                        provider->identifier, connected);
 
+       default_route_set = false;
+
        if (connected) {
                if (provider->family == AF_INET6)
                        ipconfig = provider->ipconfig_ipv6;
@@ -1883,6 +1964,28 @@ static int set_connected(struct vpn_provider *provider,
                g_hash_table_foreach(provider->user_routes,
                                        provider_append_routes, provider);
 
+               /*
+                * This is for cases when the VPN should be the default route
+                * but the default route is not provided in the routes.
+                *
+                * Do not set default route if the provider is set to be split
+                * routed or default route has been already set.
+               */
+               if (provider_is_split_routing(provider) || default_route_set)
+                       return 0;
+
+               DBG("Adding default route for provider %p", provider);
+
+               /*
+                * In routing IPv6 any (::) address prefix is 0
+                * http://www.tldp.org/HOWTO/Linux+IPv6-HOWTO/
+                */
+               if (provider->family == AF_INET6)
+                       connman_inet_add_ipv6_network_route(provider->index,
+                                               ipaddr_any, NULL, 0);
+               else
+                       connman_inet_add_network_route(provider->index,
+                                               ipaddr_any, NULL, ipaddr_any);
        } else {
                provider_indicate_state(provider,
                                        VPN_PROVIDER_STATE_DISCONNECT);
@@ -2017,6 +2120,7 @@ static void provider_initialize(struct vpn_provider 
*provider)
        provider->domain = NULL;
        provider->identifier = NULL;
        provider->immutable = false;
+       provider->do_split_routing = false;
        provider->user_networks = NULL;
        provider->routes = g_hash_table_new_full(g_direct_hash, g_direct_equal,
                                        NULL, free_route);
@@ -2185,6 +2289,7 @@ int __vpn_provider_create(DBusMessage *msg)
        GSList *networks = NULL;
        char *ident;
        int err;
+       dbus_bool_t split_routing = false;
 
        dbus_message_iter_init(msg, &iter);
        dbus_message_iter_recurse(&iter, &array);
@@ -2211,6 +2316,11 @@ int __vpn_provider_create(DBusMessage *msg)
                                        g_str_equal(key, "Domain"))
                                dbus_message_iter_get_basic(&value, &domain);
                        break;
+               case DBUS_TYPE_BOOLEAN:
+                       if (g_str_equal(key, "SplitRouting"))
+                               dbus_message_iter_get_basic(&value,
+                                                       &split_routing);
+                       break;
                case DBUS_TYPE_ARRAY:
                        if (g_str_equal(key, "UserRoutes"))
                                networks = get_user_networks(&value);
@@ -2244,6 +2354,7 @@ int __vpn_provider_create(DBusMessage *msg)
                provider->domain = g_strdup(domain);
                provider->name = g_strdup(name);
                provider->type = g_strdup(type);
+               provider->do_split_routing = split_routing;
 
                if (provider_register(provider) == 0)
                        vpn_provider_load(provider);
@@ -2392,6 +2503,7 @@ int __vpn_provider_create_from_config(GHashTable 
*settings,
 {
        struct vpn_provider *provider;
        const char *type, *name, *host, *domain, *networks_str;
+       bool split_routing;
        GSList *networks;
        char *ident = NULL;
        GHashTableIter hash;
@@ -2404,6 +2516,8 @@ int __vpn_provider_create_from_config(GHashTable 
*settings,
        domain = get_string(settings, "Domain");
        networks_str = get_string(settings, "Networks");
        networks = parse_user_networks(networks_str);
+       split_routing = !g_strcmp0(get_string(settings, "SplitRouting"),
+                                                               "true");
 
        if (!host) {
                err = -EINVAL;
@@ -2433,6 +2547,7 @@ int __vpn_provider_create_from_config(GHashTable 
*settings,
                provider->domain = g_strdup(domain);
                provider->name = g_strdup(name);
                provider->type = g_ascii_strdown(type, -1);
+               provider->do_split_routing = split_routing;
 
                provider->config_file = g_strdup(config_ident);
                provider->config_entry = g_strdup(config_entry);
@@ -2564,6 +2679,10 @@ static int set_string(struct vpn_provider *provider,
                g_free(provider->domain);
                provider->domain = g_strdup(value);
                send_value(provider->path, "Domain", provider->domain);
+       } else if (g_str_equal(key, "SplitRouting")) {
+               connman_warn("VPN SplitRouting value attempted to set as "
+                                       "string, is boolean");
+               return -EINVAL;
        } else {
                struct vpn_setting *setting;
                bool replace = true;
@@ -2650,6 +2769,23 @@ const char *vpn_provider_get_string(struct vpn_provider 
*provider,
        return setting->value;
 }
 
+int vpn_provider_set_boolean(struct vpn_provider *provider, const char *key,
+                                                       bool value)
+{
+       if (g_str_equal(key, "SplitRouting")) {
+               if (provider->do_split_routing == value)
+                       return -EALREADY;
+
+               DBG("SplitRouting set to %s", bool2str(value));
+
+               provider->do_split_routing = value;
+               send_value_boolean(provider->path, key,
+                                       provider->do_split_routing);
+       }
+
+       return 0;
+}
+
 bool vpn_provider_get_boolean(struct vpn_provider *provider, const char *key,
                                                        bool default_value)
 {
diff --git a/vpn/vpn-provider.h b/vpn/vpn-provider.h
index 0275d51a..3fb6d64f 100644
--- a/vpn/vpn-provider.h
+++ b/vpn/vpn-provider.h
@@ -83,6 +83,8 @@ const char *vpn_provider_get_string(struct vpn_provider 
*provider,
                                                        const char *key);
 bool vpn_provider_get_string_immutable(struct vpn_provider *provider,
                                                        const char *key);
+int vpn_provider_set_boolean(struct vpn_provider *provider, const char *key,
+                                                       bool value);
 bool vpn_provider_get_boolean(struct vpn_provider *provider, const char *key,
                                                        bool default_value);
 
-- 
2.20.1

------------------------------

Date: Thu, 17 Sep 2020 18:37:16 +0300
From: Jussi Laakkonen <jussi.laakko...@jolla.com>
Subject: [PATCH 6/6] doc: Document VPN connection SplitRouting boolean
To: connman@lists.01.org
Message-ID: <20200917153716.26799-7-jussi.laakko...@jolla.com>

---
 doc/vpn-connection-api.txt | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/doc/vpn-connection-api.txt b/doc/vpn-connection-api.txt
index ec557889..ba7feaa5 100644
--- a/doc/vpn-connection-api.txt
+++ b/doc/vpn-connection-api.txt
@@ -130,7 +130,14 @@ Properties string State [readonly]
                        configured externally via a configuration file.
 
                        The only valid operation are Connect(), Disconnect()
-                        and GetProperties()
+                       and GetProperties()
+
+               boolean SplitRouting
+
+                       This value reflects the split routing setting on
+                       connmand side. The value defaults to false and needs
+                       to be explicitly set to true for the VPN to be split
+                       routed.
 
                int Index [readonly]
 
-- 
2.20.1

------------------------------

Date: Thu, 17 Sep 2020 19:29:31 +0200
From: Daniel Wagner <w...@monom.org>
Subject: Re: Associating with AP without obtaining an address
To: gergely.fe...@xaptum.com
Cc: connman@lists.01.org
Message-ID: <20200917172931.m6uandxnkpkl5...@beryllium.lan>
Content-Type: text/plain; charset=utf-8

Hi,

On Wed, Sep 09, 2020 at 04:24:01PM -0000, gergely.fe...@xaptum.com wrote:
> Is there a way of using connman to associate a device with an access
> point without it running DHCP or explicitly setting an address?
>
> I was able to do this with wpa_supplicant - because it doesn’t
> explicitly run the dhcp client, but I haven’t figured out how to do it
> with connman.
>
> For those that may be asking why I would want to do this:
> I have an embedded device attached to a host.  The embedded device has
> onboard wifi and the host uses the device for network connections.  In
> mode 1, the device takes care of everything - we run connman & dhcp on
> the device.  In mode 2, the host treats the device as a dumb network
> device and runs dhcp client on the host.  We bridge the connection on
> the device, so all the device has to do is associate with the access
> point.


No, ConnMan abstracts all devices into technologies which are controlled
as one unit. It's a short coming which prevents use cases as you
described. If you just need WiFi you might want to look running iwd
standalone. I think iwd would allow this scenario.

Thanks,
Daniel

------------------------------

Date: Thu, 17 Sep 2020 19:35:57 +0200
From: Daniel Wagner <w...@monom.org>
Subject: Re: Default route per interface
To: c.stei...@lemonage.de
Cc: connman@lists.01.org
Message-ID: <20200917173557.t5y3imisqmpg5...@beryllium.lan>
Content-Type: text/plain; charset=us-ascii

Hi,

On Fri, Sep 11, 2020 at 09:01:32AM +0200, c.stei...@lemonage.de wrote:
> We have a setup with a wired and cellular connection. The wired connection
> has access to the internet, the cellular one to a 10.0.0.0/8 network. We
> would like to have both interfaces up at the same time, with the wired
> connection getting the default route and the cellular getting a route to its
> network. But when connman manages both connections, the cellular also gets a
> default route. Is there an easy way to configure a different 'default' route
> per interface? Would the sessions API help here?

Yes, the Session API allows to get an per application routing table. The
will be still a global default routing table, but for any application
which marks the network packets will be using the policy routing tables.

Thanks,
Daniel

------------------------------

Date: Thu, 17 Sep 2020 19:45:47 +0200
From: Daniel Wagner <w...@monom.org>
Subject: Re: [PATCH] iptables: Fix incorrect code
To: Rahul Jain <rahul.j...@samsung.com>
Cc: "connman@lists.01.org" <connman@lists.01.org>, AMIT KUMAR JAISWAL
        <amit.jais...@samsung.com>, Bhaskar Dutta <bhaska...@samsung.com>,
        Sheetal Arya <sheetal.a...@samsung.com>
Message-ID: <20200917174547.irnphwozsjgqm...@beryllium.lan>
Content-Type: text/plain; charset=us-ascii

On Tue, Aug 04, 2020 at 04:48:16PM +0530, Rahul Jain wrote:
> [PATCH] iptables: Fix incorrect code

Patch applied. I added a commit message.

> Signed-off-by: Bhaskar Dutta <bhaska...@samsung.com>
> Signed-off-by: Rahul Jain <rahul.j...@samsung.com>

We don't do the SoB, thus I dropped those.

Thanks,
Daniel

------------------------------

Subject: Digest Footer

_______________________________________________
connman mailing list -- connman@lists.01.org
To unsubscribe send an email to connman-le...@lists.01.org


------------------------------

End of connman Digest, Vol 59, Issue 16
***************************************

Reply via email to