static int iptables_change_policy(struct connman_iptables *table,
const char *chain_name, const char *policy)
{
- GList *chain_head;
+ GList *chain_head, *chain_tail;
struct connman_iptables_entry *entry;
struct xt_entry_target *target;
struct xt_standard_target *t;
if (entry->builtin < 0)
return -EINVAL;
+ chain_tail = find_chain_tail(table, chain_name);
+ if (chain_tail == NULL)
+ return -EINVAL;
+
+ entry = chain_tail->prev->data;
target = ipt_get_target(entry->entry);
t = (struct xt_standard_target *)target;
if (xt_m->init != NULL)
xt_m->init(xt_m->m);
- if (xt_m == xt_m->next)
- goto done;
-
#if XTABLES_VERSION_CODE > 5
if (xt_m->x6_options != NULL)
iptables_globals.opts =
xt_m = NULL;
}
-done:
return xt_m;
}
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;