summaryrefslogtreecommitdiffstats
path: root/kernel/linux
diff options
context:
space:
mode:
authorBart De Schuymer <bdschuym@pandora.be>2002-07-12 15:26:43 +0000
committerBart De Schuymer <bdschuym@pandora.be>2002-07-12 15:26:43 +0000
commitb42c5cb36c05176e268be02ae7a0b5cc9f6f0a99 (patch)
treeadc71fd13f45b8bd53b8d95cf03b80e820ce65b6 /kernel/linux
parenta0e462a906af19803d28a21d5f57bd3a03f92d86 (diff)
make chainstack smp compatible
Diffstat (limited to 'kernel/linux')
-rw-r--r--kernel/linux/include/linux/netfilter_bridge/ebtables.h2
-rw-r--r--kernel/linux/net/bridge/netfilter/ebtables.c44
2 files changed, 36 insertions, 10 deletions
diff --git a/kernel/linux/include/linux/netfilter_bridge/ebtables.h b/kernel/linux/include/linux/netfilter_bridge/ebtables.h
index 62e624f..ca1d7aa 100644
--- a/kernel/linux/include/linux/netfilter_bridge/ebtables.h
+++ b/kernel/linux/include/linux/netfilter_bridge/ebtables.h
@@ -238,7 +238,7 @@ struct ebt_table_info
struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
struct ebt_counter *counters;
// room to maintain the stack used for jumping from and into udc
- struct ebt_chainstack *chainstack;
+ struct ebt_chainstack **chainstack;
char *entries;
};
diff --git a/kernel/linux/net/bridge/netfilter/ebtables.c b/kernel/linux/net/bridge/netfilter/ebtables.c
index 34cb58d..f780a44 100644
--- a/kernel/linux/net/bridge/netfilter/ebtables.c
+++ b/kernel/linux/net/bridge/netfilter/ebtables.c
@@ -107,7 +107,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
char *base;
read_lock_bh(&table->lock);
- cs = table->private->chainstack;
+ cs = table->private->chainstack[cpu_number_map(smp_processor_id())];
chaininfo = table->private->hook_entry[hook];
nentries = table->private->hook_entry[hook]->nentries;
point = (struct ebt_entry *)(table->private->hook_entry[hook]->data);
@@ -768,10 +768,22 @@ static int translate_table(struct ebt_replace *repl,
if (udc_cnt) {
// this will get free'd in do_replace()/ebt_register_table()
// if an error occurs
- newinfo->chainstack = (struct ebt_chainstack *)
- vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
+ newinfo->chainstack = (struct ebt_chainstack **)
+ vmalloc(smp_num_cpus * sizeof(struct ebt_chainstack));
if (!newinfo->chainstack)
return -ENOMEM;
+ for (i = 0; i < smp_num_cpus; i++) {
+ newinfo->chainstack[i] =
+ vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
+ if (!newinfo->chainstack[i]) {
+ while (i)
+ vfree(newinfo->chainstack[--i]);
+ vfree(newinfo->chainstack);
+ newinfo->chainstack = NULL;
+ break;
+ }
+ }
+
cl_s = (struct ebt_cl_stack *)
vmalloc(udc_cnt * sizeof(struct ebt_cl_stack));
if (!cl_s)
@@ -845,7 +857,7 @@ static inline void get_counters(struct ebt_table_info *info,
// replace the table
static int do_replace(void *user, unsigned int len)
{
- int ret;
+ int ret, i;
struct ebt_table_info *newinfo;
struct ebt_replace tmp;
struct ebt_table *t;
@@ -959,8 +971,11 @@ static int do_replace(void *user, unsigned int len)
vfree(table->entries);
if (table->counters)
vfree(table->counters);
- if (table->chainstack)
+ if (table->chainstack) {
+ for (i = 0; i < smp_num_cpus; i++)
+ vfree(table->chainstack[i]);
vfree(table->chainstack);
+ }
vfree(table);
if (counterstmp)
@@ -975,8 +990,11 @@ free_counterstmp:
if (counterstmp)
vfree(counterstmp);
// can be initialized in translate_table()
- if (newinfo->chainstack)
+ if (newinfo->chainstack) {
+ for (i = 0; i < smp_num_cpus; i++)
+ vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
+ }
free_entries:
if (newinfo->entries)
vfree(newinfo->entries);
@@ -1067,7 +1085,7 @@ void ebt_unregister_watcher(struct ebt_watcher *watcher)
int ebt_register_table(struct ebt_table *table)
{
struct ebt_table_info *newinfo;
- int ret;
+ int ret, i;
if (!table || !table->table ||!table->table->entries ||
table->table->entries_size == 0 ||
@@ -1135,8 +1153,11 @@ free_unlock:
free_counters:
if (newinfo->counters)
vfree(newinfo->counters);
- if (newinfo->chainstack)
+ if (newinfo->chainstack) {
+ for (i = 0; i < smp_num_cpus; i++)
+ vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
+ }
free_entries:
vfree(newinfo->entries);
free_newinfo:
@@ -1146,6 +1167,8 @@ free_newinfo:
void ebt_unregister_table(struct ebt_table *table)
{
+ int i;
+
if (!table) {
BUGPRINT("Request to unregister NULL table!!!\n");
return;
@@ -1159,8 +1182,11 @@ void ebt_unregister_table(struct ebt_table *table)
vfree(table->private->counters);
if (table->private->entries)
vfree(table->private->entries);
- if (table->private->chainstack)
+ if (table->private->chainstack) {
+ for (i = 0; i < smp_num_cpus; i++)
+ vfree(table->private->chainstack[i]);
vfree(table->private->chainstack);
+ }
vfree(table->private);
MOD_DEC_USE_COUNT;
}