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. [RFC v0 0/3] Refactoring firewall and iptables code
      (Daniel Wagner)
   2. [RFC v0 1/3] firewall: Add explicit feature API (Daniel Wagner)
   3. [RFC v0 3/3] firewall: Add nftables build infrastructure
      (Daniel Wagner)
   4. [RFC v0 2/3] firewall: Rename firewall.c to
      firewall-iptables.c (Daniel Wagner)


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

Message: 1
Date: Wed,  2 Mar 2016 09:49:15 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [RFC v0 0/3] Refactoring firewall and iptables code
Message-ID: <[email protected]>

From: Daniel Wagner <[email protected]>

Hi,

here is the initial refactoring part for getting nftables support.

As you notice the arguments for the nat API is not as we discussed.
The main reason for this is that if we use struct connman_ipconfig as
argument tools/iptables-unit.c will pull in the complete ConnMan src
directory. I dropped the firewall tests just to get it compiling
again. Maybe we just delete those tests and have only iptables 'unit'
tests. In this case the nat API with struct connman_ipconfig could
just work fine.

All is just compile tested only. I just wanted to hear if this
direction is okay with you guys. And if yes, I'd like to get this in
before doing the nftables implementation.

What do you think?

cheers,
daniel

Daniel Wagner (3):
  firewall: Add explicit feature API
  firewall: Rename firewall.c to firewall-iptables.c
  firewall: Add nftables build infrastructure

 Makefile.am             |  48 +++-
 configure.ac            |  31 ++-
 src/connman.h           |  18 +-
 src/firewall-iptables.c | 677 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/firewall-nftables.c |  91 +++++++
 src/firewall.c          | 541 --------------------------------------
 src/main.c              |   2 -
 src/nat.c               |  21 +-
 src/session.c           | 133 +---------
 tools/iptables-unit.c   | 100 -------
 10 files changed, 860 insertions(+), 802 deletions(-)
 create mode 100644 src/firewall-iptables.c
 create mode 100644 src/firewall-nftables.c
 delete mode 100644 src/firewall.c

-- 
2.5.0


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

Message: 2
Date: Wed,  2 Mar 2016 09:49:16 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [RFC v0 1/3] firewall: Add explicit feature API
Message-ID: <[email protected]>

From: Daniel Wagner <[email protected]>

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

Apart of the code moving around we also drop the necessity to have
the global firewall table. This one was used to install the connection
tracking rule. We do instead install this rule when the first
session is activated and the last one goes away.
---
 src/connman.h         |  18 +++---
 src/firewall.c        | 168 +++++++++++++++++++++++++++++++++++++++++++++-----
 src/nat.c             |  21 +------
 src/session.c         | 133 +++++----------------------------------
 tools/iptables-unit.c | 100 ------------------------------
 5 files changed, 179 insertions(+), 261 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index 447bdd7..1e94123 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -989,13 +989,17 @@ 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_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, 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,
+                                       char *id, uint32_t mark);
+int __connman_firewall_disable_marking(struct firewall_context *ctx);
 int __connman_firewall_enable(struct firewall_context *ctx);
 int __connman_firewall_disable(struct firewall_context *ctx);
 bool __connman_firewall_is_up(void);
diff --git a/src/firewall.c b/src/firewall.c
index c5acc11..0350213 100644
--- a/src/firewall.c
+++ b/src/firewall.c
@@ -55,13 +55,15 @@ struct fw_rule {
 };
 
 struct firewall_context {
+       int ref;
        GList *rules;
+
+       int snat_id;
 };
 
 static GSList *managed_tables;
-
-static bool firewall_is_up;
 static unsigned int firewall_rule_id;
+static struct firewall_context *connmark_ctx;
 
 static int chain_to_index(const char *chain_name)
 {
@@ -262,6 +264,7 @@ struct firewall_context *__connman_firewall_create(void)
 
        ctx = g_new0(struct firewall_context, 1);
 
+       ctx->ref = 1;
        return ctx;
 }
 
@@ -319,7 +322,7 @@ static int firewall_disable_rule(struct fw_rule *rule)
        return 0;
 }
 
-int __connman_firewall_add_rule(struct firewall_context *ctx,
+static int firewall_add_rule(struct firewall_context *ctx,
                                const char *table,
                                const char *chain,
                                const char *rule_fmt, ...)
@@ -346,7 +349,7 @@ int __connman_firewall_add_rule(struct firewall_context 
*ctx,
        return rule->id;
 }
 
-int __connman_firewall_remove_rule(struct firewall_context *ctx, int id)
+static int firewall_remove_rule(struct firewall_context *ctx, int id)
 {
        struct fw_rule *rule;
        GList *list;
@@ -369,7 +372,7 @@ int __connman_firewall_remove_rule(struct firewall_context 
*ctx, int id)
        return err;
 }
 
-int __connman_firewall_enable_rule(struct firewall_context *ctx, int id)
+static int firewall_enable_rules(struct firewall_context *ctx, int id)
 {
        struct fw_rule *rule;
        GList *list;
@@ -391,7 +394,7 @@ int __connman_firewall_enable_rule(struct firewall_context 
*ctx, int id)
        return err;
 }
 
-int __connman_firewall_disable_rule(struct firewall_context *ctx, int id)
+static int firewall_disable_rules(struct firewall_context *ctx, int id)
 {
        struct fw_rule *rule;
        GList *list;
@@ -419,31 +422,165 @@ int __connman_firewall_disable_rule(struct 
firewall_context *ctx, int id)
        return err;
 }
 
-int __connman_firewall_enable(struct firewall_context *ctx)
+static int firewall_enable_context(struct firewall_context *ctx)
 {
        int err;
 
-       err = __connman_firewall_enable_rule(ctx, FW_ALL_RULES);
+       err = firewall_enable_rules(ctx, FW_ALL_RULES);
        if (err < 0) {
                connman_warn("Failed to install iptables rules: %s",
                                strerror(-err));
-               __connman_firewall_disable_rule(ctx, FW_ALL_RULES);
+               firewall_disable_rules(ctx, FW_ALL_RULES);
+               return err;
+       }
+
+       return 0;
+}
+
+static int firewall_disable_context(struct firewall_context *ctx)
+{
+       return firewall_disable_rules(ctx, FW_ALL_RULES);
+}
+
+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);
+
+       err = firewall_add_rule(ctx, "nat", "POSTROUTING", cmd);
+       g_free(cmd);
+       if (err < 0)
+               return err;
+
+       return firewall_enable_context(ctx);
+}
+
+int __connman_firewall_disable_nat(struct firewall_context *ctx)
+{
+       return firewall_disable_context(ctx);
+}
+
+int __connman_firewall_enable_snat(struct firewall_context *ctx,
+                               int index, char *ifname, const char *addr)
+{
+       int err, id;
+
+       id = firewall_add_rule(ctx, "nat", "POSTROUTING",
+                               "-o %s -j SNAT --to-source %s",
+                               ifname, addr);
+       g_free(ifname);
+
+       err = firewall_enable_rules(ctx, id);
+       if (err < 0) {
+               DBG("could not enable SNAT rule");
+               firewall_remove_rule(ctx, id);
+               return err;
+       }
+
+       ctx->snat_id = id;
+
+       return 0;
+}
+
+int __connman_firewall_disable_snat(struct firewall_context *ctx)
+{
+       int err;
+
+       err = firewall_disable_rules(ctx, ctx->snat_id);
+       if (err < 0) {
+               DBG("could not disable SNAT rule");
                return err;
        }
 
-       firewall_is_up = true;
+       err = firewall_remove_rule(ctx, ctx->snat_id);
+       if (err < 0)
+               DBG("could not remove SNAT rule");
+
+       return err;
+}
+
+static int firewall_enable_connmark(void)
+{
+       int err;
+
+       if (connmark_ctx) {
+               connmark_ctx->ref++;
+               return 0;
+       }
+
+       connmark_ctx = __connman_firewall_create();
+
+       err = firewall_add_rule(connmark_ctx, "mangle", "INPUT",
+                                       "-j CONNMARK --restore-mark");
+       if (err < 0)
+               goto err;
+
+       err = firewall_add_rule(connmark_ctx, "mangle", "POSTROUTING",
+                                       "-j CONNMARK --save-mark");
+       if (err < 0)
+               goto err;
 
        return 0;
+err:
+       __connman_firewall_destroy(connmark_ctx);
+       connmark_ctx = NULL;
+
+       return err;
 }
 
