Send connman mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

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


Today's Topics:

   1. [PATCH v2 5/7] session: add source ip rule ([email protected])
   2. [PATCH v2 6/7] client: add session source ip rule
      ([email protected])
   3. [PATCH v2 7/7] doc: session multi-interface routing
      ([email protected])


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

Message: 1
Date: Tue, 17 Jan 2017 09:17:06 +0000
From: [email protected]
To: [email protected]
Subject: [PATCH v2 5/7] session: add source ip rule
Message-ID: <[email protected]>

From: Lukasz Nowak <[email protected]>

Implement an option for a session to enable packet filtering
based on interfce source ip address. This allows an application
to create a session, and direct traffic to a specific network
interface, on which the session is connected.

Applications can use bind before connect on a socket to specify
the source ip address.

This mechanism re-uses the routing table created by the session,
iproute fwmark rule, and adds a new iptables source ip rule.
---
 include/session.h |  1 +
 src/session.c     | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/include/session.h b/include/session.h
index e8d7e93..48f1510 100644
--- a/include/session.h
+++ b/include/session.h
@@ -66,6 +66,7 @@ struct connman_session_config {
        bool ecall;
        GSList *allowed_bearers;
        char *allowed_interface;
+       bool source_ip_rule;
 };
 
 typedef int (* connman_session_config_func_t) (struct connman_session *session,
diff --git a/src/session.c b/src/session.c
index 9d8f484..ad7e665 100644
--- a/src/session.c
+++ b/src/session.c
@@ -273,21 +273,33 @@ static int init_firewall_session(struct connman_session 
*session)
 {
        struct firewall_context *fw;
        int err;
+       struct connman_ipconfig *ipconfig;
+       const char *addr = NULL;
 
-       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN 
&&
+                       !session->info->config.source_ip_rule)
                return 0;
 
        DBG("");
 
+       if (session->info->config.source_ip_rule) {
+               ipconfig = __connman_service_get_ip4config(session->service);
+               if (session->policy_config->id_type == 
CONNMAN_SESSION_ID_TYPE_UNKNOWN && !ipconfig)
+                       return 0;
+       }
+
        fw = __connman_firewall_create();
        if (!fw)
                return -ENOMEM;
 
+       if (session->info->config.source_ip_rule && ipconfig) {
+               addr = __connman_ipconfig_get_local(ipconfig);
+       }
+
        err =__connman_firewall_enable_marking(fw,
                                        session->policy_config->id_type,
                                        session->policy_config->id,
-                                       NULL,
-                                       session->mark);
+                                       addr, session->mark);
        if (err < 0) {
                __connman_firewall_destroy(fw);
                return err;
@@ -314,7 +326,8 @@ static int init_routing_table(struct connman_session 
*session)
 {
        int err;
 
-       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN 
&&
+                       !session->info->config.source_ip_rule)
                return 0;
 
        DBG("");
@@ -432,6 +445,12 @@ static void cleanup_routing_table(struct connman_session 
*session)
        del_default_route(session);
 }
 
+static void update_firewall(struct connman_session *session)
+{
+       cleanup_firewall_session(session);
+       init_firewall_session(session);
+}
+
 static void update_routing_table(struct connman_session *session)
 {
        del_default_route(session);
@@ -521,6 +540,7 @@ struct creation_data {
        enum connman_session_type type;
        GSList *allowed_bearers;
        char *allowed_interface;
+       bool source_ip_rule;
 };
 
 static void cleanup_creation_data(struct creation_data *creation_data)
@@ -898,6 +918,17 @@ static void append_notify(DBusMessageIter *dict,
                info_last->config.allowed_interface = 
info->config.allowed_interface;
        }
 
+       if (session->append_all ||
+                       info->config.source_ip_rule != 
info_last->config.source_ip_rule) {
+               dbus_bool_t source_ip_rule = FALSE;
+               if (info->config.source_ip_rule)
+                       source_ip_rule = TRUE;
+               connman_dbus_dict_append_basic(dict, "SourceIPRule",
+                                               DBUS_TYPE_BOOLEAN,
+                                               &source_ip_rule);
+               info_last->config.source_ip_rule = info->config.source_ip_rule;
+       }
+
        session->append_all = false;
 }
 
