diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2010-11-13 23:28:57 +0100 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2010-11-13 23:35:39 +0100 |
commit | 8c367a714016825b94c5f5843be75add6e95aa14 (patch) | |
tree | 72e11a7e6d6efd1723c940e351b4727d4e2cac56 /tools | |
parent | 50f2025803e346ec27799590699bb873c8eff915 (diff) | |
download | connman-8c367a714016825b94c5f5843be75add6e95aa14.tar.gz connman-8c367a714016825b94c5f5843be75add6e95aa14.tar.bz2 connman-8c367a714016825b94c5f5843be75add6e95aa14.zip |
iptables-test: Support for chain flushing
Diffstat (limited to 'tools')
-rw-r--r-- | tools/iptables-test.c | 86 |
1 files changed, 82 insertions, 4 deletions
diff --git a/tools/iptables-test.c b/tools/iptables-test.c index 753847a0..ff9f5c79 100644 --- a/tools/iptables-test.c +++ b/tools/iptables-test.c @@ -349,6 +349,71 @@ static int connman_add_entry(struct connman_iptables *table, return 0; } +static int connman_iptables_flush_chain(struct connman_iptables *table, + char *name) +{ + GList *chain_head, *chain_tail, *list, *next; + struct connman_iptables_entry *entry; + int builtin, removed = 0; + + chain_head = find_chain_head(table, name); + if (chain_head == NULL) + return -EINVAL; + + chain_tail = find_chain_tail(table, name); + if (chain_tail == NULL) + return -EINVAL; + + entry = chain_head->data; + builtin = entry->builtin; + + if (builtin >= 0) + list = chain_head; + else + list = chain_head->next; + + if (list == chain_tail->prev) + return 0; + + while (list != chain_tail->prev) { + entry = list->data; + next = g_list_next(list); + + table->num_entries--; + table->size -= entry->entry->next_offset; + removed += entry->entry->next_offset; + + table->entries = g_list_remove(table->entries, list->data); + + list = next; + } + + if (builtin >= 0) { + struct connman_iptables_entry *e; + + entry = list->data; + + entry->builtin = builtin; + + table->underflow[builtin] -= removed; + + for (list = chain_tail; list; list = list->next) { + e = list->data; + + builtin = e->builtin; + if (builtin < 0) + continue; + + table->hook_entry[builtin] -= removed; + table->underflow[builtin] -= removed; + } + } + + update_offsets(table); + + return 0; +} + static int connman_iptables_delete_chain(struct connman_iptables *table, char *name) { @@ -614,7 +679,7 @@ connman_iptables_blob(struct connman_iptables *table) memset(r, 0, sizeof(*r) + table->size); r->counters = g_try_malloc0(sizeof(struct xt_counters) - * table->num_entries); + * table->old_entries); if (r->counters == NULL) { g_free(r); return NULL; @@ -928,6 +993,7 @@ err: static struct option connman_iptables_opts[] = { {.name = "append", .has_arg = 1, .val = 'A'}, + {.name = "flush-chain", .has_arg = 1, .val = 'F'}, {.name = "list", .has_arg = 2, .val = 'L'}, {.name = "new-chain", .has_arg = 1, .val = 'N'}, {.name = "delete-chain", .has_arg = 1, .val = 'X'}, @@ -951,7 +1017,7 @@ int main(int argc, char *argv[]) struct xtables_match *xt_m; struct xtables_target *xt_t; char *table_name, *chain, *new_chain, *match_name, *target_name; - char *delete_chain; + char *delete_chain, *flush_chain; int c; size_t size; gboolean dump, invert, delete; @@ -962,18 +1028,22 @@ int main(int argc, char *argv[]) invert = FALSE; delete = FALSE; table_name = chain = new_chain = match_name = target_name = NULL; - delete_chain = NULL; + delete_chain = flush_chain = NULL; table = NULL; xt_m = NULL; xt_t = NULL; while ((c = getopt_long(argc, argv, - "-A:L::N:X:j:i:m:o:t:", connman_iptables_globals.opts, NULL)) != -1) { + "-A:F:L::N:X:j:i:m:o:t:", connman_iptables_globals.opts, NULL)) != -1) { switch (c) { case 'A': chain = optarg; break; + case 'F': + flush_chain = optarg; + break; + case 'L': dump = true; break; @@ -1094,6 +1164,14 @@ int main(int argc, char *argv[]) goto commit; } + if (flush_chain) { + printf("Flush chain %s\n", flush_chain); + + connman_iptables_flush_chain(table, flush_chain); + + goto commit; + } + if (dump) { connman_iptables_dump(table); |