-int __connman_firewall_disable(struct firewall_context *ctx)
+static int firewall_disable_connmark(void)
 {
-       return __connman_firewall_disable_rule(ctx, FW_ALL_RULES);
+       connmark_ctx->ref--;
+       if (connmark_ctx->ref > 1)
+               return 0;
+
+       __connman_firewall_destroy(connmark_ctx);
+       connmark_ctx = NULL;
+
+       return 0;
 }
 
-bool __connman_firewall_is_up(void)
+int __connman_firewall_enable_marking(struct firewall_context *ctx,
+                                       enum connman_session_id_type id_type,
+                                       char *id, uint32_t mark)
 {
-       return firewall_is_up;
+       int err;
+
+       err = firewall_enable_connmark();
+       if (err)
+               return err;
+
+       switch (id_type) {
+       case CONNMAN_SESSION_ID_TYPE_UID:
+               err = 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:
+               err = 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:
+               err = -EINVAL;
+       }
+
+       if (err < 0)
+               return err;
+
+       return firewall_enable_context(ctx);
+}
+
+int __connman_firewall_disable_marking(struct firewall_context *ctx)
+{
+       firewall_disable_connmark();
+       return firewall_disable_context(ctx);
 }
 
 static void iterate_chains_cb(const char *chain_name, void *user_data)
@@ -513,12 +650,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 063f085..5ac8d5c 100644
--- a/src/nat.c
+++ b/src/nat.c
@@ -60,28 +60,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)
@@ -89,8 +75,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 388aae7..c8238e2 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,
@@ -69,7 +68,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;
@@ -197,49 +195,6 @@ static char *service2bearer(enum connman_service_type type)
        return "";
 }
 
-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;
@@ -250,49 +205,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)
@@ -300,7 +228,7 @@ 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_destroy(session->fw);
 
        session->fw = NULL;
@@ -368,23 +296,12 @@ static void add_default_route(struct connman_session 
*session)
 
 static void del_nat_rules(struct connman_session *session)
 {
-       int err;
-
-       if (!session->fw || session->snat_id == 0)
-               return;
-
-       err = __connman_firewall_disable_rule(session->fw, session->snat_id);
-       if (err < 0) {
-               DBG("could not disable SNAT rule");
+       if (!session->fw)
                return;
-       }
-
-       err = __connman_firewall_remove_rule(session->fw, session->snat_id);
-       if (err < 0)
-               DBG("could not remove SNAT rule");
 
+       DBG("");
 
-       session->snat_id = 0;
+       __connman_firewall_disable_nat(session->fw);
 }
 
 static void add_nat_rules(struct connman_session *session)
@@ -392,7 +309,7 @@ static void add_nat_rules(struct connman_session *session)
        struct connman_ipconfig *ipconfig;
        const char *addr;
        char *ifname;
-       int index, id, err;
+       int index, id;
 
        if (!session->fw)
                return;
@@ -404,23 +321,9 @@ static void add_nat_rules(struct connman_session *session)
        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");
+       id = __connman_firewall_enable_snat(session->fw, index, ifname, addr);
+       if (id < 0)
                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;
-       }
-
-       session->snat_id = id;
 }
 
 static void cleanup_routing_table(struct connman_session *session)
@@ -1795,12 +1698,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;
 }
 
@@ -1811,8 +1708,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 9c09867..c4e83c3 100644
--- a/tools/iptables-unit.c
+++ b/tools/iptables-unit.c
@@ -406,105 +406,8 @@ static void test_nat_basic1(void)
 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);
 }
@@ -569,9 +472,6 @@ int main(int argc, char *argv[])
        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();
 
-- 
2.5.0


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

Message: 3
Date: Wed,  2 Mar 2016 09:49:18 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [RFC v0 3/3] firewall: Add nftables build infrastructure
Message-ID: <[email protected]>

From: Daniel Wagner <[email protected]>

Introduce --with-firewall configuration flag which is on default
iptables. You can enable nftables by providing --with-firewall=nftables.
---
 Makefile.am             | 10 ++++++
 configure.ac            | 32 ++++++++++++++---
 src/firewall-nftables.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 128 insertions(+), 5 deletions(-)
 create mode 100644 src/firewall-nftables.c

diff --git a/Makefile.am b/Makefile.am
index 48188f9..9c13630 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -142,6 +142,11 @@ src_connmand_SOURCES += src/iptables.c 
src/firewall-iptables.c
 src_connmand_LDADD += @XTABLES_LIBS@
 endif
 
+if NFTABLES
+src_connmand_SOURCES += src/firewall-nftables.c
+src_connmand_LDADD +=  @NFTABLES_LIBS@
+endif
+
 if VPN
 vpn_plugin_LTLIBRARIES =
 
@@ -262,6 +267,11 @@ AM_CFLAGS += @XTABLES_CFLAGS@
 src_connmand_CFLAGS += @XTABLES_CFLAGS@
 endif
 
+if NFTABLES
+AM_CFLAGS += @NFTABLES_CFLAGS@
+src_connmand_CFLAGS += @NFTABLES_CFLAGS@
+endif
+
 EXTRA_DIST += vpn/vpn-dbus.conf vpn/vpn-polkit.conf
 
 script_DATA =
diff --git a/configure.ac b/configure.ac
index a63269a..a63d4ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -265,11 +265,33 @@ if (test -n "${path_tmpfiles}"); then
        AC_SUBST(SYSTEMD_TMPFILESDIR)
 fi
 
