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. fedora systemd errors (Vasiliy Tolstov)
   2. Re: autoload of nft modules (Daniel Wagner)
   3. Re: Connman Ethernet/3G handover (Patrik Flykt)
   4. [PATCH v3 0/6] Add nftables support (Daniel Wagner)
   5. [PATCH v3 1/6] session: Install SNAT rules only once per
      device (Daniel Wagner)
   6. [PATCH v3 2/6] firewall: Initialize iptables directly from
      firewall.c (Daniel Wagner)
   7. [PATCH v3 3/6] firewall: Add explicit feature API (Daniel Wagner)


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

Message: 1
Date: Fri, 29 Apr 2016 01:56:08 +0300
From: Vasiliy Tolstov <[email protected]>
To: connman <[email protected]>
Subject: fedora systemd errors
Message-ID:
        <CACaajQv=f_i3yq4jsu7j_+3z0sy1taa8j+z7ekx4je0n8kw...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

Hi! I'm check my systemd journal logs and see this errors:
Apr 29 01:44:39 acer.yoctocloud.net kernel: ath: phy0: Enable LNA combining
Apr 29 01:44:39 acer.yoctocloud.net kernel: ath: phy0: ASPM enabled: 0x42
Apr 29 01:44:39 acer.yoctocloud.net kernel: ath: EEPROM regdomain: 0x6c
Apr 29 01:44:39 acer.yoctocloud.net kernel: ath: EEPROM indicates we
should expect a direct regpair map
Apr 29 01:44:39 acer.yoctocloud.net kernel: ath: Country alpha2 being used: 00
Apr 29 01:44:39 acer.yoctocloud.net kernel: ath: Regpair used: 0x6c
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {create}
index 3 type 1 <ETHER>
Apr 29 01:44:39 acer.yoctocloud.net kernel: ieee80211 phy0: Selected
rate control algorithm 'minstrel_ht'
Apr 29 01:44:39 acer.yoctocloud.net kernel: ieee80211 phy0: Atheros
AR9565 Rev:2 mem=0xffffc90000500000, irq=18
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {update}
flags 4098 <DOWN>
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {newlink}
index 3 address B8:86:87:C7:CA:5D mtu 1500
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {newlink}
index 3 operstate 2 <DOWN>
Apr 29 01:44:39 acer.yoctocloud.net kernel: IPv6: ADDRCONF(NETDEV_UP):
wlan0: link is not ready
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: Adding interface
wlan0 [ wifi ]
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {update}
flags 36931 <UP,RUNNING>
te.
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {newlink}
index 3 address B8:86:87:C7:CA:5D mtu 1500
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {newlink}
index 3 operstate 0 <UNKNOWN>
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {update}
flags 36867 <UP>
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {newlink}
index 3 address B8:86:87:C7:CA:5D mtu 1500
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {newlink}
index 3 operstate 2 <DOWN>
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {newlink}
index 3 address B8:86:87:C7:CA:5D mtu 1500
Apr 29 01:44:39 acer.yoctocloud.net connmand[643]: wlan0 {newlink}
index 3 operstate 2 <DOWN>
Apr 29 01:44:39 acer.yoctocloud.net systemd-udevd[537]: Error changing
net interface name 'wlan0' to 'wlp2s0': Device or resource busy
Apr 29 01:44:39 acer.yoctocloud.net systemd-udevd[537]: could not
rename interface '3' from 'wlan0' to 'wlp2s0': Device or resource busy

Does it possible to allow rename device from wlan0?
As i understand systemd-udevd can't rename device because it already in up state
-- 
Vasiliy Tolstov,
e-mail: [email protected]


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

Message: 2
Date: Fri, 29 Apr 2016 07:33:45 +0200
From: Daniel Wagner <[email protected]>
To: Pablo Neira Ayuso <[email protected]>
Cc: [email protected], [email protected], Dragos Tatulea
        <[email protected]>
Subject: Re: autoload of nft modules
Message-ID: <[email protected]>
Content-Type: text/plain; charset=windows-1252

On 04/27/2016 02:54 PM, Pablo Neira Ayuso wrote:
> On Wed, Apr 27, 2016 at 10:52:13AM +0200, Daniel Wagner wrote:
>> Dragos and I are working on getting nft support into ConnMan [1]. Now we
>> face a small problem with the rule we load, which are essentially:
>>
>>  nft add table connman
>>  nft add chain connman nat-prerouting                        \
>>      { type nat hook prerouting priortiy 0 ; }
>>  nft add chain connman nat-postrouting                       \
>>      { type nat hook postrouting priortiy 0 ; }
>>  nft add chain connman filter-output                 \
>>      { type filter hook output priority 0 ; }
>>
>> These work nicely using the nft CLI but when we run those commands
>> via libnftnl after a fresh reboot of the system, there is a ENOENT at
>> the third rule.
> 
> Most likely you're missing the NLM_F_CREATE flags in your netlink
> messages.

Yes, that did they the trick.

> Please, send us patches for the example so other don't hit this
> problem.

Will do.

thanks,
daniel


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

Message: 3
Date: Fri, 29 Apr 2016 09:50:50 +0300
From: Patrik Flykt <[email protected]>
To: Florent Le Saout <[email protected]>,
        [email protected]
Subject: Re: Connman Ethernet/3G handover
Message-ID: <[email protected]>
Content-Type: text/plain; charset="UTF-8"

