netfilter: xtables: add struct xt_mtdtor_param::net
[safe/jmp/linux-2.6] / net / bridge / netfilter / ebtables.c
index fa108c4..1aa0e4c 100644 (file)
@@ -79,18 +79,19 @@ static inline int ebt_do_match (struct ebt_entry_match *m,
 {
        par->match     = m->u.match;
        par->matchinfo = m->data;
-       return m->u.match->match(skb, par);
+       return m->u.match->match(skb, par) ? EBT_MATCH : EBT_NOMATCH;
 }
 
 static inline int ebt_dev_check(char *entry, const struct net_device *device)
 {
        int i = 0;
-       const char *devname = device->name;
+       const char *devname;
 
        if (*entry == '\0')
                return 0;
        if (!device)
                return 1;
+       devname = device->name;
        /* 1 is the wildcard token */
        while (entry[i] != '\0' && entry[i] != 1 && entry[i] == devname[i])
                i++;
@@ -141,6 +142,12 @@ static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
        return 0;
 }
 
+static inline __pure
+struct ebt_entry *ebt_next_entry(const struct ebt_entry *entry)
+{
+       return (void *)entry + entry->next_offset;
+}
+
 /* Do some firewalling */
 unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
@@ -163,7 +170,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
        mtpar.in      = tgpar.in  = in;
        mtpar.out     = tgpar.out = out;
        mtpar.hotdrop = &hotdrop;
-       tgpar.hooknum = hook;
+       mtpar.hooknum = tgpar.hooknum = hook;
 
        read_lock_bh(&table->lock);
        private = table->private;
@@ -248,8 +255,7 @@ letsreturn:
                /* jump to a udc */
                cs[sp].n = i + 1;
                cs[sp].chaininfo = chaininfo;
-               cs[sp].e = (struct ebt_entry *)
-                  (((char *)point) + point->next_offset);
+               cs[sp].e = ebt_next_entry(point);
                i = 0;
                chaininfo = (struct ebt_entries *) (base + verdict);
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -265,8 +271,7 @@ letsreturn:
                sp++;
                continue;
 letscontinue:
-               point = (struct ebt_entry *)
-                  (((char *)point) + point->next_offset);
+               point = ebt_next_entry(point);
                i++;
        }
 
@@ -556,13 +561,14 @@ ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
 }
 
 static inline int
-ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
+ebt_cleanup_match(struct ebt_entry_match *m, struct net *net, unsigned int *i)
 {
        struct xt_mtdtor_param par;
 
        if (i && (*i)-- == 0)
                return 1;
 
+       par.net       = net;
        par.match     = m->u.match;
        par.matchinfo = m->data;
        par.family    = NFPROTO_BRIDGE;
@@ -590,7 +596,7 @@ ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
 }
 
 static inline int
-ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
+ebt_cleanup_entry(struct ebt_entry *e, struct net *net, unsigned int *cnt)
 {
        struct xt_tgdtor_param par;
        struct ebt_entry_target *t;
@@ -601,7 +607,7 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
        if (cnt && (*cnt)-- == 0)
                return 1;
        EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
-       EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
+       EBT_MATCH_ITERATE(e, ebt_cleanup_match, net, NULL);
        t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
 
        par.target   = t->u.target;
@@ -614,7 +620,9 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
 }
 
 static inline int
-ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
+ebt_check_entry(struct ebt_entry *e,
+   struct net *net,
+   struct ebt_table_info *newinfo,
    const char *name, unsigned int *cnt,
    struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
 {
@@ -666,6 +674,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
        }
        i = 0;
 
+       mtpar.net       = net;
        mtpar.table     = tgpar.table     = name;
        mtpar.entryinfo = tgpar.entryinfo = e;
        mtpar.hook_mask = tgpar.hook_mask = hookmask;
@@ -723,7 +732,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
 cleanup_watchers:
        EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j);
 cleanup_matches:
-       EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i);
+       EBT_MATCH_ITERATE(e, ebt_cleanup_match, net, &i);
        return ret;
 }
 
@@ -786,7 +795,7 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s
                        /* this can't be 0, so the loop test is correct */
                        cl_s[i].cs.n = pos + 1;
                        pos = 0;
-                       cl_s[i].cs.e = ((void *)e + e->next_offset);
+                       cl_s[i].cs.e = ebt_next_entry(e);
                        e = (struct ebt_entry *)(hlp2->data);
                        nentries = hlp2->nentries;
                        cl_s[i].from = chain_nr;
