From: Daniel Wagner <daniel.wag...@bmw-carit.de>

Flush only ConnMan's own rules and chains. The chains naming pattern is
"connman-[CHAIN NAME]". That makes it simple to find again.
---
 src/iptables.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 92 insertions(+), 5 deletions(-)

diff --git a/src/iptables.c b/src/iptables.c
index 7a9d524..d095bbe 100644
--- a/src/iptables.c
+++ b/src/iptables.c
@@ -36,8 +36,6 @@
 
 #include "connman.h"
 
-void flush_table(const char *name);
-
 /*
  * Some comments on how the iptables API works (some of them from the
  * source code from iptables and the kernel):
@@ -136,6 +134,14 @@ static const char *hooknames[] = {
        [NF_IP_POST_ROUTING]    = "POSTROUTING",
 };
 
+static const char *managed_hooknames[] = {
+       [NF_IP_PRE_ROUTING]     = "connman-PREROUTING",
+       [NF_IP_LOCAL_IN]        = "connman-INPUT",
+       [NF_IP_FORWARD]         = "connman-FORWARD",
+       [NF_IP_LOCAL_OUT]       = "connman-OUTPUT",
+       [NF_IP_POST_ROUTING]    = "connman-POSTROUTING",
+};
+
 #define LABEL_ACCEPT  "ACCEPT"
 #define LABEL_DROP    "DROP"
 #define LABEL_QUEUE   "QUEUE"
@@ -287,6 +293,46 @@ static gboolean is_builtin_target(const char *target_name)
        return FALSE;
 }
 
+
+static int managed_chain_to_index(const char *chain_name)
+{
+       if (!strcmp(managed_hooknames[NF_IP_PRE_ROUTING], chain_name))
+               return 0;
+       if (!strcmp(managed_hooknames[NF_IP_LOCAL_IN], chain_name))
+               return 1;
+       if (!strcmp(managed_hooknames[NF_IP_FORWARD], chain_name))
+               return 2;
+       if (!strcmp(managed_hooknames[NF_IP_LOCAL_OUT], chain_name))
+               return 3;
+       if (!strcmp(managed_hooknames[NF_IP_POST_ROUTING], chain_name))
+               return 4;
+
+       return -1;
+
+}
+
+static gboolean is_managed_chain(const char *chain_name)
+{
+       int index;
+
+       index = managed_chain_to_index(chain_name);
+       if (index < 0)
+               return FALSE;
+
+       return TRUE;
+}
+
+static const char *managed_chain_to_builtin(const char *chain_name)
+{
+       int index;
+
+       index = managed_chain_to_index(chain_name);
+       if (index < 0)
+               return NULL;
+
+       return hooknames[index];
+}
+
 static gboolean is_jump(struct ipt_entry *entry)
 {
        struct xt_entry_target *target;
@@ -2349,15 +2395,24 @@ static int flush_table_cb(struct ipt_entry *entry, int 
builtin,
        if (name == NULL)
                return 0;
 
+       DBG("name %s", name);
+
+       if (is_managed_chain(name) == FALSE) {
+               g_free(name);
+               return 0;
+       }
+
        *chains = g_slist_prepend(*chains, name);
 
        return 0;
 }
 
-void flush_table(const char *name)
+static void flush_table(const char *name)
 {
        GSList *chains = NULL, *list;
        struct connman_iptables *table;
+       char *rule;
+       int err;
 
        table = get_table(name);
        if (table == NULL)
@@ -2382,13 +2437,43 @@ void flush_table(const char *name)
                char *chain = list->data;
 
                DBG("chain %s", chain);
-               iptables_flush_chain(table, chain);
+
+               rule = g_strdup_printf("-j %s", chain);
+               err = __connman_iptables_delete(name,
+                               managed_chain_to_builtin(chain), rule);
+               if (err < 0) {
+                       connman_warn("Failed to delete jump rule '%s': %s",
+                               rule, strerror(-err));
+               }
+               g_free(rule);
+
+               err = iptables_flush_chain(table, chain);
+               if (err < 0) {
+                       connman_warn("Failed to flush chain '%s': %s",
+                               chain, strerror(-err));
+               }
+               err = iptables_delete_chain(table, chain);
+               if (err < 0) {
+                       connman_warn("Failed to delete chain '%s': %s",
+                               chain, strerror(-err));
+               }
        }
 
-       __connman_iptables_commit(name);
+       err = __connman_iptables_commit(name);
+       if (err < 0) {
+               connman_warn("Commit for table %s failed: %s", name,
+                       strerror(-err));
+       }
        g_slist_free_full(chains, g_free);
 }
 
+static void flush_all_tables(void)
+{
+       flush_table("filter");
+       flush_table("mangle");
+       flush_table("nat");
+}
+
 #if XTABLES_VERSION_CODE > 5
 
 static void print_xtables_version_code(void)
@@ -2419,6 +2504,8 @@ int __connman_iptables_init(void)
 
        xtables_init_all(&iptables_globals, NFPROTO_IPV4);
 
+       flush_all_tables();
+
        return 0;
 }
 
-- 
1.8.1.3.566.gaa39828

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to