On Thu, 2016-04-28 at 08:55 +0200, Florent Le Saout wrote:
> Hi,
> 
> I'm looking for a network manager.
> 
> I would like to use ConnMan in an embedded system. It seems that it
> provides most of the features I'm looking for, including 3G and VPN
> management.
> 
> But after some research it seems that there is maybe one missing
> point in it. Let say I have the following setup :
> 
> Ethernet connection as preferred connection
> 3/4G connection as backup/failover connection
> 
> My Ethernet is always on and dhcp server is properly providing IP,
> cable is still plugged in, and power on the line is still there, but
> sometimes the internet connectivity is lost. So in that case it ll
> switch to the 3G/4G connection. But then as soon as possible, when
> connectivity is back online via the ethernet, I want to switch back
> to it for performance and cost reason.
> 
> Is this supported by default, or is there a way to configure it that
> way ?
> 
> I found this post(http://comments.gmane.org/gmane.linux.network.connm
> an/10238) which seems to say that it was not supported at that time,
> since there is no periodic check (February 2013).
> And also from the documentation :
> 
> Autoconnecting
> 
> Favorite (saved) networks that have autoconnect enabled are
> considered when autoconnecting services. These services are marked
> with '*' and 'A' in connmanctl, respectively. By default ConnMan
> autoconnects these in the order they are shown in the list of
> services until one of them gets connected. After that the
> autoconnected service is in use and ConnMan won't select a new one
> until the network goes out of range. When the service goes out of
> range or gets disconnected from the network infrastructure side,
> autoconnect is re-run and another favorite autoconnectable service is
> selected.
> 
> So I want to make sure I got the correct understanding on that ?
> 
> Feel free to ask for more informations if this is unclear.

Autoconnect works for the immediately connected networks links, i.e.
when a wifi scan is done and a known network is found and also when an
ethernet network cable is connected. So this part works as documented
and the service is being used as long as the network link is kept
connected.

Now the issue you have is that the connection to "Internet" broke
somewhere after the first network link. For this there is no good
solution, ConnMan does it's connectivity discovery once after a network
is connected. ConnMan makes a decent guess that the network will work
in the intended way also later. ConnMan does not make any connectivity
assumptions other than informing the user about its connected state; no
changes are made to the inner workings of ConnMan depending on the
network 'ready' or 'online' states.

So the question that doesn't have a good answer is with what frequency
should temporary glitches be detectable in the first place? And to what
part of the "Internet", as the connectivity check may succeed but the
end point that the application cares about won't be reachable. And as
nothing is changed internally, 'ready' and 'online' state correspond to
the same networking functionality should the connection to the
"Internet" disappear/reappear beyond the first connected network link.

Cheers,

        Patrik


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

Message: 4
Date: Fri, 29 Apr 2016 09:27:49 +0200
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Dragos Tatulea <[email protected]>, Daniel Wagner
        <[email protected]>
Subject: [PATCH v3 0/6] Add nftables support
Message-ID: <[email protected]>

From: Daniel Wagner <[email protected]>

Thanks Dragos for testing and feedback. I tested NAT so far which
works nicely for me. The session code part is next.

changes v3:
        - fixed error handling when cleaning up (this time for real)
        - dropped chain handlers (not used)
        - tell kernel to load modules if needed via NLM_F_CREATE
        - mask saddr address with netmask for NAT rule (bug fix)

changes v2:
        - rebased to current master
        - fixed some error handling path (memory leak)
        - fixed typo and error handling reported by dtatulea
        - compiler complains
        - issue no warning if table cleaning up was successful

Daniel Wagner (6):
  session: Install SNAT rules only once per device
  firewall: Initialize iptables directly from firewall.c
  firewall: Add explicit feature API
  firewall: Rename firewall.c to firewall-iptables.c
  firewall: Add nftables build infrastructure
  firewall-nftables: Add nftable support for firewall

 Makefile.am             |   48 +-
 configure.ac            |   31 +-
 src/connman.h           |   22 +-
 src/firewall-iptables.c |  622 +++++++++++++++++++++++++
 src/firewall-nftables.c | 1153 +++++++++++++++++++++++++++++++++++++++++++++++
 src/firewall.c          |  542 ----------------------
 src/main.c              |    2 -
 src/nat.c               |   21 +-
 src/session.c           |  187 ++++----
 tools/iptables-unit.c   |  112 -----
 10 files changed, 1940 insertions(+), 800 deletions(-)
 create mode 100644 src/firewall-iptables.c
 create mode 100644 src/firewall-nftables.c
 delete mode 100644 src/firewall.c

-- 
2.5.5


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

Message: 5
Date: Fri, 29 Apr 2016 09:27:50 +0200
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Dragos Tatulea <[email protected]>, Daniel Wagner
        <[email protected]>
Subject: [PATCH v3 1/6] session: Install SNAT rules only once per
        device
Message-ID: <[email protected]>

From: Daniel Wagner <[email protected]>

The marking rules are different from each session. The SNAT
routing rule is only needed once per devices. Therefore, we share the
rule between the session and should only install unique rules.

Note the live time management needs to track which session
installed/refd the rule to avoid removal from update_nat_rules()
on a session create event.
---
 src/session.c | 148 +++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 115 insertions(+), 33 deletions(-)

diff --git a/src/session.c b/src/session.c
index 388aae7..1205935 100644
--- a/src/session.c
+++ b/src/session.c
@@ -69,7 +69,6 @@ struct connman_session {
 
        enum connman_session_id_type id_type;
        struct firewall_context *fw;
-       int snat_id;
        uint32_t mark;
        int index;
        char *gateway;
@@ -81,6 +80,15 @@ struct connman_service_info {
        GSList *sessions;
 };
 
+struct fw_snat {
+       GSList *sessions;
+       int id;
+       int index;
+       struct firewall_context *fw;
+};
+
+GSList *fw_snat_list;
+
 static struct connman_session_policy *policy;
 static void session_activate(struct connman_session *session);
 static void session_deactivate(struct connman_session *session);
@@ -197,6 +205,87 @@ static char *service2bearer(enum connman_service_type type)
        return "";
 }
 
