summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/iptables.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/src/iptables.c b/src/iptables.c
index 4d88b58b..9584e126 100644
--- a/src/iptables.c
+++ b/src/iptables.c
@@ -945,7 +945,7 @@ static GList *find_existing_rule(struct connman_iptables *table,
struct ipt_ip *ip, const char *chain_name,
const char *target_name,
struct xtables_target *xt_t,
- struct xtables_match *xt_m,
+ GList *matches,
struct xtables_rule_match *xt_rm)
{
GList *chain_tail, *chain_head, *list;
@@ -963,7 +963,7 @@ static GList *find_existing_rule(struct connman_iptables *table,
if (chain_tail == NULL)
return NULL;
- if (!xt_t && !xt_m)
+ if (!xt_t && !matches)
return NULL;
entry_test = new_rule(ip, target_name, xt_t, xt_rm);
@@ -972,7 +972,7 @@ static GList *find_existing_rule(struct connman_iptables *table,
if (xt_t != NULL)
xt_e_t = ipt_get_target(entry_test);
- if (xt_m != NULL)
+ if (matches != NULL)
xt_e_m = (struct xt_entry_match *)entry_test->elems;
entry = chain_head->data;
@@ -1002,7 +1002,7 @@ static GList *find_existing_rule(struct connman_iptables *table,
continue;
}
- if (xt_m != NULL) {
+ if (matches != NULL) {
struct xt_entry_match *tmp_xt_e_m;
tmp_xt_e_m = (struct xt_entry_match *)tmp_e->elems;
@@ -1026,13 +1026,14 @@ static int iptables_delete_rule(struct connman_iptables *table,
struct ipt_ip *ip, const char *chain_name,
const char *target_name,
struct xtables_target *xt_t,
- struct xtables_match *xt_m,
+ GList *matches,
struct xtables_rule_match *xt_rm)
{
struct connman_iptables_entry *entry;
GList *chain_head, *chain_tail, *list;
int builtin, removed;
+
DBG("table %s chain %s", table->name, chain_name);
removed = 0;
@@ -1046,7 +1047,7 @@ static int iptables_delete_rule(struct connman_iptables *table,
return -EINVAL;
list = find_existing_rule(table, ip, chain_name, target_name,
- xt_t, xt_m, xt_rm);
+ xt_t, matches, xt_rm);
if (list == NULL)
return -EINVAL;
@@ -1250,6 +1251,9 @@ static void dump_target(struct ipt_entry *entry)
xt_t->print(NULL, target, 1);
}
}
+
+ if (xt_t == xt_t->next)
+ free(xt_t);
}
static void dump_match(struct ipt_entry *entry)
@@ -1275,6 +1279,8 @@ static void dump_match(struct ipt_entry *entry)
return;
}
+ if (xt_m == xt_m->next)
+ free(xt_m);
out:
DBG("\tmatch %s", match->u.user.name);
@@ -1655,6 +1661,10 @@ static struct xtables_match *prepare_matches(struct connman_iptables *table,
if (iptables_globals.opts == NULL) {
g_free(xt_m->m);
+
+ if (xt_m == xt_m->next)
+ free(xt_m);
+
xt_m = NULL;
}
@@ -1724,7 +1734,7 @@ struct parse_context {
char **argv;
struct ipt_ip *ip;
struct xtables_target *xt_t;
- struct xtables_match *xt_m;
+ GList *xt_m;
struct xtables_rule_match *xt_rm;
};
@@ -1891,6 +1901,7 @@ static int parse_rule_spec(struct connman_iptables *table,
* xtables_option_mpcall() depending on which version
* of libxtables is found.
*/
+ struct xtables_match *xt_m;
connman_bool_t invert = FALSE;
int len, c, err;
@@ -1960,11 +1971,12 @@ static int parse_rule_spec(struct connman_iptables *table,
break;
case 'm':
/* Matches */
- ctx->xt_m = prepare_matches(table, &ctx->xt_rm, optarg);
- if (ctx->xt_m == NULL) {
+ xt_m = prepare_matches(table, &ctx->xt_rm, optarg);
+ if (xt_m == NULL) {
err = -EINVAL;
goto out;
}
+ ctx->xt_m = g_list_append(ctx->xt_m, xt_m);
break;
case 'j':
@@ -2044,6 +2056,7 @@ static void reset_xtables(void)
static void cleanup_parse_context(struct parse_context *ctx)
{
struct xtables_rule_match *rm, *tmp;
+ GList *list;
g_strfreev(ctx->argv);
g_free(ctx->ip);
@@ -2051,10 +2064,19 @@ static void cleanup_parse_context(struct parse_context *ctx)
g_free(ctx->xt_t->t);
ctx->xt_t->t = NULL;
}
- if (ctx->xt_m != NULL) {
- g_free(ctx->xt_m->m);
- ctx->xt_m->m = NULL;
+
+ for (list = ctx->xt_m; list != NULL; list = list->next) {
+ struct xtables_match *xt_m = list->data;
+
+ g_free(xt_m->m);
+
+ if (xt_m != xt_m->next)
+ continue;
+
+ g_free(xt_m);
}
+ g_list_free(ctx->xt_m);
+
for (tmp = NULL, rm = ctx->xt_rm; rm != NULL; rm = rm->next) {
if (tmp != NULL)
g_free(tmp);