@@ -918,7 +949,8 @@ static bool compute_notifiable_changes(struct 
connman_session *session)
 
        if (info->config.allowed_bearers != info_last->config.allowed_bearers ||
                        info->config.type != info_last->config.type ||
-                       info->config.allowed_interface != 
info_last->config.allowed_interface)
+                       info->config.allowed_interface != 
info_last->config.allowed_interface ||
+                       info->config.source_ip_rule != 
info_last->config.source_ip_rule)
                return true;
 
        return false;
@@ -1166,6 +1198,27 @@ static DBusMessage *change_session(DBusConnection *conn,
                        goto err;
                }
                break;
+       case DBUS_TYPE_BOOLEAN:
+               if (g_str_equal(name, "SourceIPRule")) {
+                       dbus_bool_t source_ip_rule;
+                       dbus_message_iter_get_basic(&value, &source_ip_rule);
+
+                       cleanup_firewall_session(session);
+                       cleanup_routing_table(session);
+
+                       info->config.source_ip_rule = source_ip_rule;
+                       update_session_state(session);
+
+                       init_routing_table(session);
+                       err = init_firewall_session(session);
+                       if (err < 0) {
+                               connman_session_destroy(session);
+                               goto err;
+                       }
+               } else {
+                       goto err;
+               }
+               break;
        default:
                goto err;
        }
@@ -1267,6 +1320,7 @@ static int session_policy_config_cb(struct 
connman_session *session,
                goto err;
 
        session->policy_config = config;
+       session->info->config.source_ip_rule = creation_data->source_ip_rule;
 
        session->mark = session_mark++;
        session->index = -1;
@@ -1332,6 +1386,7 @@ static int session_policy_config_cb(struct 
connman_session *session,
        info_last->config.roaming_policy = info->config.roaming_policy;
        info_last->config.allowed_bearers = info->config.allowed_bearers;
        info_last->config.allowed_interface = info->config.allowed_interface;
+       info_last->config.source_ip_rule = info->config.source_ip_rule;
 
        session->append_all = true;
 
@@ -1426,7 +1481,21 @@ int __connman_session_create(DBusMessage *msg)
                                err = -EINVAL;
                                goto err;
                        }
+                       break;
+               case DBUS_TYPE_BOOLEAN:
+                       if (g_str_equal(key, "SourceIPRule")) {
+                               dbus_bool_t source_ip_rule;
+                               dbus_message_iter_get_basic(&value, 
&source_ip_rule);
+                               creation_data->source_ip_rule = source_ip_rule;
+                       } else {
+                               err = -EINVAL;
+                               goto err;
+                       }
+                       break;
+               default:
+                       goto err;
                }
+
                dbus_message_iter_next(&array);
        }
 
@@ -1610,6 +1679,7 @@ static void update_session_state(struct connman_session 
*session)
 
        DBG("session %p state %s", session, state2string(state));
 
+       update_firewall(session);
        update_routing_table(session);
        update_nat_rules(session);
        session_notify(session);
-- 
2.7.4



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

Message: 2
Date: Tue, 17 Jan 2017 09:17:07 +0000
From: [email protected]
To: [email protected]
Subject: [PATCH v2 6/7] client: add session source ip rule
Message-ID: <[email protected]>

From: Lukasz Nowak <[email protected]>

Add a session config field to enable/disable creation of the
source ip rule in iptables by a session.
---
 client/commands.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/client/commands.c b/client/commands.c