-PKG_CHECK_MODULES(XTABLES, xtables >= 1.4.11, dummy=yes,
-                               AC_MSG_ERROR(Xtables library is required))
-AC_SUBST(XTABLES_CFLAGS)
-AC_SUBST(XTABLES_LIBS)
-AM_CONDITIONAL(XTABLES, test "${XTABLES}" != "no")
+AC_ARG_WITH(firewall, AC_HELP_STRING([--with-firewall=TYPE],
+                       [specify which firewall type is used iptables or 
nftables \[default=iptables\]]),
+               [firewall_type=${withval}],
+               [firewall_type="iptables"])
+
+if (test "${firewall_type}" != "iptables" -a \
+               "${firewall_type}" != "nftables"); then
+       AC_MSG_ERROR(neither nftables nor iptables support enabled)
+fi
+
+found_iptables="no"
+if (test "${firewall_type}" = "iptables"); then
+       PKG_CHECK_MODULES(XTABLES, xtables >= 1.4.11, [found_iptables="yes"],
+                       AC_MSG_ERROR(Xtables library is required))
+       AC_SUBST(XTABLES_CFLAGS)
+       AC_SUBST(XTABLES_LIBS)
+fi
+AM_CONDITIONAL(XTABLES, test "${found_iptables}" != "no")
+
+found_nftables="no"
+if (test "${firewall_type}" = "nftables"); then
+       PKG_CHECK_MODULES(NFTABLES, [libnftnl >= 1.0.4 libmnl >= 1.0.0], 
[found_nftables="yes"],
+               AC_MSG_ERROR([libnfntl >= 1.0.4 or libmnl >= 1.0.0 not found]))
+       AC_SUBST(NFTABLES_CFLAGS)
+       AC_SUBST(NFTABLES_LIBS)
+fi
+AM_CONDITIONAL(NFTABLES, test "${found_nftables}" != "no")
 
 AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test],
                [enable test/example scripts]), [enable_test=${enableval}])
diff --git a/src/firewall-nftables.c b/src/firewall-nftables.c
new file mode 100644
index 0000000..80131fe
--- /dev/null
+++ b/src/firewall-nftables.c
@@ -0,0 +1,91 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2016  BMW Car IT GmbH.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+
+#include "connman.h"
+
+struct firewall_context *__connman_firewall_create(void)
+{
+       return NULL;
+}
+
+void __connman_firewall_destroy(struct firewall_context *ctx)
+{
+}
+
+int __connman_firewall_enable_nat(struct firewall_context *ctx,
+                                       char *address, unsigned char prefixlen,
+                                       char *interface)
+{
+       return -EPROTONOSUPPORT;
+}
+
+int __connman_firewall_disable_nat(struct firewall_context *ctx)
+{
+       return -EPROTONOSUPPORT;
+}
+
+int __connman_firewall_enable_snat(struct firewall_context *ctx,
+                               int index, char *ifname, const char *addr)
+{
+       return -EPROTONOSUPPORT;
+}
+
+int __connman_firewall_disable_snat(struct firewall_context *ctx)
+{
+       return -EPROTONOSUPPORT;
+}
+
+int __connman_firewall_enable_marking(struct firewall_context *ctx,
+                                       enum connman_session_id_type id_type,
+                                       char *id, uint32_t mark)
+{
+       return -EPROTONOSUPPORT;
+}
+
+int __connman_firewall_disable_marking(struct firewall_context *ctx)
+{
+       return -EPROTONOSUPPORT;
+}
+
+int __connman_firewall_enable(struct firewall_context *ctx)
+{
+       return -EPROTONOSUPPORT;
+}
+
+int __connman_firewall_disable(struct firewall_context *ctx)
+{
+       return -EPROTONOSUPPORT;
+}
+
+int __connman_firewall_init(void)
+{
+       return 0;
+}
+
+void __connman_firewall_cleanup(void)
+{
+}
-- 
2.5.0


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

Message: 4
Date: Wed,  2 Mar 2016 09:49:17 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [RFC v0 2/3] firewall: Rename firewall.c to
        firewall-iptables.c
Message-ID: <[email protected]>

From: Daniel Wagner <[email protected]>

There is little point in keeping the orignal firewall implementation.
It is designed based on iptables.c API. For nftables it is just
better to start from fresh. The gives the necessary freedom to really
exploit the nftables API without fearing to break the working iptables
implementation. That should also make testing considerable more simpler.
---
 Makefile.am             |  38 ++-
 configure.ac            |   1 +
 src/firewall-iptables.c | 677 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/firewall.c          | 675 -----------------------------------------------
 src/main.c              |   2 -
 5 files changed, 705 insertions(+), 688 deletions(-)
 create mode 100644 src/firewall-iptables.c
 delete mode 100644 src/firewall.c

diff --git a/Makefile.am b/Makefile.am
index d70725c..48188f9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -120,13 +120,13 @@ src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) 
$(backtrace_sources) \
                        src/storage.c src/dbus.c src/config.c \
                        src/technology.c src/counter.c src/ntp.c \
                        src/session.c src/tethering.c src/wpad.c src/wispr.c \
-                       src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \
+                       src/stats.c src/dnsproxy.c src/6to4.c \
                        src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \
-                       src/inotify.c src/firewall.c src/ipv6pd.c src/peer.c \
+                       src/inotify.c src/ipv6pd.c src/peer.c \
                        src/peer_service.c src/machine.c src/util.c
 
 src_connmand_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
-                       @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ @GNUTLS_LIBS@ \
+                       @GLIB_LIBS@ @DBUS_LIBS@ @GNUTLS_LIBS@ \
                        -lresolv -ldl -lrt
 
 src_connmand_LDFLAGS = -Wl,--export-dynamic \
@@ -137,6 +137,11 @@ src_connmand_wait_online_SOURCES = 
src/connmand-wait-online.c
 src_connmand_wait_online_LDADD = gdbus/libgdbus-internal.la \
                        @GLIB_LIBS@ @DBUS_LIBS@
 
+if XTABLES
+src_connmand_SOURCES += src/iptables.c src/firewall-iptables.c
+src_connmand_LDADD += @XTABLES_LIBS@
+endif
+
 if VPN
 vpn_plugin_LTLIBRARIES =
 
@@ -206,7 +211,7 @@ build_vpn_plugindir = $(vpn_plugindir)
 endif
 endif
 
-AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
+AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
                                @GNUTLS_CFLAGS@ $(builtin_cflags) \
                                -DCONNMAN_PLUGIN_BUILTIN \
                                -DSTATEDIR=\""$(statedir)"\" \
@@ -223,7 +228,7 @@ else
 AM_CPPFLAGS = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/gdbus
 endif
 
-src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
+src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
                                @GNUTLS_CFLAGS@ $(builtin_cflags) \
                                -DCONNMAN_PLUGIN_BUILTIN \
                                -DSTATEDIR=\""$(statedir)"\" \
@@ -252,6 +257,11 @@ vpn_connman_vpnd_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
 
 endif
 
+if XTABLES
+AM_CFLAGS += @XTABLES_CFLAGS@
+src_connmand_CFLAGS += @XTABLES_CFLAGS@
+endif
+
 EXTRA_DIST += vpn/vpn-dbus.conf vpn/vpn-polkit.conf
 
 script_DATA =