@@ -796,14 +805,15 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s
                        continue;
                }
 letscontinue:
-               e = (void *)e + e->next_offset;
+               e = ebt_next_entry(e);
                pos++;
        }
        return 0;
 }
 
 /* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
-static int translate_table(char *name, struct ebt_table_info *newinfo)
+static int translate_table(struct net *net, char *name,
+                          struct ebt_table_info *newinfo)
 {
        unsigned int i, j, k, udc_cnt;
        int ret;
@@ -912,10 +922,10 @@ static int translate_table(char *name, struct ebt_table_info *newinfo)
        /* used to know what we need to clean up if something goes wrong */
        i = 0;
        ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
-          ebt_check_entry, newinfo, name, &i, cl_s, udc_cnt);
+          ebt_check_entry, net, newinfo, name, &i, cl_s, udc_cnt);
        if (ret != 0) {
                EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
-                  ebt_cleanup_entry, &i);
+                                 ebt_cleanup_entry, net, &i);
        }
        vfree(cl_s);
        return ret;
@@ -1012,7 +1022,7 @@ static int do_replace(struct net *net, void __user *user, unsigned int len)
        if (ret != 0)
                goto free_counterstmp;
 
-       ret = translate_table(tmp.name, newinfo);
+       ret = translate_table(net, tmp.name, newinfo);
 
        if (ret != 0)
                goto free_counterstmp;
@@ -1065,7 +1075,7 @@ static int do_replace(struct net *net, void __user *user, unsigned int len)
 
        /* decrease module count and free resources */
        EBT_ENTRY_ITERATE(table->entries, table->entries_size,
-          ebt_cleanup_entry, NULL);
+                         ebt_cleanup_entry, net, NULL);
 
        vfree(table->entries);
        if (table->chainstack) {
@@ -1082,7 +1092,7 @@ free_unlock:
        mutex_unlock(&ebt_mutex);
 free_iterate:
        EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
-          ebt_cleanup_entry, NULL);
+                         ebt_cleanup_entry, net, NULL);
 free_counterstmp:
        vfree(counterstmp);
        /* can be initialized in translate_table() */
@@ -1098,23 +1108,24 @@ free_newinfo:
        return ret;
 }
 
-struct ebt_table *ebt_register_table(struct net *net, struct ebt_table *table)
+struct ebt_table *
+ebt_register_table(struct net *net, const struct ebt_table *input_table)
 {
        struct ebt_table_info *newinfo;
-       struct ebt_table *t;
+       struct ebt_table *t, *table;
        struct ebt_replace_kernel *repl;
        int ret, i, countersize;
        void *p;
 
-       if (!table || !(repl = table->table) || !repl->entries ||
-           repl->entries_size == 0 ||
-           repl->counters || table->private) {
+       if (input_table == NULL || (repl = input_table->table) == NULL ||
+           repl->entries == 0 || repl->entries_size == 0 ||
+           repl->counters != NULL || input_table->private != NULL) {
                BUGPRINT("Bad table data for ebt_register_table!!!\n");
                return ERR_PTR(-EINVAL);
        }
 
        /* Don't add one table to multiple lists. */
-       table = kmemdup(table, sizeof(struct ebt_table), GFP_KERNEL);
+       table = kmemdup(input_table, sizeof(struct ebt_table), GFP_KERNEL);
        if (!table) {
                ret = -ENOMEM;
                goto out;
@@ -1148,7 +1159,7 @@ struct ebt_table *ebt_register_table(struct net *net, struct ebt_table *table)
                        newinfo->hook_entry[i] = p +
                                ((char *)repl->hook_entry[i] - repl->entries);
        }
-       ret = translate_table(repl->name, newinfo);
+       ret = translate_table(net, repl->name, newinfo);
        if (ret != 0) {
                BUGPRINT("Translate_table failed\n");
                goto free_chainstack;
@@ -1198,7 +1209,7 @@ out:
        return ERR_PTR(ret);
 }
 
-void ebt_unregister_table(struct ebt_table *table)
+void ebt_unregister_table(struct net *net, struct ebt_table *table)
 {
        int i;
 
@@ -1210,7 +1221,7 @@ void ebt_unregister_table(struct ebt_table *table)
        list_del(&table->list);
        mutex_unlock(&ebt_mutex);
        EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
-                         ebt_cleanup_entry, NULL);
+                         ebt_cleanup_entry, net, NULL);
        if (table->private->nentries)
                module_put(table->me);
        vfree(table->private->entries);