summaryrefslogtreecommitdiffstats
path: root/kernel/patches/incremental-patches/ebtables-v2.0_vs_2.4.18.pre11.001.diff
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/patches/incremental-patches/ebtables-v2.0_vs_2.4.18.pre11.001.diff')
-rw-r--r--kernel/patches/incremental-patches/ebtables-v2.0_vs_2.4.18.pre11.001.diff388
1 files changed, 388 insertions, 0 deletions
diff --git a/kernel/patches/incremental-patches/ebtables-v2.0_vs_2.4.18.pre11.001.diff b/kernel/patches/incremental-patches/ebtables-v2.0_vs_2.4.18.pre11.001.diff
new file mode 100644
index 0000000..13f0100
--- /dev/null
+++ b/kernel/patches/incremental-patches/ebtables-v2.0_vs_2.4.18.pre11.001.diff
@@ -0,0 +1,388 @@
+--- linux/net/bridge/netfilter/ebtable_broute.c Tue Jul 16 18:49:14 2002
++++ ebt2.0pre11.001/net/bridge/netfilter/ebtable_broute.c Tue Jul 9 20:04:31 2002
+@@ -21,7 +21,7 @@
+ // EBT_ACCEPT means the frame will be bridged
+ // EBT_DROP means the frame will be routed
+ static struct ebt_entries initial_chain =
+- {0, "BROUTE", 0, EBT_ACCEPT, 0};
++ {0, "BROUTING", 0, EBT_ACCEPT, 0};
+
+ static struct ebt_replace initial_table =
+ {
+--- linux/net/bridge/netfilter/ebt_redirect.c Tue Jul 16 18:49:14 2002
++++ ebt2.0pre11.001/net/bridge/netfilter/ebt_redirect.c Tue Jul 9 15:41:46 2002
+@@ -22,9 +22,14 @@
+ {
+ struct ebt_redirect_info *infostuff = (struct ebt_redirect_info *) data;
+
+- memcpy((**pskb).mac.ethernet->h_dest,
+- in->br_port->br->dev.dev_addr, ETH_ALEN);
+- (*pskb)->pkt_type = PACKET_HOST;
++ if (hooknr != NF_BR_BROUTING)
++ memcpy((**pskb).mac.ethernet->h_dest,
++ in->br_port->br->dev.dev_addr, ETH_ALEN);
++ else {
++ memcpy((**pskb).mac.ethernet->h_dest,
++ in->dev_addr, ETH_ALEN);
++ (*pskb)->pkt_type = PACKET_HOST;
++ }
+ return infostuff->target;
+ }
+
+--- linux/net/bridge/netfilter/ebtables.c Tue Jul 16 18:49:15 2002
++++ ebt2.0pre11.001/net/bridge/netfilter/ebtables.c Sun Jul 14 20:13:16 2002
+@@ -105,15 +105,19 @@
+ struct ebt_chainstack *cs;
+ struct ebt_entries *chaininfo;
+ char *base;
++ struct ebt_table_info *private = table->private;
+
+ read_lock_bh(&table->lock);
+- cs = table->private->chainstack;
+- chaininfo = table->private->hook_entry[hook];
+- nentries = table->private->hook_entry[hook]->nentries;
+- point = (struct ebt_entry *)(table->private->hook_entry[hook]->data);
++ if (private->chainstack)
++ cs = private->chainstack[cpu_number_map(smp_processor_id())];
++ else
++ cs = NULL;
++ chaininfo = private->hook_entry[hook];
++ nentries = private->hook_entry[hook]->nentries;
++ point = (struct ebt_entry *)(private->hook_entry[hook]->data);
+ #define cb_base table->private->counters + \
+ cpu_number_map(smp_processor_id()) * table->private->nentries
+- counter_base = cb_base + table->private->hook_entry[hook]->counter_offset;
++ counter_base = cb_base + private->hook_entry[hook]->counter_offset;
+ #define FWINV(bool,invflg) ((bool) ^ !!(point->invflags & invflg))
+ // base for chain jumps
+ base = (char *)chaininfo;
+@@ -768,10 +772,22 @@
+ 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)
+@@ -825,27 +841,27 @@
+ }
+
+ // called under write_lock
+-static inline void get_counters(struct ebt_table_info *info,
+- struct ebt_counter *counters)
++static inline void get_counters(struct ebt_counter *oldcounters,
++ struct ebt_counter *counters, unsigned int nentries)
+ {
+ int i, cpu, counter_base;
+
+ // counters of cpu 0
+- memcpy(counters, info->counters,
+- sizeof(struct ebt_counter) * info->nentries);
++ memcpy(counters, oldcounters,
++ sizeof(struct ebt_counter) * nentries);
+ // add other counters to those of cpu 0
+ for (cpu = 1; cpu < smp_num_cpus; cpu++) {
+- counter_base = cpu * info->nentries;
+- for (i = 0; i < info->nentries; i++)
++ counter_base = cpu * nentries;
++ for (i = 0; i < nentries; i++)
+ counters[i].pcnt +=
+- info->counters[counter_base + i].pcnt;
++ oldcounters[counter_base + i].pcnt;
+ }
+ }
+
+ // 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;
+@@ -934,7 +950,8 @@
+ // we need an atomic snapshot of the counters
+ write_lock_bh(&t->lock);
+ if (tmp.num_counters)
+- get_counters(t->private, counterstmp);
++ get_counters(t->private->counters, counterstmp,
++ t->private->nentries);
+
+ t->private = newinfo;
+ write_unlock_bh(&t->lock);
+@@ -959,8 +976,11 @@
+ 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 +995,11 @@
+ 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 +1090,7 @@
+ 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 +1158,11 @@
+ 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 +1172,8 @@
+
+ void ebt_unregister_table(struct ebt_table *table)
+ {
++ int i;
++
+ if (!table) {
+ BUGPRINT("Request to unregister NULL table!!!\n");
+ return;
+@@ -1159,8 +1187,11 @@
+ 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;
+ }
+@@ -1263,52 +1294,65 @@
+ }
+
+ // called with ebt_mutex down
+-static int copy_everything_to_user(struct ebt_table *t, void *user, int *len)
++static int copy_everything_to_user(struct ebt_table *t, void *user,
++ int *len, int cmd)
+ {
+ struct ebt_replace tmp;
+- struct ebt_table_info *info = t->private;
+- struct ebt_counter *counterstmp;
+- int i;
++ struct ebt_counter *counterstmp, *oldcounters;
++ unsigned int entries_size, nentries;
++ char *entries;
++
++ if (cmd == EBT_SO_GET_ENTRIES) {
++ entries_size = t->private->entries_size;
++ nentries = t->private->nentries;
++ entries = t->private->entries;
++ oldcounters = t->private->counters;
++ } else {
++ entries_size = t->table->entries_size;
++ nentries = t->table->nentries;
++ entries = t->table->entries;
++ oldcounters = t->table->counters;
++ }
+
+ if (copy_from_user(&tmp, user, sizeof(tmp))) {
+ BUGPRINT("Cfu didn't work\n");
+ return -EFAULT;
+ }
+
+- if (*len != sizeof(struct ebt_replace) + info->entries_size +
+- (tmp.num_counters? info->nentries * sizeof(struct ebt_counter): 0)) {
++ if (*len != sizeof(struct ebt_replace) + entries_size +
++ (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
+ BUGPRINT("Wrong size\n");
+ return -EINVAL;
+ }
+
+- if (tmp.nentries != info->nentries) {
++ if (tmp.nentries != nentries) {
+ BUGPRINT("Nentries wrong\n");
+ return -EINVAL;
+ }
+
+- if (tmp.entries_size != info->entries_size) {
++ if (tmp.entries_size != entries_size) {
+ BUGPRINT("Wrong size\n");
+ return -EINVAL;
+ }
+
+ // userspace might not need the counters
+ if (tmp.num_counters) {
+- if (tmp.num_counters != info->nentries) {
++ if (tmp.num_counters != nentries) {
+ BUGPRINT("Num_counters wrong\n");
+ return -EINVAL;
+ }
+ counterstmp = (struct ebt_counter *)
+- vmalloc(info->nentries * sizeof(struct ebt_counter));
++ vmalloc(nentries * sizeof(struct ebt_counter));
+ if (!counterstmp) {
+ BUGPRINT("Couldn't copy counters, out of memory\n");
+ return -ENOMEM;
+ }
+ write_lock_bh(&t->lock);
+- get_counters(info, counterstmp);
++ get_counters(oldcounters, counterstmp, nentries);
+ write_unlock_bh(&t->lock);
+
+ if (copy_to_user(tmp.counters, counterstmp,
+- info->nentries * sizeof(struct ebt_counter))) {
++ nentries * sizeof(struct ebt_counter))) {
+ BUGPRINT("Couldn't copy counters to userspace\n");
+ vfree(counterstmp);
+ return -EFAULT;
+@@ -1316,23 +1360,17 @@
+ vfree(counterstmp);
+ }
+
+- if (copy_to_user(tmp.entries, info->entries, info->entries_size)) {
++ if (copy_to_user(tmp.entries, entries, entries_size)) {
+ BUGPRINT("Couldn't copy entries to userspace\n");
+ return -EFAULT;
+ }
+- // make userspace's life easier
+- memcpy(tmp.hook_entry, info->hook_entry,
+- NF_BR_NUMHOOKS * sizeof(struct ebt_entries *));
+- for (i = 0; i < NF_BR_NUMHOOKS; i++)
+- tmp.hook_entry[i] = (struct ebt_entries *)(((char *)
+- (info->hook_entry[i])) - info->entries + tmp.entries);
+ if (copy_to_user(user, &tmp, sizeof(struct ebt_replace))) {
+ BUGPRINT("Couldn't copy ebt_replace to userspace\n");
+ return -EFAULT;
+ }
+ // set the match/watcher/target names right
+- return EBT_ENTRY_ITERATE(info->entries, info->entries_size,
+- ebt_make_names, info->entries, tmp.entries);
++ return EBT_ENTRY_ITERATE(entries, entries_size,
++ ebt_make_names, entries, tmp.entries);
+ }
+
+ static int do_ebt_set_ctl(struct sock *sk,
+@@ -1368,15 +1406,21 @@
+
+ switch(cmd) {
+ case EBT_SO_GET_INFO:
++ case EBT_SO_GET_INIT_INFO:
+ if (*len != sizeof(struct ebt_replace)){
+ ret = -EINVAL;
+ up(&ebt_mutex);
+ break;
+ }
+- tmp.nentries = t->private->nentries;
+- tmp.entries_size = t->private->entries_size;
+- // userspace needs this to check the chain names
+- tmp.valid_hooks = t->valid_hooks;
++ if (cmd == EBT_SO_GET_INFO) {
++ tmp.nentries = t->private->nentries;
++ tmp.entries_size = t->private->entries_size;
++ tmp.valid_hooks = t->valid_hooks;
++ } else {
++ tmp.nentries = t->table->nentries;
++ tmp.entries_size = t->table->entries_size;
++ tmp.valid_hooks = t->table->valid_hooks;
++ }
+ up(&ebt_mutex);
+ if (copy_to_user(user, &tmp, *len) != 0){
+ BUGPRINT("c2u Didn't work\n");
+@@ -1387,9 +1431,10 @@
+ break;
+
+ case EBT_SO_GET_ENTRIES:
+- ret = copy_everything_to_user(t, user, len);
++ case EBT_SO_GET_INIT_ENTRIES:
++ ret = copy_everything_to_user(t, user, len, cmd);
+ up(&ebt_mutex);
+- break;
++ break;
+
+ default:
+ up(&ebt_mutex);
+--- linux/include/linux/netfilter_bridge/ebtables.h Tue Jul 16 18:49:15 2002
++++ ebt2.0pre11.001/include/linux/netfilter_bridge/ebtables.h Sun Jul 14 19:19:09 2002
+@@ -29,7 +29,9 @@
+
+ #define EBT_SO_GET_INFO (EBT_BASE_CTL)
+ #define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1)
+-#define EBT_SO_GET_MAX (EBT_SO_GET_ENTRIES+1)
++#define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1)
++#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
++#define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1)
+
+ // verdicts >0 are "branches"
+ #define EBT_ACCEPT -1
+@@ -55,9 +57,9 @@
+ // one standard (accept, drop, return) per hook
+ int policy;
+ // nr. of entries
+- __u32 nentries;
++ unsigned int nentries;
+ // entry list
+- __u8 data[0];
++ char data[0];
+ };
+
+ // used for the bitmask of struct ebt_entry
+@@ -238,7 +240,7 @@
+ 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;
+ };
+
+--- linux/include/linux/netfilter_bridge/ebt_nat.h Tue Jul 16 18:49:15 2002
++++ ebt2.0pre11.001/include/linux/netfilter_bridge/ebt_nat.h Tue Jul 16 18:45:16 2002
+@@ -4,7 +4,7 @@
+ struct ebt_nat_info
+ {
+ unsigned char mac[ETH_ALEN];
+- // EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN
++ // EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN
+ int target;
+ };
+ #define EBT_SNAT_TARGET "snat"