+static struct fw_snat *fw_snat_lookup(int index)
+{
+       struct fw_snat *fw_snat;
+       GSList *list;
+
+       for (list = fw_snat_list; list; list = list->next) {
+               fw_snat = list->data;
+
+               if (fw_snat->index == index)
+                       return fw_snat;
+       }
+       return NULL;
+}
+
+static int fw_snat_create(struct connman_session *session,
+                               int index, const char *ifname, const char *addr)
+{
+       struct fw_snat *fw_snat;
+       int err;
+
+       fw_snat = g_new0(struct fw_snat, 1);
+
+       fw_snat->fw = __connman_firewall_create();
+       fw_snat->index = index;
+
+       fw_snat->id = __connman_firewall_add_rule(fw_snat->fw,
+                               "nat", "POSTROUTING",
+                               "-o %s -j SNAT --to-source %s",
+                               ifname, addr);
+       if (fw_snat->id < 0) {
+               err = fw_snat->id;
+               goto err;
+       }
+
+       err = __connman_firewall_enable_rule(fw_snat->fw, fw_snat->id);
+       if (err < 0) {
+               __connman_firewall_remove_rule(fw_snat->fw, fw_snat->id);
+               goto err;
+       }
+
+       fw_snat_list = g_slist_prepend(fw_snat_list, fw_snat);
+       fw_snat->sessions = g_slist_prepend(fw_snat->sessions, session);
+
+       return 0;
+err:
+       __connman_firewall_destroy(fw_snat->fw);
+       g_free(fw_snat);
+       return err;
+}
+
+static void fw_snat_ref(struct connman_session *session,
+                               struct fw_snat *fw_snat)
+{
+       if (g_slist_find(fw_snat->sessions, session))
+               return;
+       fw_snat->sessions = g_slist_prepend(fw_snat->sessions, session);
+}
+
+static void fw_snat_unref(struct connman_session *session,
+                               struct fw_snat *fw_snat)
+{
+       int err;
+
+       fw_snat->sessions = g_slist_remove(fw_snat->sessions, session);
+       if (fw_snat->sessions)
+               return;
+
+       fw_snat_list = g_slist_remove(fw_snat_list, fw_snat);
+
+       err = __connman_firewall_disable_rule(fw_snat->fw, fw_snat->id);
+       if (err < 0)
+               DBG("could not disable SNAT rule");
+
+       err = __connman_firewall_remove_rule(fw_snat->fw, fw_snat->id);
+       if (err < 0)
+               DBG("could not remove SNAT rule");
+
+       __connman_firewall_destroy(fw_snat->fw);
+       g_free(fw_snat);
+}
+
 static int init_firewall(void)
 {
        struct firewall_context *fw;
@@ -368,59 +457,46 @@ static void add_default_route(struct connman_session 
*session)
 
 static void del_nat_rules(struct connman_session *session)
 {
-       int err;
+       struct fw_snat *fw_snat;
 
-       if (!session->fw || session->snat_id == 0)
-               return;
+       fw_snat = fw_snat_lookup(session->index);
 
-       err = __connman_firewall_disable_rule(session->fw, session->snat_id);
-       if (err < 0) {
-               DBG("could not disable SNAT rule");
+       if (!fw_snat)
                return;
-       }
-
-       err = __connman_firewall_remove_rule(session->fw, session->snat_id);
-       if (err < 0)
-               DBG("could not remove SNAT rule");
 
-
-       session->snat_id = 0;
+       fw_snat_unref(session, fw_snat);
 }
 
 static void add_nat_rules(struct connman_session *session)
 {
        struct connman_ipconfig *ipconfig;
+       struct fw_snat *fw_snat;
        const char *addr;
        char *ifname;
-       int index, id, err;
-
-       if (!session->fw)
-               return;
+       int index, err;
 
        DBG("");
 
+       if (!session->service)
+               return;
+
        ipconfig = __connman_service_get_ip4config(session->service);
        index = __connman_ipconfig_get_index(ipconfig);
-       ifname = connman_inet_ifname(index);
-       addr = __connman_ipconfig_get_local(ipconfig);
 
-       id = __connman_firewall_add_rule(session->fw, "nat", "POSTROUTING",
-                               "-o %s -j SNAT --to-source %s",
-                               ifname, addr);
-       g_free(ifname);
-       if (id < 0) {
-               DBG("failed to add SNAT rule");
+       fw_snat = fw_snat_lookup(index);
+       if (fw_snat) {
+               fw_snat_ref(session, fw_snat);
                return;
        }
 
-       err = __connman_firewall_enable_rule(session->fw, id);
-       if (err < 0) {
-               DBG("could not enable SNAT rule");
-               __connman_firewall_remove_rule(session->fw, id);
-               return;
-       }
+       ifname = connman_inet_ifname(index);
+       addr = __connman_ipconfig_get_local(ipconfig);
+
+       err = fw_snat_create(session, index, ifname, addr);
+       if (err < 0)
+               DBG("failed to add SNAT rule");
 
-       session->snat_id = id;
+       g_free(ifname);
 }
 
 static void cleanup_routing_table(struct connman_session *session)
@@ -445,6 +521,11 @@ static void update_routing_table(struct connman_session 
*session)
        add_default_route(session);
 }
 
+static void cleanup_nat_rules(struct connman_session *session)
+{
+       del_nat_rules(session);
+}
+
 static void update_nat_rules(struct connman_session *session)
 {
        del_nat_rules(session);
@@ -498,6 +579,7 @@ static void cleanup_session(gpointer user_data)
 
        DBG("remove %s", session->session_path);
 
+       cleanup_nat_rules(session);
        cleanup_routing_table(session);
        cleanup_firewall_session(session);
 
-- 
2.5.5


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

Message: 6
Date: Fri, 29 Apr 2016 09:27:51 +0200
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Dragos Tatulea <[email protected]>, Daniel Wagner
        <[email protected]>
Subject: [PATCH v3 2/6] firewall: Initialize iptables directly from
        firewall.c
Message-ID: <[email protected]>

From: Daniel Wagner <[email protected]>

The current firewall API implementation is depending on iptables. In order
to support a nftables implementation we move the init call from
main.c to firewall.c.
---
 src/firewall.c | 2 ++
 src/main.c     | 2 --
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/firewall.c b/src/firewall.c
index c440df6..fed75a8 100644
--- a/src/firewall.c
+++ b/src/firewall.c
@@ -529,6 +529,7 @@ int __connman_firewall_init(void)
 {
        DBG("");
 
+       __connman_iptables_init();
        flush_all_tables();
 
        return 0;
@@ -539,4 +540,5 @@ void __connman_firewall_cleanup(void)
        DBG("");
 
        g_slist_free_full(managed_tables, cleanup_managed_table);
+       __connman_iptables_cleanup();
 }
diff --git a/src/main.c b/src/main.c
index f44a2ed..fdb4f72 100644
--- a/src/main.c
+++ b/src/main.c
@@ -669,7 +669,6 @@ int main(int argc, char *argv[])
        __connman_device_init(option_device, option_nodevice);
 
        __connman_ippool_init();
-       __connman_iptables_init();
        __connman_firewall_init();
        __connman_nat_init();
        __connman_tethering_init();
@@ -732,7 +731,6 @@ int main(int argc, char *argv[])
        __connman_tethering_cleanup();
        __connman_nat_cleanup();
        __connman_firewall_cleanup();
-       __connman_iptables_cleanup();
        __connman_peer_service_cleanup();
        __connman_peer_cleanup();
        __connman_ippool_cleanup();
-- 
2.5.5


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

Message: 7
Date: Fri, 29 Apr 2016 09:27:52 +0200
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Dragos Tatulea <[email protected]>, Daniel Wagner
        <[email protected]>
Subject: [PATCH v3 3/6] firewall: Add explicit feature API
Message-ID: <[email protected]>

From: Daniel Wagner <[email protected]>

Instead heaving a generic firewall API, we use an just provide
a few features such as NAT, SNAT or MARK. That allows
us to push down all the code into firewall.c.

There are only two different users in ConnMan for this API:
enabling global NAT or for session handling.

Fortunately, the NAT handling is pretty simple. We just have one
global table and we either have it enabled or disabled.

The session handling is slightly more tricky. There are
three different rule sets. The first one enables one global rule
for CONNMARK save/restore. This one will be installed only when the
first session calls __connman_firewall_enable_marking(). For this we
use a global context and enable disable it only if there is a session
using it.

The SNAT rules are shared between sessions and there exists only one
per output device. The session tracking is done in session.c. Note
the SNAT rules have also their own struct firewall_context.

The third set of rule for MARK is owned by the session, that is the
rules are tracked it the session->fw context.

Due to the separation of the struct firewall_context usage we can
git rid of  any special tracking. Either we enable all or disable all
in one go. We don't have enable indiviual rules anymore with the
FW_ALL_RULES. And we are all happy again.
---
 src/connman.h         |  22 +++---
 src/firewall.c        | 190 +++++++++++++++++++++++++++++++++++---------------
 src/nat.c             |  21 +-----
 src/session.c         | 123 ++++----------------------------
 tools/iptables-unit.c | 112 -----------------------------
 5 files changed, 162 insertions(+), 306 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index e849ed8..401e3d7 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -992,16 +992,18 @@ struct firewall_context;
 
 struct firewall_context *__connman_firewall_create(void);
 void __connman_firewall_destroy(struct firewall_context *ctx);
-int __connman_firewall_add_rule(struct firewall_context *ctx,
-                               const char *table,
-                               const char *chain,
-                               const char *rule_fmt, ...);
-int __connman_firewall_remove_rule(struct firewall_context *ctx, int id);
-int __connman_firewall_enable_rule(struct firewall_context *ctx, int id);
-int __connman_firewall_disable_rule(struct firewall_context *ctx, int id);
-int __connman_firewall_enable(struct firewall_context *ctx);
-int __connman_firewall_disable(struct firewall_context *ctx);
-bool __connman_firewall_is_up(void);
+int __connman_firewall_enable_nat(struct firewall_context *ctx,
+                                       char *address, unsigned char prefixlen,
+                                       char *interface);
+int __connman_firewall_disable_nat(struct firewall_context *ctx);
+int __connman_firewall_enable_snat(struct firewall_context *ctx,
+                               int index, const char *ifname,
+                               const char *addr);
+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);
+int __connman_firewall_disable_marking(struct firewall_context *ctx);
 
 int __connman_firewall_init(void);
 void __connman_firewall_cleanup(void);
diff --git a/src/firewall.c b/src/firewall.c
index fed75a8..c58efc1 100644
--- a/src/firewall.c
+++ b/src/firewall.c
@@ -31,7 +31,6 @@
 #include "connman.h"
 
 #define CHAIN_PREFIX "connman-"
-#define FW_ALL_RULES -1
 
 static const char *builtin_chains[] = {
        [NF_IP_PRE_ROUTING]     = "PREROUTING",
@@ -47,7 +46,6 @@ struct connman_managed_table {
 };
 
 struct fw_rule {
-       int id;
        bool enabled;
        char *table;
        char *chain;
@@ -59,9 +57,8 @@ struct firewall_context {
 };
 
 static GSList *managed_tables;
-
-static bool firewall_is_up;
-static unsigned int firewall_rule_id;
+static struct firewall_context *connmark_ctx;
+static unsigned int connmark_ref;
 
 static int chain_to_index(const char *chain_name)
 {
@@ -271,7 +268,7 @@ void __connman_firewall_destroy(struct firewall_context 
*ctx)
        g_free(ctx);
 }
 
-static int firewall_enable_rule(struct fw_rule *rule)
+static int enable_rule(struct fw_rule *rule)
 {
        int err;
 
@@ -293,7 +290,7 @@ static int firewall_enable_rule(struct fw_rule *rule)
        return 0;
 }
 
-static int firewall_disable_rule(struct fw_rule *rule)
+static int disable_rule(struct fw_rule *rule)
 {
        int err;
 
@@ -319,7 +316,7 @@ static int firewall_disable_rule(struct fw_rule *rule)
        return 0;
 }
 
-int __connman_firewall_add_rule(struct firewall_context *ctx,
+static void firewall_add_rule(struct firewall_context *ctx,
                                const char *table,
                                const char *chain,
                                const char *rule_fmt, ...)
@@ -336,40 +333,29 @@ int __connman_firewall_add_rule(struct firewall_context 
*ctx,
 
        rule = g_new0(struct fw_rule, 1);
 
-       rule->id = firewall_rule_id++;
        rule->enabled = false;
        rule->table = g_strdup(table);
        rule->chain = g_strdup(chain);
        rule->rule_spec = rule_spec;
 
        ctx->rules = g_list_append(ctx->rules, rule);
-       return rule->id;
 }
 
-int __connman_firewall_remove_rule(struct firewall_context *ctx, int id)
+static void firewall_remove_rules(struct firewall_context *ctx)
 {
        struct fw_rule *rule;
        GList *list;
-       int err = -ENOENT;
 
        for (list = g_list_last(ctx->rules); list;
                        list = g_list_previous(list)) {
                rule = list->data;
 
-               if (rule->id == id || id == FW_ALL_RULES) {
-                       ctx->rules = g_list_remove(ctx->rules, rule);
-                       cleanup_fw_rule(rule);
-                       err = 0;
-
-                       if (id != FW_ALL_RULES)
-                               break;
-               }
+               ctx->rules = g_list_remove(ctx->rules, rule);
+               cleanup_fw_rule(rule);
        }
-
-       return err;
 }
 
-int __connman_firewall_enable_rule(struct firewall_context *ctx, int id)
+static int firewall_enable_rules(struct firewall_context *ctx)
 {
        struct fw_rule *rule;
        GList *list;
@@ -378,20 +364,15 @@ int __connman_firewall_enable_rule(struct 
firewall_context *ctx, int id)
        for (list = g_list_first(ctx->rules); list; list = g_list_next(list)) {
                rule = list->data;
 
-               if (rule->id == id || id == FW_ALL_RULES) {
-                       err = firewall_enable_rule(rule);
-                       if (err < 0)
-                               break;
-
-                       if (id != FW_ALL_RULES)
-                               break;
-               }
+               err = enable_rule(rule);
+               if (err < 0)
+                       break;
        }
 
        return err;
 }
 
-int __connman_firewall_disable_rule(struct firewall_context *ctx, int id)
+static int firewall_disable_rules(struct firewall_context *ctx)
 {
        struct fw_rule *rule;
        GList *list;
@@ -402,49 +383,149 @@ int __connman_firewall_disable_rule(struct 
firewall_context *ctx, int id)
                        list = g_list_previous(list)) {
                rule = list->data;
 
-               if (rule->id == id || id == FW_ALL_RULES) {
-                       e = firewall_disable_rule(rule);
+               e = disable_rule(rule);
 
-                       /* Report last error back */
-                       if (e == 0 && err == -ENOENT)
-                               err = 0;
-                       else if (e < 0)
-                               err = e;
+               /* Report last error back */
+               if (e == 0 && err == -ENOENT)
+                       err = 0;
+               else if (e < 0)
+                       err = e;
+       }
 
-                       if (id != FW_ALL_RULES)
-                               break;
-               }
+       return err;
+}
+
+int __connman_firewall_enable_nat(struct firewall_context *ctx,
+                               char *address, unsigned char prefixlen,
+                               char *interface)
+{
+       char *cmd;
+       int err;
+
+       cmd = g_strdup_printf("-s %s/%d -o %s -j MASQUERADE",
+                                       address, prefixlen, interface);
+
+       firewall_add_rule(ctx, "nat", "POSTROUTING", cmd);
+       g_free(cmd);
+       err = firewall_enable_rules(ctx);
+       if (err)
+               firewall_remove_rules(ctx);
+       return err;
+}
+
+int __connman_firewall_disable_nat(struct firewall_context *ctx)
+{
+       int err;
+
+       err = firewall_disable_rules(ctx);
+       if (err < 0) {
+               DBG("could not disable NAT rule");
+               return err;
        }
 
+       firewall_remove_rules(ctx);
+       return 0;
+}
+
+int __connman_firewall_enable_snat(struct firewall_context *ctx,
+                               int index, const char *ifname,
+                               const char *addr)
+{
+       int err;
+
+       firewall_add_rule(ctx, "nat", "POSTROUTING",
+                               "-o %s -j SNAT --to-source %s",
+                               ifname, addr);
+
+       err = firewall_enable_rules(ctx);
+       if (err)
+               firewall_remove_rules(ctx);
        return err;
 }
 
-int __connman_firewall_enable(struct firewall_context *ctx)
+int __connman_firewall_disable_snat(struct firewall_context *ctx)
 {
        int err;
 
-       err = __connman_firewall_enable_rule(ctx, FW_ALL_RULES);
+       err = firewall_disable_rules(ctx);
        if (err < 0) {
-               connman_warn("Failed to install iptables rules: %s",
-                               strerror(-err));
-               __connman_firewall_disable_rule(ctx, FW_ALL_RULES);
+               DBG("could not disable SNAT rule");
                return err;
        }
 
-       firewall_is_up = true;
+       firewall_remove_rules(ctx);
+       return 0;
+}
+
+static int firewall_enable_connmark(void)
+{
+       int err;
+
+       if (connmark_ref > 0) {
+               connmark_ref++;
+               return 0;
+       }
+
+       connmark_ctx = __connman_firewall_create();
 
+       firewall_add_rule(connmark_ctx, "mangle", "INPUT",
+                                       "-j CONNMARK --restore-mark");
+       firewall_add_rule(connmark_ctx, "mangle", "POSTROUTING",
+                                       "-j CONNMARK --save-mark");
+       err = firewall_enable_rules(connmark_ctx);
+       if (err) {
+               __connman_firewall_destroy(connmark_ctx);
+               connmark_ctx = NULL;
+               return err;
+       }
+       connmark_ref++;
        return 0;
 }
 
-int __connman_firewall_disable(struct firewall_context *ctx)
+static void firewall_disable_connmark(void)
+{
+       connmark_ref--;
+       if (connmark_ref > 0)
+               return;
+
+       firewall_disable_rules(connmark_ctx);
+       __connman_firewall_destroy(connmark_ctx);
+       connmark_ctx = NULL;
+}
+
+int __connman_firewall_enable_marking(struct firewall_context *ctx,
+                                       enum connman_session_id_type id_type,
+                                       char *id, uint32_t mark)
 {
-       __connman_firewall_disable_rule(ctx, FW_ALL_RULES);
-       return __connman_firewall_remove_rule(ctx, FW_ALL_RULES);
+       int err;
+
+       err = firewall_enable_connmark();
+       if (err)
+               return err;
+
+       switch (id_type) {
+       case CONNMAN_SESSION_ID_TYPE_UID:
+               firewall_add_rule(ctx, "mangle", "OUTPUT",
+                               "-m owner --uid-owner %s -j MARK --set-mark %d",
+                                       id, mark);
+               break;
+       case CONNMAN_SESSION_ID_TYPE_GID:
+               firewall_add_rule(ctx, "mangle", "OUTPUT",
+                               "-m owner --gid-owner %s -j MARK --set-mark %d",
+                                       id, mark);
+               break;
+       case CONNMAN_SESSION_ID_TYPE_LSM:
+       default:
+               return -EINVAL;
+       }
+
+       return firewall_enable_rules(ctx);
 }
 
-bool __connman_firewall_is_up(void)
+int __connman_firewall_disable_marking(struct firewall_context *ctx)
 {
-       return firewall_is_up;
+       firewall_disable_connmark();
+       return firewall_disable_rules(ctx);
 }
 
 static void iterate_chains_cb(const char *chain_name, void *user_data)
@@ -514,12 +595,9 @@ static void flush_all_tables(void)
 
        if (!g_file_test("/proc/net/ip_tables_names",
                        G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
-               firewall_is_up = false;
                return;
        }
 
-       firewall_is_up = true;
-
        flush_table("filter");
        flush_table("mangle");
        flush_table("nat");
diff --git a/src/nat.c b/src/nat.c
index 33ae6df..4c1f858 100644
--- a/src/nat.c
+++ b/src/nat.c
@@ -80,28 +80,14 @@ static int enable_ip_forward(bool enable)
 
 static int enable_nat(struct connman_nat *nat)
 {
-       char *cmd;
-       int err;
-
        g_free(nat->interface);
        nat->interface = g_strdup(default_interface);
 
        if (!nat->interface)
                return 0;
 
-       /* Enable masquerading */
-       cmd = g_strdup_printf("-s %s/%d -o %s -j MASQUERADE",
-                                       nat->address,
-                                       nat->prefixlen,
-                                       nat->interface);
-
-       err = __connman_firewall_add_rule(nat->fw, "nat",
-                               "POSTROUTING", cmd);
-       g_free(cmd);
-       if (err < 0)
-               return err;
-
-       return __connman_firewall_enable(nat->fw);
+       return __connman_firewall_enable_nat(nat->fw, nat->address,
+                                       nat->prefixlen, nat->interface);
 }
 
 static void disable_nat(struct connman_nat *nat)
@@ -109,8 +95,7 @@ static void disable_nat(struct connman_nat *nat)
        if (!nat->interface)
                return;
 
-       /* Disable masquerading */
-       __connman_firewall_disable(nat->fw);
+       __connman_firewall_disable_nat(nat->fw);
 }
 
 int __connman_nat_enable(const char *name, const char *address,
diff --git a/src/session.c b/src/session.c
index 1205935..b1e9e1b 100644
--- a/src/session.c
+++ b/src/session.c
@@ -37,7 +37,6 @@ static GHashTable *session_hash;
 static GHashTable *service_hash;
 static struct connman_session *ecall_session;
 static uint32_t session_mark = 256;
-static struct firewall_context *global_firewall = NULL;
 
 enum connman_session_state {
        CONNMAN_SESSION_STATE_DISCONNECTED   = 0,
@@ -230,21 +229,13 @@ static int fw_snat_create(struct connman_session *session,
        fw_snat->fw = __connman_firewall_create();
        fw_snat->index = index;
 
-       fw_snat->id = __connman_firewall_add_rule(fw_snat->fw,
-                               "nat", "POSTROUTING",
-                               "-o %s -j SNAT --to-source %s",
-                               ifname, addr);
+       fw_snat->id = __connman_firewall_enable_snat(fw_snat->fw,
+                                               index, ifname, addr);
        if (fw_snat->id < 0) {
                err = fw_snat->id;
                goto err;
        }
 
-       err = __connman_firewall_enable_rule(fw_snat->fw, fw_snat->id);
-       if (err < 0) {
-               __connman_firewall_remove_rule(fw_snat->fw, fw_snat->id);
-               goto err;
-       }
-
        fw_snat_list = g_slist_prepend(fw_snat_list, fw_snat);
        fw_snat->sessions = g_slist_prepend(fw_snat->sessions, session);
 
@@ -266,69 +257,17 @@ static void fw_snat_ref(struct connman_session *session,
 static void fw_snat_unref(struct connman_session *session,
                                struct fw_snat *fw_snat)
 {
-       int err;
-
        fw_snat->sessions = g_slist_remove(fw_snat->sessions, session);
        if (fw_snat->sessions)
                return;
 
        fw_snat_list = g_slist_remove(fw_snat_list, fw_snat);
 
-       err = __connman_firewall_disable_rule(fw_snat->fw, fw_snat->id);
-       if (err < 0)
-               DBG("could not disable SNAT rule");
-
-       err = __connman_firewall_remove_rule(fw_snat->fw, fw_snat->id);
-       if (err < 0)
-               DBG("could not remove SNAT rule");
-
+       __connman_firewall_disable_snat(fw_snat->fw);
        __connman_firewall_destroy(fw_snat->fw);
        g_free(fw_snat);
 }
 
-static int init_firewall(void)
-{
-       struct firewall_context *fw;
-       int err;
-
-       if (global_firewall)
-               return 0;
-
-       fw = __connman_firewall_create();
-
-       err = __connman_firewall_add_rule(fw, "mangle", "INPUT",
-                                       "-j CONNMARK --restore-mark");
-       if (err < 0)
-               goto err;
-
-       err = __connman_firewall_add_rule(fw, "mangle", "POSTROUTING",
-                                       "-j CONNMARK --save-mark");
-       if (err < 0)
-               goto err;
-
-       err = __connman_firewall_enable(fw);
-       if (err < 0)
-               goto err;
-
-       global_firewall = fw;
-
-       return 0;
-
-err:
-       __connman_firewall_destroy(fw);
-
-       return err;
-}
-
-static void cleanup_firewall(void)
-{
-       if (!global_firewall)
-               return;
-
-       __connman_firewall_disable(global_firewall);
-       __connman_firewall_destroy(global_firewall);
-}
-
 static int init_firewall_session(struct connman_session *session)
 {
        struct firewall_context *fw;
@@ -339,49 +278,22 @@ static int init_firewall_session(struct connman_session 
*session)
 
        DBG("");
 
-       err = init_firewall();
-       if (err < 0)
-               return err;
-
        fw = __connman_firewall_create();
        if (!fw)
                return -ENOMEM;
 
-       switch (session->policy_config->id_type) {
-       case CONNMAN_SESSION_ID_TYPE_UID:
-               err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
-                               "-m owner --uid-owner %s -j MARK --set-mark %d",
-                                               session->policy_config->id,
-                                               session->mark);
-               break;
-       case CONNMAN_SESSION_ID_TYPE_GID:
-               err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
-                               "-m owner --gid-owner %s -j MARK --set-mark %d",
-                                               session->policy_config->id,
-                                               session->mark);
-               break;
-       case CONNMAN_SESSION_ID_TYPE_LSM:
-       default:
-               err = -EINVAL;
+       err =__connman_firewall_enable_marking(fw,
+                                       session->policy_config->id_type,
+                                       session->policy_config->id,
+                                       session->mark);
+       if (err < 0) {
+               __connman_firewall_destroy(fw);
+               return err;
        }
-
-       if (err < 0)
-               goto err;
-
        session->id_type = session->policy_config->id_type;
-
-       err = __connman_firewall_enable(fw);
-       if (err)
-               goto err;
-
        session->fw = fw;
 
        return 0;
-
-err:
-       __connman_firewall_destroy(fw);
-
-       return err;
 }
 
 static void cleanup_firewall_session(struct connman_session *session)
@@ -389,7 +301,8 @@ static void cleanup_firewall_session(struct connman_session 
*session)
        if (!session->fw)
                return;
 
-       __connman_firewall_disable(session->fw);
+       __connman_firewall_disable_marking(session->fw);
+       __connman_firewall_disable_snat(session->fw);
        __connman_firewall_destroy(session->fw);
 
        session->fw = NULL;
@@ -472,10 +385,8 @@ static void add_nat_rules(struct connman_session *session)
        struct connman_ipconfig *ipconfig;
        struct fw_snat *fw_snat;
        const char *addr;
-       char *ifname;
        int index, err;
-
-       DBG("");
+       char *ifname;
 
        if (!session->service)
                return;
@@ -1877,12 +1788,6 @@ int __connman_session_init(void)
 
        service_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
                                                NULL, cleanup_service);
-       if (__connman_firewall_is_up()) {
-               err = init_firewall();
-               if (err < 0)
-                       return err;
-       }
-
        return 0;
 }
 
@@ -1893,8 +1798,6 @@ void __connman_session_cleanup(void)
        if (!connection)
                return;
 
-       cleanup_firewall();
-
        connman_notifier_unregister(&session_notifier);
 
        g_hash_table_foreach(session_hash, release_session, NULL);
diff --git a/tools/iptables-unit.c b/tools/iptables-unit.c
index e919aa5..426631a 100644
--- a/tools/iptables-unit.c
+++ b/tools/iptables-unit.c
@@ -406,112 +406,6 @@ static void test_nat_basic1(void)
        g_free(service);
 }
 
-static void test_firewall_basic0(void)
-{
-       struct firewall_context *ctx;
-       int err;
-
-       ctx = __connman_firewall_create();
-       g_assert(ctx);
-
-       err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
-                                       "-m mark --mark 999 -j LOG");
-       g_assert(err >= 0);
-
-       err = __connman_firewall_enable(ctx);
-       g_assert(err == 0);
-
-       assert_rule_exists("filter", ":connman-INPUT - [0:0]");
-       assert_rule_exists("filter", "-A INPUT -j connman-INPUT");
-       assert_rule_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 -j 
LOG");
-
-       err = __connman_firewall_disable(ctx);
-       g_assert(err == 0);
-
-       assert_rule_not_exists("filter", ":connman-INPUT - [0:0]");
-       assert_rule_not_exists("filter", "-A INPUT -j connman-INPUT");
-       assert_rule_not_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 
-j LOG");
-
-       __connman_firewall_destroy(ctx);
-}
-
-static void test_firewall_basic1(void)
-{
-       struct firewall_context *ctx;
-       int err;
-
-       ctx = __connman_firewall_create();
-       g_assert(ctx);
-
-       err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
-                                       "-m mark --mark 999 -j LOG");
-       g_assert(err >= 0);
-
-       err = __connman_firewall_add_rule(ctx, "filter", "OUTPUT",
-                                       "-m mark --mark 999 -j LOG");
-       g_assert(err >= 0);
-
-       err = __connman_firewall_enable(ctx);
-       g_assert(err == 0);
-
-       err = __connman_firewall_disable(ctx);
-       g_assert(err == 0);
-
-       __connman_firewall_destroy(ctx);
-}
-
-static void test_firewall_basic2(void)
-{
-       struct firewall_context *ctx;
-       int err;
-
-       ctx = __connman_firewall_create();
-       g_assert(ctx);
-
-       err = __connman_firewall_add_rule(ctx, "mangle", "INPUT",
-                                       "-j CONNMARK --restore-mark");
-       g_assert(err >= 0);
-
-       err = __connman_firewall_add_rule(ctx, "mangle", "POSTROUTING",
-                                       "-j CONNMARK --save-mark");
-       g_assert(err >= 0);
-
-       err = __connman_firewall_enable(ctx);
-       g_assert(err == 0);
-
-       err = __connman_firewall_disable(ctx);
-       g_assert(err == 0);
-
-       __connman_firewall_destroy(ctx);
-}
-
-static void test_firewall_basic3(void)
-{
-       struct firewall_context *ctx;
-       int err, id;
-
-       ctx = __connman_firewall_create();
-       g_assert(ctx);
-
-       id = __connman_firewall_add_rule(ctx, "mangle", "INPUT",
-                                       "-j CONNMARK --restore-mark");
-       g_assert(id >= 0);
-
-       err = __connman_firewall_enable_rule(ctx, id);
-       g_assert(err == 0);
-
-       err = __connman_firewall_disable_rule(ctx, id);
-       g_assert(err == 0);
-
-       err = __connman_firewall_remove_rule(ctx, id);
-       g_assert(err == 0);
-
-       err = __connman_firewall_disable(ctx);
-       g_assert(err == -ENOENT);
-
-       __connman_firewall_destroy(ctx);
-}
-
 static gchar *option_debug = NULL;
 
 static bool parse_debug(const char *key, const char *value,
@@ -558,7 +452,6 @@ int main(int argc, char *argv[])
                        "Unit Tests Connection Manager", VERSION);
 
        __connman_iptables_init();
-       __connman_firewall_init();
        __connman_nat_init();
 
        g_test_add_func("/iptables/chain0", test_iptables_chain0);
@@ -571,15 +464,10 @@ int main(int argc, char *argv[])
        g_test_add_func("/iptables/target0", test_iptables_target0);
        g_test_add_func("/nat/basic0", test_nat_basic0);
        g_test_add_func("/nat/basic1", test_nat_basic1);
-       g_test_add_func("/firewall/basic0", test_firewall_basic0);
-       g_test_add_func("/firewall/basic1", test_firewall_basic1);
-       g_test_add_func("/firewall/basic2", test_firewall_basic2);
-       g_test_add_func("/firewall/basic3", test_firewall_basic3);
 
        err = g_test_run();
 
        __connman_nat_cleanup();
-       __connman_firewall_cleanup();
        __connman_iptables_cleanup();
 
        g_free(option_debug);
-- 
2.5.5


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

Subject: Digest Footer

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


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

End of connman Digest, Vol 6, Issue 23
**************************************

Reply via email to