return ret;
}
-static struct ebt_replace * translate_user2kernel(struct ebt_u_replace *u_repl)
+static struct ebt_replace *translate_user2kernel(struct ebt_u_replace *u_repl)
{
struct ebt_replace *new;
struct ebt_u_entry *e;
struct ebt_u_match_list *m_l;
struct ebt_u_watcher_list *w_l;
- struct ebt_u_chain_list *cl;
struct ebt_u_entries *entries;
char *p, *base;
int i, j;
new->nentries = u_repl->nentries;
new->num_counters = u_repl->num_counters;
new->counters = sparc_cast u_repl->counters;
- /* Determine nr of udc */
- i = 0;
- cl = u_repl->udc;
- while (cl) {
- i++;
- cl = cl->next;
- }
- i += NF_BR_NUMHOOKS;
- chain_offsets = (unsigned int *)malloc(i * sizeof(unsigned int));
+ chain_offsets = (unsigned int *)malloc(u_repl->num_chains * sizeof(unsigned int));
/* Determine size */
- i = 0;
- cl = u_repl->udc;
- while (1) {
- if (i < NF_BR_NUMHOOKS) {
- if (!(new->valid_hooks & (1 << i))) {
- i++;
- continue;
- }
- entries = u_repl->hook_entry[i];
- } else {
- if (!cl)
- break;
- entries = cl->udc;
- }
+ for (i = 0; i < u_repl->num_chains; i++) {
+ if (!(entries = u_repl->chains[i]))
+ continue;
chain_offsets[i] = entries_size;
entries_size += sizeof(struct ebt_entries);
j = 0;
if (j != entries->nentries)
ebt_print_bug("Wrong nentries: %d != %d, hook = %s", j,
entries->nentries, entries->name);
- if (i >= NF_BR_NUMHOOKS)
- cl = cl->next;
- i++;
}
new->entries_size = entries_size;
/* Put everything in one block */
new->entries = sparc_cast p;
- i = 0;
- cl = u_repl->udc;
- while (1) {
+ for (i = 0; i < u_repl->num_chains; i++) {
struct ebt_entries *hlp;
hlp = (struct ebt_entries *)p;
- if (i < NF_BR_NUMHOOKS) {
- if (!(new->valid_hooks & (1 << i))) {
- i++;
- continue;
- }
- entries = u_repl->hook_entry[i];
+ if (!(entries = u_repl->chains[i]))
+ continue;
+ if (i < NF_BR_NUMHOOKS)
new->hook_entry[i] = sparc_cast hlp;
- } else {
- if (!cl)
- break;
- entries = cl->udc;
- }
hlp->nentries = entries->nentries;
hlp->policy = entries->policy;
strcpy(hlp->name, entries->name);
tmp->next_offset = p - base;
e = e->next;
}
- if (i >= NF_BR_NUMHOOKS)
- cl = cl->next;
- i++;
}
/* Sanity check */
new = newcounters;
while (cc) {
if (!next) {
- while (!(entries = ebt_nr_to_chain(u_repl, chainnr++)))
+ while (!(entries = u_repl->chains[chainnr++]))
if (chainnr > NF_BR_NUMHOOKS)
goto letscontinue;/* Prevent infinite loop for -D x:-1 */
if (!(next = entries->entries))
char *tmp = base;
int verdict = ((struct ebt_standard_target *)t)->verdict;
int i;
- struct ebt_u_chain_list *cl;
if (verdict >= 0) {
tmp += verdict;
- cl = u_repl->udc;
- i = 0;
- while (cl && cl->kernel_start != tmp) {
- i++;
- cl = cl->next;
- }
- if (!cl)
- ebt_print_bug("Can't find udc for "
- "jump");
+ for (i = NF_BR_NUMHOOKS; i < u_repl->num_chains; i++)
+ if (u_repl->chains[i]->kernel_start == tmp)
+ break;
+ if (i == u_repl->num_chains)
+ ebt_print_bug("Can't find udc for jump");
((struct ebt_standard_target *)new->t)->verdict = i;
}
}
} else { /* A new chain */
int i;
struct ebt_entries *entries = (struct ebt_entries *)e;
- struct ebt_u_chain_list *cl;
if (*n != *cnt)
ebt_print_bug("Nr of entries in the chain is wrong");
if (valid_hooks & (1 << i))
break;
*hook = i;
- /* Makes use of fact that standard chains come before udc */
- if (i >= NF_BR_NUMHOOKS) { /* Udc */
- i -= NF_BR_NUMHOOKS;
- cl = u_repl->udc;
- while (i-- > 0)
- cl = cl->next;
- *u_e = &(cl->udc->entries);
- } else
- *u_e = &(u_repl->hook_entry[*hook]->entries);
+ *u_e = &(u_repl->chains[*hook]->entries);
return 0;
}
}
int i;
struct ebt_entries *entries = (struct ebt_entries *)e;
struct ebt_u_entries *new;
- struct ebt_u_chain_list **chain_list;
if (!(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
for (i = *hook + 1; i < NF_BR_NUMHOOKS; i++)
if (valid_hooks & (1 << i))
break;
- /* Makes use of fact that standard chains come before udc */
- if (i >= NF_BR_NUMHOOKS) { /* Udc */
- chain_list = &u_repl->udc;
- /* Add in the back */
- while (*chain_list)
- chain_list = &((*chain_list)->next);
- *chain_list = (struct ebt_u_chain_list *)
- malloc(sizeof(struct ebt_u_chain_list));
- if (!(*chain_list))
- ebt_print_memory();
- (*chain_list)->next = NULL;
- (*chain_list)->udc = (struct ebt_u_entries *)
- malloc(sizeof(struct ebt_u_entries));
- if (!((*chain_list)->udc))
- ebt_print_memory();
- new = (*chain_list)->udc;
- /* ebt_translate_entry depends on this for knowing
- * to which chain is being jumped */
- (*chain_list)->kernel_start = (char *)e;
- } else {
- *hook = i;
- new = (struct ebt_u_entries *)
- malloc(sizeof(struct ebt_u_entries));
- if (!new)
- ebt_print_memory();
- u_repl->hook_entry[*hook] = new;
- }
+ new = (struct ebt_u_entries *)malloc(sizeof(struct ebt_u_entries));
+ if (!new)
+ ebt_print_memory();
+ if (i == u_repl->max_chains)
+ ebt_double_chains(u_repl);
+ u_repl->chains[i] = new;
+ if (i >= NF_BR_NUMHOOKS)
+ new->kernel_start = (char *)e;
+ *hook = i;
new->nentries = entries->nentries;
new->policy = entries->policy;
new->entries = NULL;
u_repl->nentries = repl.nentries;
u_repl->num_counters = repl.num_counters;
u_repl->counters = repl.counters;
- u_repl->udc = NULL;
u_repl->counterchanges = NULL;
for (i = 0; i < repl.nentries; i++) {
new_cc = (struct ebt_cntchanges *)
*prev_cc = new_cc;
prev_cc = &(new_cc->next);
}
+ u_repl->chains = (struct ebt_u_entries **)calloc(EBT_ORI_MAX_CHAINS, sizeof(void *));
+ u_repl->max_chains = EBT_ORI_MAX_CHAINS;
hook = -1;
/* FIXME: Clean up when an error is encountered */
EBT_ENTRY_ITERATE(repl.entries, repl.entries_size, ebt_translate_chains,
&hook, u_repl, u_repl->valid_hooks);
+ if (hook >= NF_BR_NUMHOOKS)
+ u_repl->num_chains = hook + 1;
+ else
+ u_repl->num_chains = NF_BR_NUMHOOKS;
i = 0; /* Holds the expected nr. of entries for the chain */
j = 0; /* Holds the up to now counted entries for the chain */
k = 0; /* Holds the total nr. of entries, should equal u_repl->nentries afterwards */
#include <sys/wait.h>
static void decrease_chain_jumps(struct ebt_u_replace *replace);
-static void remove_udc(struct ebt_u_replace *replace);
static int iterate_entries(struct ebt_u_replace *replace, int type);
/* The standard names */
{
int i;
struct ebt_u_entries *entries;
- struct ebt_u_chain_list *udc1, *udc2;
struct ebt_cntchanges *cc1, *cc2;
struct ebt_u_entry *u_e1, *u_e2;
free(replace->counters);
replace->counters = NULL;
- i = -1;
- while (1) {
- i++;
- entries = ebt_nr_to_chain(replace, i);
- if (!entries) {
- if (i < NF_BR_NUMHOOKS)
- continue;
- else
- break;
- }
+ for (i = 0; i < replace->num_chains; i++) {
+ if (!(entries = replace->chains[i]))
+ continue;
u_e1 = entries->entries;
while (u_e1) {
ebt_free_u_entry(u_e1);
free(u_e1);
u_e1 = u_e2;
}
+ free(entries);
+ replace->chains[i] = NULL;
}
- for (i = 0; i < NF_BR_NUMHOOKS; i++) {
- free(replace->hook_entry[i]);
- replace->hook_entry[i] = NULL;
- }
- udc1 = replace->udc;
- while (udc1) {
- free(udc1->udc);
- udc2 = udc1->next;
- free(udc1);
- udc1 = udc2;
- }
- replace->udc = NULL;
cc1 = replace->counterchanges;
while (cc1) {
cc2 = cc1->next;
return 0;
}
-/* Gives back a pointer to the chain base, based on nr.
- * If nr >= NF_BR_NUMHOOKS you'll get back a user-defined chain.
- * Returns NULL on failure. */
-struct ebt_u_entries *ebt_nr_to_chain(const struct ebt_u_replace *replace, int nr)
-{
- if (nr == -1)
- return NULL;
- if (nr < NF_BR_NUMHOOKS)
- return replace->hook_entry[nr];
- else {
- int i;
- struct ebt_u_chain_list *cl = replace->udc;
-
- i = nr - NF_BR_NUMHOOKS;
- while (i > 0 && cl) {
- cl = cl->next;
- i--;
- }
- if (cl)
- return cl->udc;
- else
- return NULL;
- }
-}
-
-/* Gives back a pointer to the chain base of selected_chain */
-struct ebt_u_entries *ebt_to_chain(const struct ebt_u_replace *replace)
-{
- return ebt_nr_to_chain(replace, replace->selected_chain);
-}
-
/* Parse the chain name and return a pointer to the chain base.
* Returns NULL on failure. */
-struct ebt_u_entries *ebt_name_to_chain(const struct ebt_u_replace *replace,
- const char* arg)
+struct ebt_u_entries *ebt_name_to_chain(const struct ebt_u_replace *replace, const char* arg)
{
int i;
- struct ebt_u_chain_list *cl = replace->udc;
+ struct ebt_u_entries *chain;
- for (i = 0; i < NF_BR_NUMHOOKS; i++) {
- if (!replace->hook_entry[i])
+ for (i = 0; i < replace->num_chains; i++) {
+ if (!(chain = replace->chains[i]))
continue;
- if (!strcmp(arg, replace->hook_entry[i]->name))
- return replace->hook_entry[i];
- }
- while(cl) {
- if (!strcmp(arg, cl->udc->name))
- return cl->udc;
- cl = cl->next;
+ if (!strcmp(arg, chain->name))
+ return chain;
}
return NULL;
}
int ebt_get_chainnr(const struct ebt_u_replace *replace, const char* arg)
{
int i;
- struct ebt_u_chain_list *cl = replace->udc;
- for (i = 0; i < NF_BR_NUMHOOKS; i++) {
- if (!replace->hook_entry[i])
+ for (i = 0; i < replace->num_chains; i++) {
+ if (!replace->chains[i])
continue;
- if (!strcmp(arg, replace->hook_entry[i]->name))
+ if (!strcmp(arg, replace->chains[i]->name))
return i;
}
- while(cl) {
- if (!strcmp(arg, cl->udc->name))
- return i;
- i++;
- cl = cl->next;
- }
return -1;
}
replace->nentries = 0;
/* Free everything and zero (n)entries */
- i = -1;
- while (1) {
- i++;
- entries = ebt_nr_to_chain(replace, i);
- if (!entries) {
- if (i < NF_BR_NUMHOOKS)
- continue;
- else
- break;
- }
+ for (i = 0; i < replace->num_chains; i++) {
+ if (!(entries = replace->chains[i]))
+ continue;
entries->nentries = 0;
entries->counter_offset = 0;
u_e = entries->entries;
/* Delete the counters belonging to the specified chain,
* update counter_offset */
- i = -1;
- while (1) {
- i++;
- entries = ebt_nr_to_chain(replace, i);
- if (!entries) {
- if (i < NF_BR_NUMHOOKS)
- continue;
- else
- break;
- }
+ for (i = 0; i < replace->num_chains; i++) {
+ if (!(entries = replace->chains[i]))
+ continue;
if (i > replace->selected_chain) {
entries->counter_offset -= numdel;
continue;
* pointers so that they point to ebt_{match,watcher,target}, before adding
* the rule to the chain. Don't free() the ebt_{match,watcher,target} and
* don't reuse the new_entry after a successful call to ebt_add_rule() */
-void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry,
- int rule_nr)
+void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry, int rule_nr)
{
int i, j;
struct ebt_u_entry **u_e;
/* Handle counter stuff */
for (i = 0; i < replace->selected_chain; i++) {
- if (i < NF_BR_NUMHOOKS && !(replace->hook_entry[i]))
+ if (!(replace->chains[i]))
continue;
- j = ebt_nr_to_chain(replace, i)->nentries;
+ j = replace->chains[i]->nentries;
while (j) {
if (cc->type != CNT_DEL)
j--;
}
new_entry->t = ((struct ebt_u_target *)new_entry->t)->t;
/* Update the counter_offset of chains behind this one */
- i = replace->selected_chain;
- while (1) {
- i++;
- entries = ebt_nr_to_chain(replace, i);
- if (!entries) {
- if (i < NF_BR_NUMHOOKS)
- continue;
- else
- break;
- } else
- entries->counter_offset++;
+ for (i = replace->selected_chain+1; i < replace->num_chains; i++) {
+ entries = replace->chains[i];
+ if (!(entries = replace->chains[i]))
+ continue;
+ entries->counter_offset++;
}
}
/* Handle counter stuff */
for (i = 0; i < replace->selected_chain; i++) {
- if (i < NF_BR_NUMHOOKS && !(replace->hook_entry[i]))
+ if (!(replace->chains[i]))
continue;
- j = ebt_nr_to_chain(replace, i)->nentries;
+ j = replace->chains[i]->nentries;
while (j) {
if (cc->type != CNT_DEL)
j--;
/* Update the counter_offset of chains behind this one */
j = replace->selected_chain;
- while (1) {
- j++;
- entries = ebt_nr_to_chain(replace, j);
- if (!entries) {
- if (j < NF_BR_NUMHOOKS)
- continue;
- else
- break;
- } else
- entries->counter_offset -= nr_deletes;
+ for (j = replace->selected_chain+1; j < replace->num_chains; j++) {
+ if (!(entries = replace->chains[j]))
+ continue;
+ entries->counter_offset -= nr_deletes;
}
}
return;
for (i = 0; i < replace->selected_chain; i++) {
- if (i < NF_BR_NUMHOOKS && !(replace->hook_entry[i]))
+ if (!(replace->chains[i]))
continue;
- j = ebt_nr_to_chain(replace, i)->nentries;
+ j = replace->chains[i]->nentries;
while (j) {
if (cc->type != CNT_DEL)
j--;
cc->type = CNT_ZERO;
cc = cc->next;
}
- i = -1;
- while (1) {
- i++;
- if (i < NF_BR_NUMHOOKS && !(replace->hook_entry[i]))
+ for (i = 0; i < replace->num_chains; i++) {
+ if (!(entries = replace->chains[i]))
continue;
- entries = ebt_nr_to_chain(replace, i);
- if (!entries) {
-#ifdef EBT_DEBUG
- if (i < NF_BR_NUMHOOKS)
- ebt_print_bug("i < NF_BR_NUMHOOKS");
-#endif
- break;
- }
next = entries->entries;
while (next) {
next->cnt.bcnt = next->cnt.pcnt = 0;
return;
for (i = 0; i < replace->selected_chain; i++) {
- if (i < NF_BR_NUMHOOKS && !(replace->hook_entry[i]))
+ if (!(replace->chains[i]))
continue;
- j = ebt_nr_to_chain(replace, i)->nentries;
+ j = replace->chains[i]->nentries;
while (j) {
if (cc->type != CNT_DEL)
j--;
/* Add a new chain and specify its policy */
void ebt_new_chain(struct ebt_u_replace *replace, const char *name, int policy)
{
- struct ebt_u_chain_list *cl, **cl2;
+ struct ebt_u_entries *new;
if (ebt_get_chainnr(replace, name) != -1) {
ebt_print_error("Chain %s already exists", optarg);
EBT_CHAIN_MAXNAMELEN - 1);
return;
}
- cl = (struct ebt_u_chain_list *)
- malloc(sizeof(struct ebt_u_chain_list));
- if (!cl)
- ebt_print_memory();
- cl->next = NULL;
- cl->udc = (struct ebt_u_entries *)malloc(sizeof(struct ebt_u_entries));
- if (!cl->udc)
+ if (replace->num_chains == replace->max_chains)
+ ebt_double_chains(replace);
+ new = (struct ebt_u_entries *)malloc(sizeof(struct ebt_u_entries));
+ if (!new)
ebt_print_memory();
- cl->udc->nentries = 0;
- cl->udc->policy = policy;
- cl->udc->counter_offset = replace->nentries;
- cl->udc->hook_mask = 0;
- strcpy(cl->udc->name, name);
- cl->udc->entries = NULL;
- cl->kernel_start = NULL;
- /* Put the new chain at the end */
- cl2 = &(replace->udc);
- while (*cl2)
- cl2 = &((*cl2)->next);
- *cl2 = cl;
+ replace->chains[replace->num_chains++] = new;
+ new->nentries = 0;
+ new->policy = policy;
+ new->counter_offset = replace->nentries;
+ new->hook_mask = 0;
+ strcpy(new->name, name);
+ new->entries = NULL;
+ new->kernel_start = NULL;
+}
+
+static void ebt_delete_a_chain(struct ebt_u_replace *replace, int chain, int print_err)
+{
+ int tmp = replace->selected_chain;
+ /* If the chain is referenced, don't delete it,
+ * also decrement jumps to a chain behind the
+ * one we're deleting */
+ replace->selected_chain = chain;
+ if (ebt_check_for_references(replace, print_err))
+ return;
+ decrease_chain_jumps(replace);
+ ebt_flush_chains(replace);
+ replace->selected_chain = tmp;
+ free(replace->chains[chain]);
+ memmove(replace->chains+chain, replace->chains+chain+1, (replace->num_chains-chain-1)*sizeof(void *));
+ replace->num_chains--;
}
/* Selected_chain == -1: delete all non-referenced udc
* selected_chain < NF_BR_NUMHOOKS is illegal */
void ebt_delete_chain(struct ebt_u_replace *replace)
{
- int chain_nr = replace->selected_chain, print_error = 1;
+ int i;
- if (chain_nr != -1 && chain_nr < NF_BR_NUMHOOKS)
+ if (replace->selected_chain != -1 && replace->selected_chain < NF_BR_NUMHOOKS)
ebt_print_bug("You can't remove a standard chain");
- if (chain_nr == -1) {
- print_error = 0;
- replace->selected_chain = NF_BR_NUMHOOKS;
- }
- do {
- if (ebt_to_chain(replace) == NULL) {
- if (chain_nr == -1)
- break;
- ebt_print_bug("udc nr %d doesn't exist", chain_nr);
- }
- /* If the chain is referenced, don't delete it,
- * also decrement jumps to a chain behind the
- * one we're deleting */
- if (ebt_check_for_references(replace, print_error)) {
- if (chain_nr != -1)
- break;
- replace->selected_chain++;
- continue;
- }
- decrease_chain_jumps(replace);
- ebt_flush_chains(replace);
- remove_udc(replace);
- } while (chain_nr == -1);
- replace->selected_chain = chain_nr; /* Put back to -1 */
+ if (replace->selected_chain == -1)
+ for (i = NF_BR_NUMHOOKS; i < replace->num_chains; i++)
+ ebt_delete_a_chain(replace, i, 0);
+ else
+ ebt_delete_a_chain(replace, replace->selected_chain, 1);
}
/* Rename an existing chain. */
*/
+void ebt_double_chains(struct ebt_u_replace *replace)
+{
+ struct ebt_u_entries **new;
+
+ replace->max_chains *= 2;
+ new = (struct ebt_u_entries **)malloc(replace->max_chains*sizeof(void *));
+ if (!new)
+ ebt_print_memory();
+ memcpy(new, replace->chains, replace->max_chains/2*sizeof(void *));
+ free(replace->chains);
+ replace->chains = new;
+}
+
/* Executes the final_check() function for all extensions used by the rule
* ebt_check_for_loops should have been executed earlier, to make sure the
* hook_mask is correct. The time argument to final_check() is set to 1,
struct ebt_u_stack *stack = NULL;
struct ebt_u_entry *e;
- i = -1;
/* Initialize hook_mask to 0 */
- while (1) {
- i++;
- if (i < NF_BR_NUMHOOKS && !(replace->hook_entry[i]))
+ for (i = 0; i < replace->num_chains; i++) {
+ if (!(entries = replace->chains[i]))
continue;
- entries = ebt_nr_to_chain(replace, i);
- if (!entries)
- break;
entries->hook_mask = 0;
}
- if (i > NF_BR_NUMHOOKS) {
- stack = (struct ebt_u_stack *)malloc((i - NF_BR_NUMHOOKS) * sizeof(struct ebt_u_stack));
- if (!stack)
- ebt_print_memory();
- }
+ if (replace->num_chains == NF_BR_NUMHOOKS)
+ return;
+ stack = (struct ebt_u_stack *)malloc((replace->num_chains - NF_BR_NUMHOOKS) * sizeof(struct ebt_u_stack));
+ if (!stack)
+ ebt_print_memory();
/* Check for loops, starting from every base chain */
for (i = 0; i < NF_BR_NUMHOOKS; i++) {
- if (!(replace->hook_entry[i]))
+ if (!(entries = replace->chains[i]))
continue;
- entries = ebt_nr_to_chain(replace, i);
/* (1 << NF_BR_NUMHOOKS) implies it's a standard chain
* (usefull in the final_check() funtions) */
entries->hook_mask = (1 << i) | (1 << NF_BR_NUMHOOKS);
verdict = ((struct ebt_standard_target *)(e->t))->verdict;
if (verdict < 0)
goto letscontinue;
- entries2 = ebt_nr_to_chain(replace, verdict + NF_BR_NUMHOOKS);
+ entries2 = replace->chains[verdict + NF_BR_NUMHOOKS];
entries2->hook_mask |= entries->hook_mask;
/* Now see if we've been here before */
for (k = 0; k < sp; k++)
if (stack[k].chain_nr == verdict + NF_BR_NUMHOOKS) {
ebt_print_error("Loop from chain '%s' to chain '%s'",
- ebt_nr_to_chain(replace, chain_nr)->name,
- ebt_nr_to_chain(replace, stack[k].chain_nr)->name);
+ replace->chains[chain_nr]->name,
+ replace->chains[stack[k].chain_nr]->name);
goto free_stack;
}
/* Jump to the chain, make sure we know how to get back */
* returns 0 otherwise */
static int iterate_entries(struct ebt_u_replace *replace, int type)
{
- int i = -1, j, chain_nr = replace->selected_chain - NF_BR_NUMHOOKS;
+ int i, j, chain_nr = replace->selected_chain - NF_BR_NUMHOOKS;
struct ebt_u_entries *entries;
struct ebt_u_entry *e;
if (chain_nr < 0)
ebt_print_bug("iterate_entries: udc = %d < 0", chain_nr);
- while (1) {
- i++;
- entries = ebt_nr_to_chain(replace, i);
- if (!entries) {
- if (i < NF_BR_NUMHOOKS)
- continue;
- else
- break;
- }
+ for (i = 0; i < replace->num_chains; i++) {
+ if (!(entries = replace->chains[i]))
+ continue;
e = entries->entries;
j = 0;
while (e) {
if (type == 2)
return 1;
ebt_print_error("Can't delete the chain '%s', it's referenced in chain '%s', rule %d",
- ebt_nr_to_chain(replace, chain_nr + NF_BR_NUMHOOKS)->name, entries->name, j);
+ replace->chains[chain_nr + NF_BR_NUMHOOKS]->name, entries->name, j);
return 1;
}
break;
iterate_entries(replace, 0);
}
-/* Selected_chain >= NF_BR_NUMHOOKS */
-static void remove_udc(struct ebt_u_replace *replace)
-{
- struct ebt_u_chain_list *cl, **cl2;
- struct ebt_u_entries *entries;
- struct ebt_u_entry *u_e, *tmp;
- int chain_nr = replace->selected_chain;
-
- if (chain_nr < NF_BR_NUMHOOKS)
- ebt_print_bug("remove_udc: chain_nr = %d < %d", chain_nr,
- NF_BR_NUMHOOKS);
- /* First free the rules */
- entries = ebt_nr_to_chain(replace, chain_nr);
- u_e = entries->entries;
- while (u_e) {
- ebt_free_u_entry(u_e);
- tmp = u_e->next;
- free(u_e);
- u_e = tmp;
- }
-
- /* next, remove the chain */
- cl2 = &(replace->udc);
- while ((*cl2)->udc != entries)
- cl2 = &((*cl2)->next);
- cl = (*cl2);
- (*cl2) = (*cl2)->next;
- free(cl->udc);
- free(cl);
-}
-
/* Used in initialization code of modules */
void ebt_register_match(struct ebt_u_match *m)
{