@@ -297,9 +307,9 @@ noinst_PROGRAMS += tools/supplicant-test \
                        tools/dhcp-test tools/dhcp-server-test \
                        tools/addr-test tools/web-test tools/resolv-test \
                        tools/dbus-test tools/polkit-test \
-                       tools/iptables-test tools/tap-test tools/wpad-test \
+                       tools/tap-test tools/wpad-test \
                        tools/stats-tool tools/private-network-test \
-                       tools/session-test tools/iptables-unit \
+                       tools/session-test \
                        tools/dnsproxy-test tools/netlink-test
 
 tools_supplicant_test_SOURCES = tools/supplicant-test.c \
@@ -330,9 +340,6 @@ tools_dbus_test_LDADD = gdbus/libgdbus-internal.la 
@GLIB_LIBS@ @DBUS_LIBS@
 
 tools_polkit_test_LDADD = @DBUS_LIBS@
 
-tools_iptables_test_SOURCES = $(backtrace_sources) src/log.c src/iptables.c 
tools/iptables-test.c
-tools_iptables_test_LDADD = @GLIB_LIBS@ @XTABLES_LIBS@ -ldl
-
 tools_private_network_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
 
 tools_session_test_SOURCES = $(backtrace_sources) src/log.c src/dbus.c 
src/error.c \
@@ -341,12 +348,21 @@ tools_session_test_SOURCES = $(backtrace_sources) 
src/log.c src/dbus.c src/error
 tools_session_test_LDADD = gdbus/libgdbus-internal.la \
                                @GLIB_LIBS@ @DBUS_LIBS@ -ldl
 
+if XTABLES
+noinst_PROGRAMS += tools/iptables-test tools/iptables-unit
+
+tools_iptables_test_SOURCES = $(backtrace_sources) src/log.c src/iptables.c \
+                               tools/iptables-test.c
+tools_iptables_test_LDADD = @GLIB_LIBS@ @XTABLES_LIBS@ -ldl
+
 tools_iptables_unit_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
                -DIPTABLES_SAVE=\""${IPTABLES_SAVE}"\"
 tools_iptables_unit_SOURCES = $(backtrace_sources) src/log.c \
-                src/iptables.c src/firewall.c src/nat.c tools/iptables-unit.c
+               src/iptables.c src/firewall-iptables.c src/nat.c \
+               tools/iptables-unit.c
 tools_iptables_unit_LDADD = gdbus/libgdbus-internal.la \
                                @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ -ldl
+endif
 
 tools_dnsproxy_test_SOURCES = tools/dnsproxy-test.c
 tools_dnsproxy_test_LDADD = @GLIB_LIBS@
diff --git a/configure.ac b/configure.ac
index 9a5a70e..a63269a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -269,6 +269,7 @@ PKG_CHECK_MODULES(XTABLES, xtables >= 1.4.11, dummy=yes,
                                AC_MSG_ERROR(Xtables library is required))
 AC_SUBST(XTABLES_CFLAGS)
 AC_SUBST(XTABLES_LIBS)
+AM_CONDITIONAL(XTABLES, test "${XTABLES}" != "no")
 
 AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test],
                [enable test/example scripts]), [enable_test=${enableval}])