index c41e9b4..583095b 100644
--- a/client/commands.c
+++ b/client/commands.c
@@ -1897,6 +1897,7 @@ static int session_config(char *args[], int num,
        struct config_append append;
        char c;
        char *ifname;
+       dbus_bool_t source_ip_rule;
 
        while (index < num && args[index]) {
                append.opts = &args[index];
@@ -1935,6 +1936,29 @@ static int session_config(char *args[], int num,
                                        DBUS_TYPE_STRING, &ifname);
                        append.values = 2;
                        break;
+               case 's':
+                       if (!args[index + 1]) {
+                               res = -EINVAL;
+                               break;
+                       }
+                       switch (parse_boolean(args[index + 1])) {
+                       case 1:
+                               source_ip_rule = TRUE;
+                               break;
+                       case 0:
+                               source_ip_rule = FALSE;
+                               break;
+                       default:
+                               res = -EINVAL;
+                               break;
+                       }
+
+                       res = __connmanctl_dbus_session_change(connection,
+                                       session_path, session_config_return,
+                                       "SourceIPRule", "SourceIPRule",
+                                       DBUS_TYPE_BOOLEAN, &source_ip_rule);
+                       append.values = 2;
+                       break;
 
                default:
                        res = -EINVAL;
@@ -2223,6 +2247,7 @@ static struct connman_option session_options[] = {
        {"bearers", 'b', "<technology1> [<technology2> [...]]"},
        {"type", 't', "local|internet|any"},
        {"ifname", 'i', "[<interface_name>]"},
+       {"srciprule", 's', "yes|no"},
        { NULL, }
 };
 
-- 
2.7.4



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

Message: 3
Date: Tue, 17 Jan 2017 09:17:08 +0000
From: [email protected]
To: [email protected]
Subject: [PATCH v2 7/7] doc: session multi-interface routing
Message-ID: <[email protected]>

From: Lukasz Nowak <[email protected]>

Update session overview and API documents to demonstrate how sessions
can be used to maintain multiple connections in parallel.
---
 doc/session-api.txt      | 22 ++++++++++++++++++++++
 doc/session-overview.txt | 31 +++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/doc/session-api.txt b/doc/session-api.txt
index 3aac535..42766e7 100644
--- a/doc/session-api.txt
+++ b/doc/session-api.txt
@@ -182,3 +182,25 @@ Settings   string State [readonly]
                        (This setting will be removed when the unique process
                        identification problem is solved.)
 
+               string AllowedInterface [readwrite]
+
+                       This field is used to bind a session to a specific
+                       network interface. If this field is empty, the first
+                       interface from a list of available ones will be used.
+
+                       Only one interface may be specified.
+
+                       If a specified network interface is not available
+                       (e.g. because AllowedBearers filters it out), the
+                       session will not go online.
+
+               boolean SourceIPRule [readwrite]
+
+                       If set to true the session will create source ip
+                       address rule in the firewall, which redirects traffic
+                       to that session's routing table.
+
+                       Each session maintains a dedicated routing table, with
+                       a default route. When the source ip rule is enabled,
+                       an application can select which session/interface to
+                       send traffic on, using bind-before-connect mechanism.
diff --git a/doc/session-overview.txt b/doc/session-overview.txt
index 2393167..a18600d 100644
--- a/doc/session-overview.txt
+++ b/doc/session-overview.txt
@@ -92,3 +92,34 @@ The default session configuration does not enable the per 
application
 routing. Sessions are still useful in this setup, because the
 notification of sessions is still available, e.g. the online/offline
 notification.
+
+
+Multiple per-session routing tables
+===================================
+
+Sessions can be used in an environment with multiple network interfaces,
+where an application needs to direct outside traffic through a selected
+interface(s). Connman can maintain multiple sessions in a connected
+stated, and the application can dynamically, on a per-socket basis,
+select which session is used to route traffic.
+
+Example use cases are:
+- monitoring liveness of multiple connected interfaces, by sending
+  end-to-end heartbeat traffic on all of them in parallel.
+- prioritising traffic - e.g. sensitive data can be transferred over a slow,
+  but secure connection, while big, public downloads use a second session
+
+By default, Connman maintains only one online service. So it is impossible
+to send external traffic (routed through a gateway) on multiple interfaces.
+In order to enable this functionality, an application needs to issue the
+following API calls:
+- create multiple sessions, one for each interface to be used
+- set each session's AllowedInterface config field to the required interface
+  name (eth0, eth1, wlan0, ppp0, etc.)
+- set each session's SourceIPRule config field to true
+- connect each session (or the service it is using)
+
+That will instruct Connman to create multiple routing tables, with default
+routes in them. After that, the application can issue a bind() call on each
+socket, using required interface's source IP address. The bind() call must
+be made before a connect() call on a socket.
-- 
2.7.4



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

Subject: Digest Footer

_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman


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

End of connman Digest, Vol 15, Issue 18
***************************************

Reply via email to