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 0/7] session: add per-interface routing
([email protected])
2. [PATCH v2 1/7] session: fix default route for ppp services
([email protected])
3. [PATCH v2 2/7] session: add allowed interface config
parameter ([email protected])
4. [PATCH v2 3/7] client: add session allowed interface config
([email protected])
5. [PATCH v2 4/7] firewall: add fwmark based on source ip
address ([email protected])
----------------------------------------------------------------------
Message: 1
Date: Tue, 17 Jan 2017 09:17:01 +0000
From: [email protected]
To: [email protected]
Subject: [PATCH v2 0/7] session: add per-interface routing
Message-ID: <[email protected]>
From: Lukasz Nowak <[email protected]>
changes from v1:
- added documentation
- split firewall and session changes into separate commits
- cosmetic updates after v1 review
Adding a new feature to the sessions, which allows applications to direct
routed traffic to a specific network interface.
This requires that multiple default routes with gateways are set up, one
for each interface. And then iproute and iptables rules need to be added
to direct traffic based on source ip address, to the correct routing table.
Applications can use bind before connect mechanism, to bind sockets to
required interfaces.
The application side can be tested with:
ping -I <interface_ip> <target_ip>
Use case for this is to have multiple network interfaces available for
external traffic at the same time. It can be used to validate that a full
path to an external server is working properly, by maintaining multiple
tcp connections, one for each interface.
Lukasz Nowak (7):
session: fix default route for ppp services
session: add allowed interface config parameter
client: add session allowed interface config
firewall: add fwmark based on source ip address
session: add source ip rule
client: add session source ip rule
doc: session multi-interface routing
client/commands.c | 39 ++++++++++++
doc/session-api.txt | 22 +++++++
doc/session-overview.txt | 31 +++++++++
include/session.h | 2 +
src/connman.h | 3 +-
src/firewall-iptables.c | 11 +++-
src/firewall-nftables.c | 5 +-
src/session.c | 161 +++++++++++++++++++++++++++++++++++++++++++++--
8 files changed, 264 insertions(+), 10 deletions(-)
--
2.7.4
------------------------------
Message: 2
Date: Tue, 17 Jan 2017 09:17:02 +0000
From: [email protected]
To: [email protected]
Subject: [PATCH v2 1/7] session: fix default route for ppp services
Message-ID: <[email protected]>
From: Lukasz Nowak <[email protected]>
When a session is connected to a ppp service, ipconfig
will not contain a gateway IP address. Currently setting up
of the session routing table fails, due to
__connman_inet_add_default_to_table returning an error.
In that scenario, INADDR_ANY needs to be used as a gateway.
---
src/session.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/session.c b/src/session.c
index b1e9e1b..09fc7c3 100644
--- a/src/session.c
+++ b/src/session.c
@@ -351,6 +351,7 @@ static void add_default_route(struct connman_session
*session)
{
struct connman_ipconfig *ipconfig;
int err;
+ struct in_addr addr = { INADDR_ANY };
if (!session->service)
return;
@@ -359,6 +360,9 @@ static void add_default_route(struct connman_session
*session)
session->index = __connman_ipconfig_get_index(ipconfig);
session->gateway = g_strdup(__connman_ipconfig_get_gateway(ipconfig));
+ if (!session->gateway)
+ session->gateway = g_strdup(inet_ntoa(addr));
+
DBG("index %d routing table %d default gateway %s",
session->index, session->mark, session->gateway);
--
2.7.4
------------------------------
Message: 3
Date: Tue, 17 Jan 2017 09:17:03 +0000
From: [email protected]
To: [email protected]
Subject: [PATCH v2 2/7] session: add allowed interface config
parameter
Message-ID: <[email protected]>
From: Lukasz Nowak <[email protected]>
In order to be able to bind a session to a specific interface,
a config option has been added. It is supported through both
dbus and session policy. Policy always overrides dbus.
This is the first step to implement per-interface routing.
Next step will be to add src ip rules to iptables, which
will allow the application to transmit through multiple
interfaces.
---
include/session.h | 1 +
src/session.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/include/session.h b/include/session.h
index 37dfc4e..e8d7e93 100644
--- a/include/session.h
+++ b/include/session.h
@@ -65,6 +65,7 @@ struct connman_session_config {
enum connman_session_type type;
bool ecall;
GSList *allowed_bearers;
+ char *allowed_interface;
};
typedef int (* connman_session_config_func_t) (struct connman_session *session,
diff --git a/src/session.c b/src/session.c
index 09fc7c3..2dfd428 100644
--- a/src/session.c
+++ b/src/session.c
@@ -63,6 +63,7 @@ struct connman_session {
struct connman_service *service_last;
struct connman_session_config *policy_config;
GSList *user_allowed_bearers;
+ char *user_allowed_interface;
bool ecall;
@@ -467,6 +468,7 @@ static void free_session(struct connman_session *session)
destroy_policy_config(session);
g_slist_free(session->info->config.allowed_bearers);
+ g_free(session->info->config.allowed_interface);
g_free(session->owner);
g_free(session->session_path);
g_free(session->notify_path);
@@ -505,6 +507,7 @@ static void cleanup_session(gpointer user_data)
update_session_state(session);
g_slist_free(session->user_allowed_bearers);
+ g_free(session->user_allowed_interface);
free_session(session);
}
@@ -516,6 +519,7 @@ struct creation_data {
/* user config */
enum connman_session_type type;
GSList *allowed_bearers;
+ char *allowed_interface;
};
static void cleanup_creation_data(struct creation_data *creation_data)
@@ -527,6 +531,7 @@ static void cleanup_creation_data(struct creation_data
*creation_data)
dbus_message_unref(creation_data->pending);
g_slist_free(creation_data->allowed_bearers);
+ g_free(creation_data->allowed_interface);
g_free(creation_data);
}
@@ -725,6 +730,17 @@ static void apply_policy_on_bearers(GSList
*policy_bearers, GSList *bearers,
}
}
+static char * apply_policy_on_interface(const char *policy_interface,
+ const char *user_interface)
+{
+ if (policy_interface)
+ return g_strdup(policy_interface);
+ else if (user_interface)
+ return g_strdup(user_interface);
+ else
+ return NULL;
+}
+
const char *connman_session_get_owner(struct connman_session *session)
{
return session->owner;
@@ -870,6 +886,17 @@ static void append_notify(DBusMessageIter *dict,
info_last->config.allowed_bearers =
info->config.allowed_bearers;
}
+ if (session->append_all ||
+ info->config.allowed_interface !=
info_last->config.allowed_interface) {
+ char *ifname = info->config.allowed_interface;
+ if (!ifname)
+ ifname = "";
+ connman_dbus_dict_append_basic(dict, "AllowedInterface",
+ DBUS_TYPE_STRING,
+ &ifname);
+ info_last->config.allowed_interface =
info->config.allowed_interface;
+ }
+
session->append_all = false;
}
@@ -889,7 +916,8 @@ static bool compute_notifiable_changes(struct
connman_session *session)
return true;
if (info->config.allowed_bearers != info_last->config.allowed_bearers ||
- info->config.type != info_last->config.type)
+ info->config.type != info_last->config.type ||
+ info->config.allowed_interface !=
info_last->config.allowed_interface)
return true;
return false;
@@ -943,6 +971,7 @@ int connman_session_config_update(struct connman_session
*session)
{
struct session_info *info = session->info;
GSList *allowed_bearers;
+ char *allowed_interface;
int err;
DBG("session %p", session);
@@ -968,6 +997,10 @@ int connman_session_config_update(struct connman_session
*session)
session->user_allowed_bearers,
&allowed_bearers);
+ allowed_interface = apply_policy_on_interface(
+ session->policy_config->allowed_interface,
+ session->user_allowed_interface);
+
if (session->active)
set_active_session(session, false);
@@ -977,6 +1010,9 @@ int connman_session_config_update(struct connman_session
*session)
g_slist_free(info->config.allowed_bearers);
info->config.allowed_bearers = allowed_bearers;
+ g_free(info->config.allowed_interface);
+ info->config.allowed_interface = allowed_interface;
+
session_activate(session);
info->config.type = apply_policy_on_type(
@@ -1105,6 +1141,26 @@ static DBusMessage *change_session(DBusConnection *conn,
info->config.type = apply_policy_on_type(
session->policy_config->type,
connman_session_parse_connection_type(val));
+ } else if (g_str_equal(name, "AllowedInterface")) {
+ dbus_message_iter_get_basic(&value, &val);
+ if (session->active)
+ set_active_session(session, false);
+
+ session->active = false;
+ session_deactivate(session);
+
+ g_free(session->user_allowed_interface);
+ /* empty string means allow any interface */
+ if (0 == g_strcmp0(val, ""))
+ session->user_allowed_interface = NULL;
+ else
+ session->user_allowed_interface = g_strdup(val);
+
+ info->config.allowed_interface =
apply_policy_on_interface(
+ session->policy_config->allowed_interface,
+ session->user_allowed_interface);
+
+ session_activate(session);
} else {
goto err;
}
@@ -1238,11 +1294,18 @@ static int session_policy_config_cb(struct
connman_session *session,
session->user_allowed_bearers = creation_data->allowed_bearers;
creation_data->allowed_bearers = NULL;
+ session->user_allowed_interface = creation_data->allowed_interface;
+ creation_data->allowed_interface = NULL;
+
apply_policy_on_bearers(
session->policy_config->allowed_bearers,
session->user_allowed_bearers,
&info->config.allowed_bearers);
+ info->config.allowed_interface = apply_policy_on_interface(
+ session->policy_config->allowed_interface,
+ session->user_allowed_interface);
+
g_hash_table_replace(session_hash, session->session_path, session);
DBG("add %s", session->session_path);
@@ -1267,6 +1330,7 @@ static int session_policy_config_cb(struct
connman_session *session,
info_last->config.priority = info->config.priority;
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;
session->append_all = true;
@@ -1354,6 +1418,9 @@ int __connman_session_create(DBusMessage *msg)
connman_session_parse_connection_type(val);
user_connection_type = true;
+ } else if (g_str_equal(key, "AllowedInterface")) {
+ dbus_message_iter_get_basic(&value, &val);
+ creation_data->allowed_interface =
g_strdup(val);
} else {
err = -EINVAL;
goto err;
@@ -1553,6 +1620,7 @@ static bool session_match_service(struct connman_session
*session,
enum connman_service_type bearer_type;
enum connman_service_type service_type;
GSList *list;
+ char *ifname;
if (policy && policy->allowed)
return policy->allowed(session, service);
@@ -1560,9 +1628,15 @@ static bool session_match_service(struct connman_session
*session,
for (list = session->info->config.allowed_bearers; list; list =
list->next) {
bearer_type = GPOINTER_TO_INT(list->data);
service_type = connman_service_get_type(service);
+ ifname = connman_service_get_interface(service);
- if (bearer_type == service_type)
- return true;
+ if (bearer_type == service_type &&
+ (session->info->config.allowed_interface == NULL ||
+ 0 == g_strcmp0(session->info->config.allowed_interface,
ifname))) {
+ g_free(ifname);
+ return true;
+ }
+ g_free(ifname);
}
return false;
--
2.7.4
------------------------------
Message: 4
Date: Tue, 17 Jan 2017 09:17:04 +0000
From: [email protected]
To: [email protected]
Subject: [PATCH v2 3/7] client: add session allowed interface config
Message-ID: <[email protected]>
From: Lukasz Nowak <[email protected]>
Add ability to set allowed interface in session config.
Using --ifname without a second argument, clears the
allowed interface, i.e. any interface is allowed.
---
client/commands.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/client/commands.c b/client/commands.c
index d7f59ef..c41e9b4 100644
--- a/client/commands.c
+++ b/client/commands.c
@@ -1896,6 +1896,7 @@ static int session_config(char *args[], int num,
int index = 0, res = 0;
struct config_append append;
char c;
+ char *ifname;
while (index < num && args[index]) {
append.opts = &args[index];
@@ -1922,6 +1923,18 @@ static int session_config(char *args[], int num,
DBUS_TYPE_STRING, &args[index + 1]);
append.values = 2;
break;
+ case 'i':
+ if (index + 1 < num)
+ ifname = args[index + 1];
+ else
+ ifname = "";
+
+ res = __connmanctl_dbus_session_change(connection,
+ session_path, session_config_return,
+ "AllowedInterface", "AllowedInterface",
+ DBUS_TYPE_STRING, &ifname);
+ append.values = 2;
+ break;
default:
res = -EINVAL;
@@ -2209,6 +2222,7 @@ static struct connman_option monitor_options[] = {
static struct connman_option session_options[] = {
{"bearers", 'b', "<technology1> [<technology2> [...]]"},
{"type", 't', "local|internet|any"},
+ {"ifname", 'i', "[<interface_name>]"},
{ NULL, }
};
--
2.7.4
------------------------------
Message: 5
Date: Tue, 17 Jan 2017 09:17:05 +0000
From: [email protected]
To: [email protected]
Subject: [PATCH v2 4/7] firewall: add fwmark based on source ip
address
Message-ID: <[email protected]>
From: Lukasz Nowak <[email protected]>
Add an option to enable insertion of firewall MARK into packets,
based on their source ip address. This will be used by the
multi-interface routing functionality of sessions.
---
src/connman.h | 3 ++-
src/firewall-iptables.c | 11 ++++++++++-
src/firewall-nftables.c | 5 +++--
src/session.c | 1 +
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/src/connman.h b/src/connman.h
index 577c808..ce4d82e 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -1013,7 +1013,8 @@ int __connman_firewall_enable_snat(struct
firewall_context *ctx,
int __connman_firewall_disable_snat(struct firewall_context *ctx);
int __connman_firewall_enable_marking(struct firewall_context *ctx,
enum connman_session_id_type id_type,
- char *id, uint32_t mark);
+ char *id, const char *src_ip,
+ uint32_t mark);
int __connman_firewall_disable_marking(struct firewall_context *ctx);
int __connman_firewall_init(void);
diff --git a/src/firewall-iptables.c b/src/firewall-iptables.c
index c58efc1..45943a8 100644
--- a/src/firewall-iptables.c
+++ b/src/firewall-iptables.c
@@ -495,7 +495,8 @@ static void firewall_disable_connmark(void)
int __connman_firewall_enable_marking(struct firewall_context *ctx,
enum connman_session_id_type id_type,
- char *id, uint32_t mark)
+ char *id, const char *src_ip,
+ uint32_t mark)
{
int err;
@@ -514,11 +515,19 @@ int __connman_firewall_enable_marking(struct
firewall_context *ctx,
"-m owner --gid-owner %s -j MARK --set-mark %d",
id, mark);
break;
+ case CONNMAN_SESSION_ID_TYPE_UNKNOWN:
+ break;
case CONNMAN_SESSION_ID_TYPE_LSM:
default:
return -EINVAL;
}
+ if (src_ip) {
+ firewall_add_rule(ctx, "mangle", "OUTPUT",
+ "-s %s -j MARK --set-mark %d",
+ src_ip, mark);
+ }
+
return firewall_enable_rules(ctx);
}
diff --git a/src/firewall-nftables.c b/src/firewall-nftables.c
index 4d47f20..badf8bc 100644
--- a/src/firewall-nftables.c
+++ b/src/firewall-nftables.c
@@ -800,7 +800,8 @@ err:
int __connman_firewall_enable_marking(struct firewall_context *ctx,
enum connman_session_id_type id_type,
- char *id, uint32_t mark)
+ char *id, const char *src_ip,
+ uint32_t mark)
{
struct nftnl_rule *rule;
struct mnl_socket *nl;
@@ -811,7 +812,7 @@ int __connman_firewall_enable_marking(struct
firewall_context *ctx,
DBG("");
- if (id_type != CONNMAN_SESSION_ID_TYPE_UID)
+ if (id_type != CONNMAN_SESSION_ID_TYPE_UID || src_ip)
return -ENOTSUP;
pw = getpwnam(id);
diff --git a/src/session.c b/src/session.c
index 2dfd428..9d8f484 100644
--- a/src/session.c
+++ b/src/session.c
@@ -286,6 +286,7 @@ static int init_firewall_session(struct connman_session
*session)
err =__connman_firewall_enable_marking(fw,
session->policy_config->id_type,
session->policy_config->id,
+ NULL,
session->mark);
if (err < 0) {
__connman_firewall_destroy(fw);
--
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 17
***************************************