summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Wagner <daniel.wagner@bmw-carit.de>2013-03-19 13:46:29 +0100
committerPatrik Flykt <patrik.flykt@linux.intel.com>2013-03-25 13:17:57 +0200
commit6caa1417f6c8b2e1460915f2372f333c4b218ac7 (patch)
tree62ac77da9c7832b22d0fc3ac676c6f19cd0a0159
parenta0b5c505ec9e42811bfe3b398b7b074cd7aab355 (diff)
downloadconnman-6caa1417f6c8b2e1460915f2372f333c4b218ac7.tar.gz
connman-6caa1417f6c8b2e1460915f2372f333c4b218ac7.tar.bz2
connman-6caa1417f6c8b2e1460915f2372f333c4b218ac7.zip
iptables: Add chain iterator
We will implement the ConnMan iptables specific part in a different file and leave the iptables.c file as small as possible. Therefore, we move the flushing part out, but we need a way to find our chains on bootup (left over from a crash). Let's add an interater which walks over all chains which allows a higher level to find the chains it is looking for (e.g. connman-INPUT)
-rw-r--r--src/connman.h6
-rw-r--r--src/iptables.c46
2 files changed, 20 insertions, 32 deletions
diff --git a/src/connman.h b/src/connman.h
index 8e26304b..6b81477a 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -810,6 +810,12 @@ int __connman_iptables_delete(const char *table_name,
const char *chain,
const char *rule_spec);
+typedef void (*connman_iptables_iterate_chains_cb_t) (const char *chain_name,
+ void *user_data);
+int __connman_iptables_iterate_chains(const char *table_name,
+ connman_iptables_iterate_chains_cb_t cb,
+ void *user_data);
+
int __connman_iptables_init(void);
void __connman_iptables_cleanup(void);
int __connman_iptables_commit(const char *table_name);
diff --git a/src/iptables.c b/src/iptables.c
index 51831546..4d88b58b 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):
@@ -2306,13 +2304,13 @@ static void remove_table(gpointer user_data)
table_cleanup(table);
}
-static int flush_table_cb(struct ipt_entry *entry, int builtin,
+static int iterate_chains_cb(struct ipt_entry *entry, int builtin,
unsigned int hook, size_t size,
unsigned int offset, void *user_data)
{
- GSList **chains = user_data;
+ struct cb_data *cbd = user_data;
+ connman_iptables_iterate_chains_cb_t cb = cbd->cb;
struct xt_entry_target *target;
- char *name;
if (offset + entry->next_offset == size)
return 0;
@@ -2320,50 +2318,34 @@ static int flush_table_cb(struct ipt_entry *entry, int builtin,
target = ipt_get_target(entry);
if (!g_strcmp0(target->u.user.name, IPT_ERROR_TARGET))
- name = g_strdup((const char*)target->data);
+ (*cb)((const char*)target->data, cbd->user_data);
else if (builtin >= 0)
- name = g_strdup(hooknames[builtin]);
- else
- return 0;
-
- *chains = g_slist_prepend(*chains, name);
+ (*cb)(hooknames[builtin], cbd->user_data);
return 0;
}
-void flush_table(const char *name)
+int __connman_iptables_iterate_chains(const char *table_name,
+ connman_iptables_iterate_chains_cb_t cb,
+ void *user_data)
{
- GSList *chains = NULL, *list;
+ struct cb_data *cbd = cb_data_new(cb, user_data);
struct connman_iptables *table;
- table = get_table(name);
+ table = get_table(table_name);
if (table == NULL)
- return;
+ return -EINVAL;
iterate_entries(table->blob_entries->entrytable,
table->info->valid_hooks,
table->info->hook_entry,
table->info->underflow,
table->blob_entries->size,
- flush_table_cb, &chains);
-
-
- /*
- * The offset update code is fragile and it works
- * only safe if we remove elements and move forwards
- * in the table.
- */
- chains = g_slist_reverse(chains);
-
- for (list = chains; list != NULL; list = list->next) {
- char *chain = list->data;
+ iterate_chains_cb, cbd);
- DBG("chain %s", chain);
- iptables_flush_chain(table, chain);
- }
+ g_free(cbd);
- __connman_iptables_commit(name);
- g_slist_free_full(chains, g_free);
+ return 0;
}
int __connman_iptables_init(void)