diff --git a/src/firewall-iptables.c b/src/firewall-iptables.c
new file mode 100644
index 0000000..ae92dde
--- /dev/null
+++ b/src/firewall-iptables.c
@@ -0,0 +1,677 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2013,2015  BMW Car IT GmbH.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+
+#include <xtables.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+#include "connman.h"
+
+#define CHAIN_PREFIX "connman-"
+#define FW_ALL_RULES -1
+
+static const char *builtin_chains[] = {
+       [NF_IP_PRE_ROUTING]     = "PREROUTING",
+       [NF_IP_LOCAL_IN]        = "INPUT",
+       [NF_IP_FORWARD]         = "FORWARD",
+       [NF_IP_LOCAL_OUT]       = "OUTPUT",
+       [NF_IP_POST_ROUTING]    = "POSTROUTING",
+};
+
+struct connman_managed_table {
+       char *name;
+       unsigned int chains[NF_INET_NUMHOOKS];
+};
+
+struct fw_rule {
+       int id;
+       bool enabled;
+       char *table;
+       char *chain;
+       char *rule_spec;
+};
+
+struct firewall_context {
+       int ref;
+       GList *rules;
+
+       int snat_id;
+};
+
+static GSList *managed_tables;
+static unsigned int firewall_rule_id;
+static struct firewall_context *connmark_ctx;
+
+static int chain_to_index(const char *chain_name)
+{
+       if (!g_strcmp0(builtin_chains[NF_IP_PRE_ROUTING], chain_name))
+               return NF_IP_PRE_ROUTING;
+       if (!g_strcmp0(builtin_chains[NF_IP_LOCAL_IN], chain_name))
+               return NF_IP_LOCAL_IN;
+       if (!g_strcmp0(builtin_chains[NF_IP_FORWARD], chain_name))
+               return NF_IP_FORWARD;
+       if (!g_strcmp0(builtin_chains[NF_IP_LOCAL_OUT], chain_name))
+               return NF_IP_LOCAL_OUT;
+       if (!g_strcmp0(builtin_chains[NF_IP_POST_ROUTING], chain_name))
+               return NF_IP_POST_ROUTING;
+
+       return -1;
+}
+
+static int managed_chain_to_index(const char *chain_name)
+{
+       if (!g_str_has_prefix(chain_name, CHAIN_PREFIX))
+               return -1;
+
+       return chain_to_index(chain_name + strlen(CHAIN_PREFIX));
+}
+
+static int insert_managed_chain(const char *table_name, int id)
+{
+       char *rule, *managed_chain;
+       int err;
+
+       managed_chain = g_strdup_printf("%s%s", CHAIN_PREFIX,
+                                       builtin_chains[id]);
+
+       err = __connman_iptables_new_chain(table_name, managed_chain);
+       if (err < 0)
+               goto out;
+
+       rule = g_strdup_printf("-j %s", managed_chain);
+       err = __connman_iptables_insert(table_name, builtin_chains[id], rule);
+       g_free(rule);
+       if (err < 0) {
+               __connman_iptables_delete_chain(table_name, managed_chain);
+               goto out;
+       }
+
+out:
+       g_free(managed_chain);
+
+       return err;
+}
+
+static int delete_managed_chain(const char *table_name, int id)
+{
+       char *rule, *managed_chain;
+       int err;
+
+       managed_chain = g_strdup_printf("%s%s", CHAIN_PREFIX,
+                                       builtin_chains[id]);
+
+       rule = g_strdup_printf("-j %s", managed_chain);
+       err = __connman_iptables_delete(table_name, builtin_chains[id], rule);
+       g_free(rule);
+
+       if (err < 0)
+               goto out;
+
+       err =  __connman_iptables_delete_chain(table_name, managed_chain);
+
+out:
+       g_free(managed_chain);
+
+       return err;
+}
+
+static int insert_managed_rule(const char *table_name,
+                               const char *chain_name,
+                               const char *rule_spec)
+{
+       struct connman_managed_table *mtable = NULL;
+       GSList *list;
+       char *chain;
+       int id, err;
+
+       id = chain_to_index(chain_name);
+       if (id < 0) {
+               /* This chain is not managed */
+               chain = g_strdup(chain_name);
+               goto out;
+       }
+
+       for (list = managed_tables; list; list = list->next) {
+               mtable = list->data;
+
+               if (g_strcmp0(mtable->name, table_name) == 0)
+                       break;
+
+               mtable = NULL;
+       }
+
+       if (!mtable) {
+               mtable = g_new0(struct connman_managed_table, 1);
+               mtable->name = g_strdup(table_name);
+
+               managed_tables = g_slist_prepend(managed_tables, mtable);
+       }
+
+       if (mtable->chains[id] == 0) {
+               DBG("table %s add managed chain for %s",
+                       table_name, chain_name);
+
+               err = insert_managed_chain(table_name, id);
+               if (err < 0)
+                       return err;
+       }
+
+       mtable->chains[id]++;
+       chain = g_strdup_printf("%s%s", CHAIN_PREFIX, chain_name);
+
+out:
+       err = __connman_iptables_append(table_name, chain, rule_spec);
+
+       g_free(chain);
+
+       return err;
+ }
+
+static int delete_managed_rule(const char *table_name,
+                               const char *chain_name,
+                               const char *rule_spec)
+ {
+       struct connman_managed_table *mtable = NULL;
+       GSList *list;
+       int id, err;
+       char *managed_chain;
+
+       id = chain_to_index(chain_name);
+       if (id < 0) {
+               /* This chain is not managed */
+               return __connman_iptables_delete(table_name, chain_name,
+                                                       rule_spec);
+       }
+
+       managed_chain = g_strdup_printf("%s%s", CHAIN_PREFIX, chain_name);
+
+       err = __connman_iptables_delete(table_name, managed_chain,
+                                       rule_spec);
+
+       for (list = managed_tables; list; list = list->next) {
+               mtable = list->data;
+
+               if (g_strcmp0(mtable->name, table_name) == 0)
+                       break;
+
+               mtable = NULL;
+       }
+
+       if (!mtable) {
+               err = -ENOENT;
+               goto out;
+       }
+
+       mtable->chains[id]--;
+       if (mtable->chains[id] > 0)
+               goto out;
+
+       DBG("table %s remove managed chain for %s",
+                       table_name, chain_name);
+
+       err = delete_managed_chain(table_name, id);
+
+ out:
+       g_free(managed_chain);
+
+       return err;
+}
+
+static void cleanup_managed_table(gpointer user_data)
+{
+       struct connman_managed_table *table = user_data;
+
+       g_free(table->name);
+       g_free(table);
+}
+
+static void cleanup_fw_rule(gpointer user_data)
+{
+       struct fw_rule *rule = user_data;
+
+       g_free(rule->rule_spec);
+       g_free(rule->chain);
+       g_free(rule->table);
+       g_free(rule);
+}
+
+struct firewall_context *__connman_firewall_create(void)
+{
+       struct firewall_context *ctx;
+
+       ctx = g_new0(struct firewall_context, 1);
+
+       ctx->ref = 1;
+       return ctx;
+}
+
+void __connman_firewall_destroy(struct firewall_context *ctx)
+{
+       g_list_free_full(ctx->rules, cleanup_fw_rule);
+       g_free(ctx);
+}
+
+static int firewall_enable_rule(struct fw_rule *rule)
+{
+       int err;
+
+       if (rule->enabled)
+               return -EALREADY;
+
+       DBG("%s %s %s", rule->table, rule->chain, rule->rule_spec);
+
+       err = insert_managed_rule(rule->table, rule->chain, rule->rule_spec);
+       if (err < 0)
+               return err;
+
+       err = __connman_iptables_commit(rule->table);
+       if (err < 0)
+               return err;
+
+       rule->enabled = true;
+
+       return 0;
+}
+
+static int firewall_disable_rule(struct fw_rule *rule)
+{
+       int err;
+
+       if (!rule->enabled)
+               return -EALREADY;
+
+       err = delete_managed_rule(rule->table, rule->chain, rule->rule_spec);
+       if (err < 0) {
+               connman_error("Cannot remove previously installed "
+                       "iptables rules: %s", strerror(-err));
+               return err;
+       }
+
+       err = __connman_iptables_commit(rule->table);
+       if (err < 0) {
+               connman_error("Cannot remove previously installed "
+                       "iptables rules: %s", strerror(-err));
+               return err;
+       }
+
+       rule->enabled = false;
+
+       return 0;
+}
+
+static int firewall_add_rule(struct firewall_context *ctx,
+                               const char *table,
+                               const char *chain,
+                               const char *rule_fmt, ...)
+{
+       va_list args;
+       char *rule_spec;
+       struct fw_rule *rule;
+
+       va_start(args, rule_fmt);
+
+       rule_spec = g_strdup_vprintf(rule_fmt, args);
+
+       va_end(args);
+
+       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;
+}
+
+static int firewall_remove_rule(struct firewall_context *ctx, int id)
+{
+       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;
+               }
+       }
+
+       return err;
+}
+
+static int firewall_enable_rules(struct firewall_context *ctx, int id)
+{
+       struct fw_rule *rule;
+       GList *list;
+       int err = -ENOENT;
+
+       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;
+               }
+       }
+
+       return err;
+}
+
+static int firewall_disable_rules(struct firewall_context *ctx, int id)
+{
+       struct fw_rule *rule;
+       GList *list;
+       int e;
+       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) {
+                       e = firewall_disable_rule(rule);
+
+                       /* 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;
+}
+
+static int firewall_enable_context(struct firewall_context *ctx)
+{
+       int err;
+
+       err = firewall_enable_rules(ctx, FW_ALL_RULES);
+       if (err < 0) {
+               connman_warn("Failed to install iptables rules: %s",
+                               strerror(-err));
+               firewall_disable_rules(ctx, FW_ALL_RULES);
+               return err;
+       }
+
+       return 0;
+}
+
+static int firewall_disable_context(struct firewall_context *ctx)
+{
+       return firewall_disable_rules(ctx, FW_ALL_RULES);
+}
+
+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);
+
+       err = firewall_add_rule(ctx, "nat", "POSTROUTING", cmd);
+       g_free(cmd);
+       if (err < 0)
+               return err;
+
+       return firewall_enable_context(ctx);
+}
+
+int __connman_firewall_disable_nat(struct firewall_context *ctx)
+{
+       return firewall_disable_context(ctx);
+}
+
+int __connman_firewall_enable_snat(struct firewall_context *ctx,
+                               int index, char *ifname, const char *addr)
+{
+       int err, id;
+
+       id = firewall_add_rule(ctx, "nat", "POSTROUTING",
+                               "-o %s -j SNAT --to-source %s",
+                               ifname, addr);
+       g_free(ifname);
+
+       err = firewall_enable_rules(ctx, id);
+       if (err < 0) {
+               DBG("could not enable SNAT rule");
+               firewall_remove_rule(ctx, id);
+               return err;
+       }
+
+       ctx->snat_id = id;
+
+       return 0;
+}
+
+int __connman_firewall_disable_snat(struct firewall_context *ctx)
+{
+       int err;
+
+       err = firewall_disable_rules(ctx, ctx->snat_id);
+       if (err < 0) {
+               DBG("could not disable SNAT rule");
+               return err;
+       }
+
+       err = firewall_remove_rule(ctx, ctx->snat_id);
+       if (err < 0)
+               DBG("could not remove SNAT rule");
+
+       return err;
+}
+
+static int firewall_enable_connmark(void)
+{
+       int err;
+
+       if (connmark_ctx) {
+               connmark_ctx->ref++;
+               return 0;
+       }
+
+       connmark_ctx = __connman_firewall_create();
+
+       err = firewall_add_rule(connmark_ctx, "mangle", "INPUT",
+                                       "-j CONNMARK --restore-mark");
+       if (err < 0)
+               goto err;
+
+       err = firewall_add_rule(connmark_ctx, "mangle", "POSTROUTING",
+                                       "-j CONNMARK --save-mark");
+       if (err < 0)
+               goto err;
+
+       return 0;
+err:
+       __connman_firewall_destroy(connmark_ctx);
+       connmark_ctx = NULL;
+
+       return err;
+}
+
+static int firewall_disable_connmark(void)
+{
+       connmark_ctx->ref--;
+       if (connmark_ctx->ref > 1)
+               return 0;
+
+       __connman_firewall_destroy(connmark_ctx);
+       connmark_ctx = NULL;
+
+       return 0;
+}
+
+int __connman_firewall_enable_marking(struct firewall_context *ctx,
+                                       enum connman_session_id_type id_type,
+                                       char *id, uint32_t mark)
+{
+       int err;
+
+       err = firewall_enable_connmark();
+       if (err)
+               return err;
+
+       switch (id_type) {
+       case CONNMAN_SESSION_ID_TYPE_UID:
+               err = 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:
+               err = 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:
+               err = -EINVAL;
+       }
+
+       if (err < 0)
+               return err;
+
+       return firewall_enable_context(ctx);
+}
+
+int __connman_firewall_disable_marking(struct firewall_context *ctx)
+{
+       firewall_disable_connmark();
+       return firewall_disable_context(ctx);
+}
+
+static void iterate_chains_cb(const char *chain_name, void *user_data)
+{
+       GSList **chains = user_data;
+       int id;
+
+       id = managed_chain_to_index(chain_name);
+       if (id < 0)
+               return;
+
+       *chains = g_slist_prepend(*chains, GINT_TO_POINTER(id));
+}
+
+static void flush_table(const char *table_name)
+{
+       GSList *chains = NULL, *list;
+       char *rule, *managed_chain;
+       int id, err;
+
+       __connman_iptables_iterate_chains(table_name, iterate_chains_cb,
+                                               &chains);
+
+       for (list = chains; list; list = list->next) {
+               id = GPOINTER_TO_INT(list->data);
+
+               managed_chain = g_strdup_printf("%s%s", CHAIN_PREFIX,
+                                               builtin_chains[id]);
+
+               rule = g_strdup_printf("-j %s", managed_chain);
+               err = __connman_iptables_delete(table_name,
+                                               builtin_chains[id], rule);
+               if (err < 0) {
+                       connman_warn("Failed to delete jump rule '%s': %s",
+                               rule, strerror(-err));
+               }
+               g_free(rule);
+
+               err = __connman_iptables_flush_chain(table_name, managed_chain);
+               if (err < 0) {
+                       connman_warn("Failed to flush chain '%s': %s",
+                               managed_chain, strerror(-err));
+               }
+               err = __connman_iptables_delete_chain(table_name, 
managed_chain);
+               if (err < 0) {
+                       connman_warn("Failed to delete chain '%s': %s",
+                               managed_chain, strerror(-err));
+               }
+
+               g_free(managed_chain);
+       }
+
+       err = __connman_iptables_commit(table_name);
+       if (err < 0) {
+               connman_warn("Failed to flush table '%s': %s",
+                       table_name, strerror(-err));
+       }
+
+       g_slist_free(chains);
+}
+
+static void flush_all_tables(void)
+{
+       /* Flush the tables ConnMan might have modified
+        * But do so if only ConnMan has done something with
+        * iptables */
+
+       if (!g_file_test("/proc/net/ip_tables_names",
+                       G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+               return;
+       }
+
+       flush_table("filter");
+       flush_table("mangle");
+       flush_table("nat");
+}
+
+int __connman_firewall_init(void)
+{
+       DBG("");
+
+       __connman_iptables_init();
+       flush_all_tables();
+
+       return 0;
+}
+
+void __connman_firewall_cleanup(void)
+{
+       DBG("");
+
+       g_slist_free_full(managed_tables, cleanup_managed_table);
+       __connman_iptables_cleanup();
+}
diff --git a/src/firewall.c b/src/firewall.c
deleted file mode 100644
index 0350213..0000000
--- a/src/firewall.c
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- *
- *  Connection Manager
- *
- *  Copyright (C) 2013,2015  BMW Car IT GmbH.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-
-#include <xtables.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-
-#include "connman.h"
-
-#define CHAIN_PREFIX "connman-"
-#define FW_ALL_RULES -1
-
-static const char *builtin_chains[] = {
-       [NF_IP_PRE_ROUTING]     = "PREROUTING",
-       [NF_IP_LOCAL_IN]        = "INPUT",
-       [NF_IP_FORWARD]         = "FORWARD",
-       [NF_IP_LOCAL_OUT]       = "OUTPUT",
-       [NF_IP_POST_ROUTING]    = "POSTROUTING",
-};
-
-struct connman_managed_table {
-       char *name;
-       unsigned int chains[NF_INET_NUMHOOKS];
-};
-
-struct fw_rule {
-       int id;
-       bool enabled;
-       char *table;
-       char *chain;
-       char *rule_spec;
-};
-
-struct firewall_context {
-       int ref;
-       GList *rules;
-
-       int snat_id;
-};
-
-static GSList *managed_tables;
-static unsigned int firewall_rule_id;
-static struct firewall_context *connmark_ctx;
-
-static int chain_to_index(const char *chain_name)
-{
-       if (!g_strcmp0(builtin_chains[NF_IP_PRE_ROUTING], chain_name))
-               return NF_IP_PRE_ROUTING;
-       if (!g_strcmp0(builtin_chains[NF_IP_LOCAL_IN], chain_name))
-               return NF_IP_LOCAL_IN;
-       if (!g_strcmp0(builtin_chains[NF_IP_FORWARD], chain_name))
-               return NF_IP_FORWARD;
-       if (!g_strcmp0(builtin_chains[NF_IP_LOCAL_OUT], chain_name))
-               return NF_IP_LOCAL_OUT;
-       if (!g_strcmp0(builtin_chains[NF_IP_POST_ROUTING], chain_name))
-               return NF_IP_POST_ROUTING;
-
-       return -1;
-}
-
-static int managed_chain_to_index(const char *chain_name)
-{
-       if (!g_str_has_prefix(chain_name, CHAIN_PREFIX))
-               return -1;
-
-       return chain_to_index(chain_name + strlen(CHAIN_PREFIX));
-}
-
-static int insert_managed_chain(const char *table_name, int id)
-{
-       char *rule, *managed_chain;
-       int err;
-
-       managed_chain = g_strdup_printf("%s%s", CHAIN_PREFIX,
-                                       builtin_chains[id]);
-
-       err = __connman_iptables_new_chain(table_name, managed_chain);
-       if (err < 0)
-               goto out;
-
-       rule = g_strdup_printf("-j %s", managed_chain);
-       err = __connman_iptables_insert(table_name, builtin_chains[id], rule);
-       g_free(rule);
-       if (err < 0) {
-               __connman_iptables_delete_chain(table_name, managed_chain);
-               goto out;
-       }
-
-out:
-       g_free(managed_chain);
-
-       return err;
-}
-
-static int delete_managed_chain(const char *table_name, int id)
-{
-       char *rule, *managed_chain;
-       int err;
-
-       managed_chain = g_strdup_printf("%s%s", CHAIN_PREFIX,
-                                       builtin_chains[id]);
-
-       rule = g_strdup_printf("-j %s", managed_chain);
-       err = __connman_iptables_delete(table_name, builtin_chains[id], rule);
-       g_free(rule);
-
-       if (err < 0)
-               goto out;
-
-       err =  __connman_iptables_delete_chain(table_name, managed_chain);
-
-out:
-       g_free(managed_chain);
-
-       return err;
-}
-
-static int insert_managed_rule(const char *table_name,
-                               const char *chain_name,
-                               const char *rule_spec)
-{
-       struct connman_managed_table *mtable = NULL;
-       GSList *list;
-       char *chain;
-       int id, err;
-
-       id = chain_to_index(chain_name);
-       if (id < 0) {
-               /* This chain is not managed */
-               chain = g_strdup(chain_name);
-               goto out;
-       }
-
-       for (list = managed_tables; list; list = list->next) {
-               mtable = list->data;
-
-               if (g_strcmp0(mtable->name, table_name) == 0)
-                       break;
-
-               mtable = NULL;
-       }
-
-       if (!mtable) {
-               mtable = g_new0(struct connman_managed_table, 1);
-               mtable->name = g_strdup(table_name);
-
-               managed_tables = g_slist_prepend(managed_tables, mtable);
-       }
-
-       if (mtable->chains[id] == 0) {
-               DBG("table %s add managed chain for %s",
-                       table_name, chain_name);
-
-               err = insert_managed_chain(table_name, id);
-               if (err < 0)
-                       return err;
-       }
-
-       mtable->chains[id]++;
-       chain = g_strdup_printf("%s%s", CHAIN_PREFIX, chain_name);
-
-out:
-       err = __connman_iptables_append(table_name, chain, rule_spec);
-
-       g_free(chain);
-
-       return err;
- }
-
-static int delete_managed_rule(const char *table_name,
-                               const char *chain_name,
-                               const char *rule_spec)
- {
-       struct connman_managed_table *mtable = NULL;
-       GSList *list;
-       int id, err;
-       char *managed_chain;
-
-       id = chain_to_index(chain_name);
-       if (id < 0) {
-               /* This chain is not managed */
-               return __connman_iptables_delete(table_name, chain_name,
-                                                       rule_spec);
-       }
-
-       managed_chain = g_strdup_printf("%s%s", CHAIN_PREFIX, chain_name);
-
-       err = __connman_iptables_delete(table_name, managed_chain,
-                                       rule_spec);
-
-       for (list = managed_tables; list; list = list->next) {
-               mtable = list->data;
-
-               if (g_strcmp0(mtable->name, table_name) == 0)
-                       break;
-
-               mtable = NULL;
-       }
-
-       if (!mtable) {
-               err = -ENOENT;
-               goto out;
-       }
-
-       mtable->chains[id]--;
-       if (mtable->chains[id] > 0)
-               goto out;
-
-       DBG("table %s remove managed chain for %s",
-                       table_name, chain_name);
-
-       err = delete_managed_chain(table_name, id);
-
- out:
-       g_free(managed_chain);
-
-       return err;
-}
-
-static void cleanup_managed_table(gpointer user_data)
-{
-       struct connman_managed_table *table = user_data;
-
-       g_free(table->name);
-       g_free(table);
-}
-
-static void cleanup_fw_rule(gpointer user_data)
-{
-       struct fw_rule *rule = user_data;
-
-       g_free(rule->rule_spec);
-       g_free(rule->chain);
-       g_free(rule->table);
-       g_free(rule);
-}
-
-struct firewall_context *__connman_firewall_create(void)
-{
-       struct firewall_context *ctx;
-
-       ctx = g_new0(struct firewall_context, 1);
-
-       ctx->ref = 1;
-       return ctx;
-}
-
-void __connman_firewall_destroy(struct firewall_context *ctx)
-{
-       g_list_free_full(ctx->rules, cleanup_fw_rule);
-       g_free(ctx);
-}
-
-static int firewall_enable_rule(struct fw_rule *rule)
-{
-       int err;
-
-       if (rule->enabled)
-               return -EALREADY;
-
-       DBG("%s %s %s", rule->table, rule->chain, rule->rule_spec);
-
-       err = insert_managed_rule(rule->table, rule->chain, rule->rule_spec);
-       if (err < 0)
-               return err;
-
-       err = __connman_iptables_commit(rule->table);
-       if (err < 0)
-               return err;
-
-       rule->enabled = true;
-
-       return 0;
-}
-
-static int firewall_disable_rule(struct fw_rule *rule)
-{
-       int err;
-
-       if (!rule->enabled)
-               return -EALREADY;
-
-       err = delete_managed_rule(rule->table, rule->chain, rule->rule_spec);
-       if (err < 0) {
-               connman_error("Cannot remove previously installed "
-                       "iptables rules: %s", strerror(-err));
-               return err;
-       }
-
-       err = __connman_iptables_commit(rule->table);
-       if (err < 0) {
-               connman_error("Cannot remove previously installed "
-                       "iptables rules: %s", strerror(-err));
-               return err;
-       }
-
-       rule->enabled = false;
-
-       return 0;
-}
-
-static int firewall_add_rule(struct firewall_context *ctx,
-                               const char *table,
-                               const char *chain,
-                               const char *rule_fmt, ...)
-{
-       va_list args;
-       char *rule_spec;
-       struct fw_rule *rule;
-
-       va_start(args, rule_fmt);
-
-       rule_spec = g_strdup_vprintf(rule_fmt, args);
-
-       va_end(args);
-
-       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;
-}
-
-static int firewall_remove_rule(struct firewall_context *ctx, int id)
-{
-       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;
-               }
-       }
-
-       return err;
-}
-
-static int firewall_enable_rules(struct firewall_context *ctx, int id)
-{
-       struct fw_rule *rule;
-       GList *list;
-       int err = -ENOENT;
-
-       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;
-               }
-       }
-
-       return err;
-}
-
-static int firewall_disable_rules(struct firewall_context *ctx, int id)
-{
-       struct fw_rule *rule;
-       GList *list;
-       int e;
-       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) {
-                       e = firewall_disable_rule(rule);
-
-                       /* 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;
-}
-
-static int firewall_enable_context(struct firewall_context *ctx)
-{
-       int err;
-
-       err = firewall_enable_rules(ctx, FW_ALL_RULES);
-       if (err < 0) {
-               connman_warn("Failed to install iptables rules: %s",
-                               strerror(-err));
-               firewall_disable_rules(ctx, FW_ALL_RULES);
-               return err;
-       }
-
-       return 0;
-}
-
-static int firewall_disable_context(struct firewall_context *ctx)
-{
-       return firewall_disable_rules(ctx, FW_ALL_RULES);
-}
-
-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);
-
-       err = firewall_add_rule(ctx, "nat", "POSTROUTING", cmd);
-       g_free(cmd);
-       if (err < 0)
-               return err;
-
-       return firewall_enable_context(ctx);
-}
-
-int __connman_firewall_disable_nat(struct firewall_context *ctx)
-{
-       return firewall_disable_context(ctx);
-}
-
-int __connman_firewall_enable_snat(struct firewall_context *ctx,
-                               int index, char *ifname, const char *addr)
-{
-       int err, id;
-
-       id = firewall_add_rule(ctx, "nat", "POSTROUTING",
-                               "-o %s -j SNAT --to-source %s",
-                               ifname, addr);
-       g_free(ifname);
-
-       err = firewall_enable_rules(ctx, id);
-       if (err < 0) {
-               DBG("could not enable SNAT rule");
-               firewall_remove_rule(ctx, id);
-               return err;
-       }
-
-       ctx->snat_id = id;
-
-       return 0;
-}
-
-int __connman_firewall_disable_snat(struct firewall_context *ctx)
-{
-       int err;
-
-       err = firewall_disable_rules(ctx, ctx->snat_id);
-       if (err < 0) {
-               DBG("could not disable SNAT rule");
-               return err;
-       }
-
-       err = firewall_remove_rule(ctx, ctx->snat_id);
-       if (err < 0)
-               DBG("could not remove SNAT rule");
-
-       return err;
-}
-
-static int firewall_enable_connmark(void)
-{
-       int err;
-
-       if (connmark_ctx) {
-               connmark_ctx->ref++;
-               return 0;
-       }
-
-       connmark_ctx = __connman_firewall_create();
-
-       err = firewall_add_rule(connmark_ctx, "mangle", "INPUT",
-                                       "-j CONNMARK --restore-mark");
-       if (err < 0)
-               goto err;
-
-       err = firewall_add_rule(connmark_ctx, "mangle", "POSTROUTING",
-                                       "-j CONNMARK --save-mark");
-       if (err < 0)
-               goto err;
-
-       return 0;
-err:
-       __connman_firewall_destroy(connmark_ctx);
-       connmark_ctx = NULL;
-
-       return err;
-}
-
-static int firewall_disable_connmark(void)
-{
-       connmark_ctx->ref--;
-       if (connmark_ctx->ref > 1)
-               return 0;
-
-       __connman_firewall_destroy(connmark_ctx);
-       connmark_ctx = NULL;
-
-       return 0;
-}
-
-int __connman_firewall_enable_marking(struct firewall_context *ctx,
-                                       enum connman_session_id_type id_type,
-                                       char *id, uint32_t mark)
-{
-       int err;
-
-       err = firewall_enable_connmark();
-       if (err)
-               return err;
-
-       switch (id_type) {
-       case CONNMAN_SESSION_ID_TYPE_UID:
-               err = 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:
-               err = 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:
-               err = -EINVAL;
-       }
-
-       if (err < 0)
-               return err;
-
-       return firewall_enable_context(ctx);
-}
-
-int __connman_firewall_disable_marking(struct firewall_context *ctx)
-{
-       firewall_disable_connmark();
-       return firewall_disable_context(ctx);
-}
-
-static void iterate_chains_cb(const char *chain_name, void *user_data)
-{
-       GSList **chains = user_data;
-       int id;
-
-       id = managed_chain_to_index(chain_name);
-       if (id < 0)
-               return;
-
-       *chains = g_slist_prepend(*chains, GINT_TO_POINTER(id));
-}
-
-static void flush_table(const char *table_name)
-{
-       GSList *chains = NULL, *list;
-       char *rule, *managed_chain;
-       int id, err;
-
-       __connman_iptables_iterate_chains(table_name, iterate_chains_cb,
-                                               &chains);
-
-       for (list = chains; list; list = list->next) {
-               id = GPOINTER_TO_INT(list->data);
-
-               managed_chain = g_strdup_printf("%s%s", CHAIN_PREFIX,
-                                               builtin_chains[id]);
-
-               rule = g_strdup_printf("-j %s", managed_chain);
-               err = __connman_iptables_delete(table_name,
-                                               builtin_chains[id], rule);
-               if (err < 0) {
-                       connman_warn("Failed to delete jump rule '%s': %s",
-                               rule, strerror(-err));
-               }
-               g_free(rule);
-
-               err = __connman_iptables_flush_chain(table_name, managed_chain);
-               if (err < 0) {
-                       connman_warn("Failed to flush chain '%s': %s",
-                               managed_chain, strerror(-err));
-               }
-               err = __connman_iptables_delete_chain(table_name, 
managed_chain);
-               if (err < 0) {
-                       connman_warn("Failed to delete chain '%s': %s",
-                               managed_chain, strerror(-err));
-               }
-
-               g_free(managed_chain);
-       }
-
-       err = __connman_iptables_commit(table_name);
-       if (err < 0) {
-               connman_warn("Failed to flush table '%s': %s",
-                       table_name, strerror(-err));
-       }
-
-       g_slist_free(chains);
-}
-
-static void flush_all_tables(void)
-{
-       /* Flush the tables ConnMan might have modified
-        * But do so if only ConnMan has done something with
-        * iptables */
-
-       if (!g_file_test("/proc/net/ip_tables_names",
-                       G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
-               return;
-       }
-
-       flush_table("filter");
-       flush_table("mangle");
-       flush_table("nat");
-}
-
-int __connman_firewall_init(void)
-{
-       DBG("");
-
-       flush_all_tables();
-
-       return 0;
-}
-
-void __connman_firewall_cleanup(void)
-{
-       DBG("");
-
-       g_slist_free_full(managed_tables, cleanup_managed_table);
-}
diff --git a/src/main.c b/src/main.c
index e46fa7b..f7a0c0e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -667,7 +667,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();
@@ -730,7 +729,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.0


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

Subject: Digest Footer

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


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

End of connman Digest, Vol 5, Issue 2
*************************************

Reply via email to