From 85af5ae58446d858ade934ae80d643f3830f0459 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Fri, 23 Sep 2011 14:43:36 +0300 Subject: [PATCH] iptables: Adding capability to delete user-defined chains --- src/iptables.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/src/iptables.c b/src/iptables.c index fec4fb8..cb30cf5 100644 --- a/src/iptables.c +++ b/src/iptables.c @@ -483,6 +483,39 @@ err_head: return -ENOMEM; } +static int iptables_delete_chain(struct connman_iptables *table, char *name) +{ + struct connman_iptables_entry *entry; + GList *chain_head, *chain_tail; + + chain_head = find_chain_head(table, name); + if (chain_head == NULL) + return -EINVAL; + + entry = chain_head->data; + + /* We cannot remove builtin chain */ + if (entry->builtin >= 0) + return -EINVAL; + + chain_tail = find_chain_tail(table, name); + if (chain_tail == NULL) + return -EINVAL; + + /* Chain must be flushed */ + if (chain_head->next != chain_tail->prev) + return -EINVAL; + + remove_table_entry(table, entry); + + entry = chain_tail->prev->data; + remove_table_entry(table, entry); + + update_offsets(table); + + return 0; +} + static struct ipt_entry * new_rule(struct connman_iptables *table, struct ipt_ip *ip, char *target_name, struct xtables_target *xt_t, @@ -969,6 +1002,7 @@ static struct option iptables_opts[] = { {.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'}, {.name = "destination", .has_arg = 1, .val = 'd'}, {.name = "in-interface", .has_arg = 1, .val = 'i'}, {.name = "jump", .has_arg = 1, .val = 'j'}, @@ -992,7 +1026,7 @@ static int iptables_command(int argc, char *argv[]) struct xtables_target *xt_t; struct ipt_ip ip; char *table_name, *chain, *new_chain, *match_name, *target_name; - char *flush_chain; + char *flush_chain, *delete_chain; int c, ret, in_len, out_len; size_t size; gboolean dump, invert; @@ -1004,7 +1038,7 @@ static int iptables_command(int argc, char *argv[]) dump = FALSE; invert = FALSE; table_name = chain = new_chain = match_name = target_name = NULL; - flush_chain = NULL; + flush_chain = delete_chain = NULL; memset(&ip, 0, sizeof(struct ipt_ip)); table = NULL; xt_m = NULL; @@ -1014,7 +1048,7 @@ static int iptables_command(int argc, char *argv[]) optind = 0; while ((c = getopt_long(argc, argv, - "-A:F:L::N:d:j:i:m:o:s:t:", iptables_globals.opts, NULL)) != -1) { + "-A:F:L::N:X:d:j:i:m:o:s:t:", iptables_globals.opts, NULL)) != -1) { switch (c) { case 'A': chain = optarg; @@ -1032,6 +1066,10 @@ static int iptables_command(int argc, char *argv[]) new_chain = optarg; break; + case 'X': + delete_chain = optarg; + break; + case 'd': if (!inet_pton(AF_INET, optarg, &dst)) break; @@ -1186,6 +1224,14 @@ static int iptables_command(int argc, char *argv[]) goto out; } + if (delete_chain != NULL) { + printf("Delete chain %s\n", delete_chain); + + iptables_delete_chain(table, delete_chain); + + goto out; + } + if (dump) { iptables_dump(table); -- 2.7.4