MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / net / bridge / netfilter / ebtables.c
blob8352eec5bec4cd16f530d52455afff529928ab2f
1 /*
2 * ebtables
4 * Author:
5 * Bart De Schuymer <bdschuym@pandora.be>
7 * ebtables.c,v 2.0, July, 2002
9 * This code is stongly inspired on the iptables code which is
10 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
18 /* used for print_string */
19 #include <linux/sched.h>
20 #include <linux/tty.h>
22 #include <linux/kmod.h>
23 #include <linux/module.h>
24 #include <linux/vmalloc.h>
25 #include <linux/netfilter_bridge/ebtables.h>
26 #include <linux/spinlock.h>
27 #include <asm/uaccess.h>
28 #include <linux/smp.h>
29 #include <net/sock.h>
30 /* needed for logical [in,out]-dev filtering */
31 #include "../br_private.h"
33 /* list_named_find */
34 #define ASSERT_READ_LOCK(x)
35 #define ASSERT_WRITE_LOCK(x)
36 #include <linux/netfilter_ipv4/listhelp.h>
38 #if 0
39 /* use this for remote debugging
40 * Copyright (C) 1998 by Ori Pomerantz
41 * Print the string to the appropriate tty, the one
42 * the current task uses
44 static void print_string(char *str)
46 struct tty_struct *my_tty;
48 /* The tty for the current task */
49 my_tty = current->signal->tty;
50 if (my_tty != NULL) {
51 my_tty->driver->write(my_tty, 0, str, strlen(str));
52 my_tty->driver->write(my_tty, 0, "\015\012", 2);
56 #define BUGPRINT(args) print_string(args);
57 #else
58 #define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\
59 "report to author: "format, ## args)
60 /* #define BUGPRINT(format, args...) */
61 #endif
62 #define MEMPRINT(format, args...) printk("kernel msg: ebtables "\
63 ": out of memory: "format, ## args)
64 /* #define MEMPRINT(format, args...) */
69 * Each cpu has its own set of counters, so there is no need for write_lock in
70 * the softirq
71 * For reading or updating the counters, the user context needs to
72 * get a write_lock
75 /* The size of each set of counters is altered to get cache alignment */
76 #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
77 #define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))
78 #define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \
79 COUNTER_OFFSET(n) * cpu))
83 static DECLARE_MUTEX(ebt_mutex);
84 static LIST_HEAD(ebt_tables);
85 static LIST_HEAD(ebt_targets);
86 static LIST_HEAD(ebt_matches);
87 static LIST_HEAD(ebt_watchers);
89 static struct ebt_target ebt_standard_target =
90 { {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL};
92 static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
93 const struct sk_buff *skb, const struct net_device *in,
94 const struct net_device *out)
96 w->u.watcher->watcher(skb, in, out, w->data,
97 w->watcher_size);
98 /* watchers don't give a verdict */
99 return 0;
102 static inline int ebt_do_match (struct ebt_entry_match *m,
103 const struct sk_buff *skb, const struct net_device *in,
104 const struct net_device *out)
106 return m->u.match->match(skb, in, out, m->data,
107 m->match_size);
110 static inline int ebt_dev_check(char *entry, const struct net_device *device)
112 if (*entry == '\0')
113 return 0;
114 if (!device)
115 return 1;
116 return !!strcmp(entry, device->name);
119 #define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg))
120 /* process standard matches */
121 static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
122 const struct net_device *in, const struct net_device *out)
124 int verdict, i;
126 if (e->bitmask & EBT_802_3) {
127 if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO))
128 return 1;
129 } else if (!(e->bitmask & EBT_NOPROTO) &&
130 FWINV2(e->ethproto != h->h_proto, EBT_IPROTO))
131 return 1;
133 if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN))
134 return 1;
135 if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
136 return 1;
137 if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check(
138 e->logical_in, in->br_port->br->dev), EBT_ILOGICALIN))
139 return 1;
140 if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check(
141 e->logical_out, out->br_port->br->dev), EBT_ILOGICALOUT))
142 return 1;
144 if (e->bitmask & EBT_SOURCEMAC) {
145 verdict = 0;
146 for (i = 0; i < 6; i++)
147 verdict |= (h->h_source[i] ^ e->sourcemac[i]) &
148 e->sourcemsk[i];
149 if (FWINV2(verdict != 0, EBT_ISOURCE) )
150 return 1;
152 if (e->bitmask & EBT_DESTMAC) {
153 verdict = 0;
154 for (i = 0; i < 6; i++)
155 verdict |= (h->h_dest[i] ^ e->destmac[i]) &
156 e->destmsk[i];
157 if (FWINV2(verdict != 0, EBT_IDEST) )
158 return 1;
160 return 0;
163 /* Do some firewalling */
164 unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
165 const struct net_device *in, const struct net_device *out,
166 struct ebt_table *table)
168 int i, nentries;
169 struct ebt_entry *point;
170 struct ebt_counter *counter_base, *cb_base;
171 struct ebt_entry_target *t;
172 int verdict, sp = 0;
173 struct ebt_chainstack *cs;
174 struct ebt_entries *chaininfo;
175 char *base;
176 struct ebt_table_info *private = table->private;
178 read_lock_bh(&table->lock);
179 cb_base = COUNTER_BASE(private->counters, private->nentries,
180 smp_processor_id());
181 if (private->chainstack)
182 cs = private->chainstack[smp_processor_id()];
183 else
184 cs = NULL;
185 chaininfo = private->hook_entry[hook];
186 nentries = private->hook_entry[hook]->nentries;
187 point = (struct ebt_entry *)(private->hook_entry[hook]->data);
188 counter_base = cb_base + private->hook_entry[hook]->counter_offset;
189 /* base for chain jumps */
190 base = private->entries;
191 i = 0;
192 while (i < nentries) {
193 if (ebt_basic_match(point, eth_hdr(*pskb), in, out))
194 goto letscontinue;
196 if (EBT_MATCH_ITERATE(point, ebt_do_match, *pskb, in, out) != 0)
197 goto letscontinue;
199 /* increase counter */
200 (*(counter_base + i)).pcnt++;
201 (*(counter_base + i)).bcnt+=(**pskb).len;
203 /* these should only watch: not modify, nor tell us
204 what to do with the packet */
205 EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, in,
206 out);
208 t = (struct ebt_entry_target *)
209 (((char *)point) + point->target_offset);
210 /* standard target */
211 if (!t->u.target->target)
212 verdict = ((struct ebt_standard_target *)t)->verdict;
213 else
214 verdict = t->u.target->target(pskb, hook,
215 in, out, t->data, t->target_size);
216 if (verdict == EBT_ACCEPT) {
217 read_unlock_bh(&table->lock);
218 return NF_ACCEPT;
220 if (verdict == EBT_DROP) {
221 read_unlock_bh(&table->lock);
222 return NF_DROP;
224 if (verdict == EBT_RETURN) {
225 letsreturn:
226 #ifdef CONFIG_NETFILTER_DEBUG
227 if (sp == 0) {
228 BUGPRINT("RETURN on base chain");
229 /* act like this is EBT_CONTINUE */
230 goto letscontinue;
232 #endif
233 sp--;
234 /* put all the local variables right */
235 i = cs[sp].n;
236 chaininfo = cs[sp].chaininfo;
237 nentries = chaininfo->nentries;
238 point = cs[sp].e;
239 counter_base = cb_base +
240 chaininfo->counter_offset;
241 continue;
243 if (verdict == EBT_CONTINUE)
244 goto letscontinue;
245 #ifdef CONFIG_NETFILTER_DEBUG
246 if (verdict < 0) {
247 BUGPRINT("bogus standard verdict\n");
248 read_unlock_bh(&table->lock);
249 return NF_DROP;
251 #endif
252 /* jump to a udc */
253 cs[sp].n = i + 1;
254 cs[sp].chaininfo = chaininfo;
255 cs[sp].e = (struct ebt_entry *)
256 (((char *)point) + point->next_offset);
257 i = 0;
258 chaininfo = (struct ebt_entries *) (base + verdict);
259 #ifdef CONFIG_NETFILTER_DEBUG
260 if (chaininfo->distinguisher) {
261 BUGPRINT("jump to non-chain\n");
262 read_unlock_bh(&table->lock);
263 return NF_DROP;
265 #endif
266 nentries = chaininfo->nentries;
267 point = (struct ebt_entry *)chaininfo->data;
268 counter_base = cb_base + chaininfo->counter_offset;
269 sp++;
270 continue;
271 letscontinue:
272 point = (struct ebt_entry *)
273 (((char *)point) + point->next_offset);
274 i++;
277 /* I actually like this :) */
278 if (chaininfo->policy == EBT_RETURN)
279 goto letsreturn;
280 if (chaininfo->policy == EBT_ACCEPT) {
281 read_unlock_bh(&table->lock);
282 return NF_ACCEPT;
284 read_unlock_bh(&table->lock);
285 return NF_DROP;
288 /* If it succeeds, returns element and locks mutex */
289 static inline void *
290 find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
291 struct semaphore *mutex)
293 void *ret;
295 *error = down_interruptible(mutex);
296 if (*error != 0)
297 return NULL;
299 ret = list_named_find(head, name);
300 if (!ret) {
301 *error = -ENOENT;
302 up(mutex);
304 return ret;
307 #ifndef CONFIG_KMOD
308 #define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
309 #else
310 static void *
311 find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
312 int *error, struct semaphore *mutex)
314 void *ret;
316 ret = find_inlist_lock_noload(head, name, error, mutex);
317 if (!ret) {
318 request_module("%s%s", prefix, name);
319 ret = find_inlist_lock_noload(head, name, error, mutex);
321 return ret;
323 #endif
325 static inline struct ebt_table *
326 find_table_lock(const char *name, int *error, struct semaphore *mutex)
328 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
331 static inline struct ebt_match *
332 find_match_lock(const char *name, int *error, struct semaphore *mutex)
334 return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
337 static inline struct ebt_watcher *
338 find_watcher_lock(const char *name, int *error, struct semaphore *mutex)
340 return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
343 static inline struct ebt_target *
344 find_target_lock(const char *name, int *error, struct semaphore *mutex)
346 return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
349 static inline int
350 ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
351 const char *name, unsigned int hookmask, unsigned int *cnt)
353 struct ebt_match *match;
354 int ret;
356 if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) >
357 ((char *)e) + e->watchers_offset)
358 return -EINVAL;
359 match = find_match_lock(m->u.name, &ret, &ebt_mutex);
360 if (!match)
361 return ret;
362 m->u.match = match;
363 if (!try_module_get(match->me)) {
364 up(&ebt_mutex);
365 return -ENOENT;
367 up(&ebt_mutex);
368 if (match->check &&
369 match->check(name, hookmask, e, m->data, m->match_size) != 0) {
370 BUGPRINT("match->check failed\n");
371 module_put(match->me);
372 return -EINVAL;
374 (*cnt)++;
375 return 0;
378 static inline int
379 ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
380 const char *name, unsigned int hookmask, unsigned int *cnt)
382 struct ebt_watcher *watcher;
383 int ret;
385 if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) >
386 ((char *)e) + e->target_offset)
387 return -EINVAL;
388 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
389 if (!watcher)
390 return ret;
391 w->u.watcher = watcher;
392 if (!try_module_get(watcher->me)) {
393 up(&ebt_mutex);
394 return -ENOENT;
396 up(&ebt_mutex);
397 if (watcher->check &&
398 watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) {
399 BUGPRINT("watcher->check failed\n");
400 module_put(watcher->me);
401 return -EINVAL;
403 (*cnt)++;
404 return 0;
408 * this one is very careful, as it is the first function
409 * to parse the userspace data
411 static inline int
412 ebt_check_entry_size_and_hooks(struct ebt_entry *e,
413 struct ebt_table_info *newinfo, char *base, char *limit,
414 struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt,
415 unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks)
417 int i;
419 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
420 if ((valid_hooks & (1 << i)) == 0)
421 continue;
422 if ( (char *)hook_entries[i] - base ==
423 (char *)e - newinfo->entries)
424 break;
426 /* beginning of a new chain
427 if i == NF_BR_NUMHOOKS it must be a user defined chain */
428 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
429 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) {
430 /* we make userspace set this right,
431 so there is no misunderstanding */
432 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
433 "in distinguisher\n");
434 return -EINVAL;
436 /* this checks if the previous chain has as many entries
437 as it said it has */
438 if (*n != *cnt) {
439 BUGPRINT("nentries does not equal the nr of entries "
440 "in the chain\n");
441 return -EINVAL;
443 /* before we look at the struct, be sure it is not too big */
444 if ((char *)hook_entries[i] + sizeof(struct ebt_entries)
445 > limit) {
446 BUGPRINT("entries_size too small\n");
447 return -EINVAL;
449 if (((struct ebt_entries *)e)->policy != EBT_DROP &&
450 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
451 /* only RETURN from udc */
452 if (i != NF_BR_NUMHOOKS ||
453 ((struct ebt_entries *)e)->policy != EBT_RETURN) {
454 BUGPRINT("bad policy\n");
455 return -EINVAL;
458 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
459 (*udc_cnt)++;
460 else
461 newinfo->hook_entry[i] = (struct ebt_entries *)e;
462 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
463 BUGPRINT("counter_offset != totalcnt");
464 return -EINVAL;
466 *n = ((struct ebt_entries *)e)->nentries;
467 *cnt = 0;
468 return 0;
470 /* a plain old entry, heh */
471 if (sizeof(struct ebt_entry) > e->watchers_offset ||
472 e->watchers_offset > e->target_offset ||
473 e->target_offset >= e->next_offset) {
474 BUGPRINT("entry offsets not in right order\n");
475 return -EINVAL;
477 /* this is not checked anywhere else */
478 if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) {
479 BUGPRINT("target size too small\n");
480 return -EINVAL;
483 (*cnt)++;
484 (*totalcnt)++;
485 return 0;
488 struct ebt_cl_stack
490 struct ebt_chainstack cs;
491 int from;
492 unsigned int hookmask;
496 * we need these positions to check that the jumps to a different part of the
497 * entries is a jump to the beginning of a new chain.
499 static inline int
500 ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
501 struct ebt_entries **hook_entries, unsigned int *n, unsigned int valid_hooks,
502 struct ebt_cl_stack *udc)
504 int i;
506 /* we're only interested in chain starts */
507 if (e->bitmask & EBT_ENTRY_OR_ENTRIES)
508 return 0;
509 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
510 if ((valid_hooks & (1 << i)) == 0)
511 continue;
512 if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
513 break;
515 /* only care about udc */
516 if (i != NF_BR_NUMHOOKS)
517 return 0;
519 udc[*n].cs.chaininfo = (struct ebt_entries *)e;
520 /* these initialisations are depended on later in check_chainloops() */
521 udc[*n].cs.n = 0;
522 udc[*n].hookmask = 0;
524 (*n)++;
525 return 0;
528 static inline int
529 ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
531 if (i && (*i)-- == 0)
532 return 1;
533 if (m->u.match->destroy)
534 m->u.match->destroy(m->data, m->match_size);
535 module_put(m->u.match->me);
537 return 0;
540 static inline int
541 ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
543 if (i && (*i)-- == 0)
544 return 1;
545 if (w->u.watcher->destroy)
546 w->u.watcher->destroy(w->data, w->watcher_size);
547 module_put(w->u.watcher->me);
549 return 0;
552 static inline int
553 ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
555 struct ebt_entry_target *t;
557 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
558 return 0;
559 /* we're done */
560 if (cnt && (*cnt)-- == 0)
561 return 1;
562 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
563 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
564 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
565 if (t->u.target->destroy)
566 t->u.target->destroy(t->data, t->target_size);
567 module_put(t->u.target->me);
569 return 0;
572 static inline int
573 ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
574 const char *name, unsigned int *cnt, unsigned int valid_hooks,
575 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
577 struct ebt_entry_target *t;
578 struct ebt_target *target;
579 unsigned int i, j, hook = 0, hookmask = 0;
580 int ret;
582 /* don't mess with the struct ebt_entries */
583 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
584 return 0;
586 if (e->bitmask & ~EBT_F_MASK) {
587 BUGPRINT("Unknown flag for bitmask\n");
588 return -EINVAL;
590 if (e->invflags & ~EBT_INV_MASK) {
591 BUGPRINT("Unknown flag for inv bitmask\n");
592 return -EINVAL;
594 if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) {
595 BUGPRINT("NOPROTO & 802_3 not allowed\n");
596 return -EINVAL;
598 /* what hook do we belong to? */
599 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
600 if ((valid_hooks & (1 << i)) == 0)
601 continue;
602 if ((char *)newinfo->hook_entry[i] < (char *)e)
603 hook = i;
604 else
605 break;
607 /* (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on
608 a base chain */
609 if (i < NF_BR_NUMHOOKS)
610 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
611 else {
612 for (i = 0; i < udc_cnt; i++)
613 if ((char *)(cl_s[i].cs.chaininfo) > (char *)e)
614 break;
615 if (i == 0)
616 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
617 else
618 hookmask = cl_s[i - 1].hookmask;
620 i = 0;
621 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
622 if (ret != 0)
623 goto cleanup_matches;
624 j = 0;
625 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
626 if (ret != 0)
627 goto cleanup_watchers;
628 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
629 target = find_target_lock(t->u.name, &ret, &ebt_mutex);
630 if (!target)
631 goto cleanup_watchers;
632 if (!try_module_get(target->me)) {
633 up(&ebt_mutex);
634 ret = -ENOENT;
635 goto cleanup_watchers;
637 up(&ebt_mutex);
639 t->u.target = target;
640 if (t->u.target == &ebt_standard_target) {
641 if (e->target_offset + sizeof(struct ebt_standard_target) >
642 e->next_offset) {
643 BUGPRINT("Standard target size too big\n");
644 ret = -EFAULT;
645 goto cleanup_watchers;
647 if (((struct ebt_standard_target *)t)->verdict <
648 -NUM_STANDARD_TARGETS) {
649 BUGPRINT("Invalid standard target\n");
650 ret = -EFAULT;
651 goto cleanup_watchers;
653 } else if ((e->target_offset + t->target_size +
654 sizeof(struct ebt_entry_target) > e->next_offset) ||
655 (t->u.target->check &&
656 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
657 module_put(t->u.target->me);
658 ret = -EFAULT;
659 goto cleanup_watchers;
661 (*cnt)++;
662 return 0;
663 cleanup_watchers:
664 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j);
665 cleanup_matches:
666 EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i);
667 return ret;
671 * checks for loops and sets the hook mask for udc
672 * the hook mask for udc tells us from which base chains the udc can be
673 * accessed. This mask is a parameter to the check() functions of the extensions
675 static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s,
676 unsigned int udc_cnt, unsigned int hooknr, char *base)
678 int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict;
679 struct ebt_entry *e = (struct ebt_entry *)chain->data;
680 struct ebt_entry_target *t;
682 while (pos < nentries || chain_nr != -1) {
683 /* end of udc, go back one 'recursion' step */
684 if (pos == nentries) {
685 /* put back values of the time when this chain was called */
686 e = cl_s[chain_nr].cs.e;
687 if (cl_s[chain_nr].from != -1)
688 nentries =
689 cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries;
690 else
691 nentries = chain->nentries;
692 pos = cl_s[chain_nr].cs.n;
693 /* make sure we won't see a loop that isn't one */
694 cl_s[chain_nr].cs.n = 0;
695 chain_nr = cl_s[chain_nr].from;
696 if (pos == nentries)
697 continue;
699 t = (struct ebt_entry_target *)
700 (((char *)e) + e->target_offset);
701 if (strcmp(t->u.name, EBT_STANDARD_TARGET))
702 goto letscontinue;
703 if (e->target_offset + sizeof(struct ebt_standard_target) >
704 e->next_offset) {
705 BUGPRINT("Standard target size too big\n");
706 return -1;
708 verdict = ((struct ebt_standard_target *)t)->verdict;
709 if (verdict >= 0) { /* jump to another chain */
710 struct ebt_entries *hlp2 =
711 (struct ebt_entries *)(base + verdict);
712 for (i = 0; i < udc_cnt; i++)
713 if (hlp2 == cl_s[i].cs.chaininfo)
714 break;
715 /* bad destination or loop */
716 if (i == udc_cnt) {
717 BUGPRINT("bad destination\n");
718 return -1;
720 if (cl_s[i].cs.n) {
721 BUGPRINT("loop\n");
722 return -1;
724 /* this can't be 0, so the above test is correct */
725 cl_s[i].cs.n = pos + 1;
726 pos = 0;
727 cl_s[i].cs.e = ((void *)e + e->next_offset);
728 e = (struct ebt_entry *)(hlp2->data);
729 nentries = hlp2->nentries;
730 cl_s[i].from = chain_nr;
731 chain_nr = i;
732 /* this udc is accessible from the base chain for hooknr */
733 cl_s[i].hookmask |= (1 << hooknr);
734 continue;
736 letscontinue:
737 e = (void *)e + e->next_offset;
738 pos++;
740 return 0;
743 /* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
744 static int translate_table(struct ebt_replace *repl,
745 struct ebt_table_info *newinfo)
747 unsigned int i, j, k, udc_cnt;
748 int ret;
749 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
751 i = 0;
752 while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i)))
753 i++;
754 if (i == NF_BR_NUMHOOKS) {
755 BUGPRINT("No valid hooks specified\n");
756 return -EINVAL;
758 if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) {
759 BUGPRINT("Chains don't start at beginning\n");
760 return -EINVAL;
762 /* make sure chains are ordered after each other in same order
763 as their corresponding hooks */
764 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
765 if (!(repl->valid_hooks & (1 << j)))
766 continue;
767 if ( repl->hook_entry[j] <= repl->hook_entry[i] ) {
768 BUGPRINT("Hook order must be followed\n");
769 return -EINVAL;
771 i = j;
774 for (i = 0; i < NF_BR_NUMHOOKS; i++)
775 newinfo->hook_entry[i] = NULL;
777 newinfo->entries_size = repl->entries_size;
778 newinfo->nentries = repl->nentries;
780 /* do some early checkings and initialize some things */
781 i = 0; /* holds the expected nr. of entries for the chain */
782 j = 0; /* holds the up to now counted entries for the chain */
783 k = 0; /* holds the total nr. of entries, should equal
784 newinfo->nentries afterwards */
785 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
786 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
787 ebt_check_entry_size_and_hooks, newinfo, repl->entries,
788 repl->entries + repl->entries_size, repl->hook_entry, &i, &j, &k,
789 &udc_cnt, repl->valid_hooks);
791 if (ret != 0)
792 return ret;
794 if (i != j) {
795 BUGPRINT("nentries does not equal the nr of entries in the "
796 "(last) chain\n");
797 return -EINVAL;
799 if (k != newinfo->nentries) {
800 BUGPRINT("Total nentries is wrong\n");
801 return -EINVAL;
804 /* check if all valid hooks have a chain */
805 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
806 if (newinfo->hook_entry[i] == NULL &&
807 (repl->valid_hooks & (1 << i))) {
808 BUGPRINT("Valid hook without chain\n");
809 return -EINVAL;
813 /* get the location of the udc, put them in an array
814 while we're at it, allocate the chainstack */
815 if (udc_cnt) {
816 /* this will get free'd in do_replace()/ebt_register_table()
817 if an error occurs */
818 newinfo->chainstack = (struct ebt_chainstack **)
819 vmalloc(NR_CPUS * sizeof(struct ebt_chainstack));
820 if (!newinfo->chainstack)
821 return -ENOMEM;
822 for (i = 0; i < NR_CPUS; i++) {
823 newinfo->chainstack[i] =
824 vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
825 if (!newinfo->chainstack[i]) {
826 while (i)
827 vfree(newinfo->chainstack[--i]);
828 vfree(newinfo->chainstack);
829 newinfo->chainstack = NULL;
830 return -ENOMEM;
834 cl_s = (struct ebt_cl_stack *)
835 vmalloc(udc_cnt * sizeof(struct ebt_cl_stack));
836 if (!cl_s)
837 return -ENOMEM;
838 i = 0; /* the i'th udc */
839 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
840 ebt_get_udc_positions, newinfo, repl->hook_entry, &i,
841 repl->valid_hooks, cl_s);
842 /* sanity check */
843 if (i != udc_cnt) {
844 BUGPRINT("i != udc_cnt\n");
845 vfree(cl_s);
846 return -EFAULT;
850 /* Check for loops */
851 for (i = 0; i < NF_BR_NUMHOOKS; i++)
852 if (repl->valid_hooks & (1 << i))
853 if (check_chainloops(newinfo->hook_entry[i],
854 cl_s, udc_cnt, i, newinfo->entries)) {
855 if (cl_s)
856 vfree(cl_s);
857 return -EINVAL;
860 /* we now know the following (along with E=mc²):
861 - the nr of entries in each chain is right
862 - the size of the allocated space is right
863 - all valid hooks have a corresponding chain
864 - there are no loops
865 - wrong data can still be on the level of a single entry
866 - could be there are jumps to places that are not the
867 beginning of a chain. This can only occur in chains that
868 are not accessible from any base chains, so we don't care. */
870 /* used to know what we need to clean up if something goes wrong */
871 i = 0;
872 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
873 ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks,
874 cl_s, udc_cnt);
875 if (ret != 0) {
876 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
877 ebt_cleanup_entry, &i);
879 if (cl_s)
880 vfree(cl_s);
881 return ret;
884 /* called under write_lock */
885 static void get_counters(struct ebt_counter *oldcounters,
886 struct ebt_counter *counters, unsigned int nentries)
888 int i, cpu;
889 struct ebt_counter *counter_base;
891 /* counters of cpu 0 */
892 memcpy(counters, oldcounters,
893 sizeof(struct ebt_counter) * nentries);
894 /* add other counters to those of cpu 0 */
895 for (cpu = 1; cpu < NR_CPUS; cpu++) {
896 counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
897 for (i = 0; i < nentries; i++) {
898 counters[i].pcnt += counter_base[i].pcnt;
899 counters[i].bcnt += counter_base[i].bcnt;
904 /* replace the table */
905 static int do_replace(void __user *user, unsigned int len)
907 int ret, i, countersize;
908 struct ebt_table_info *newinfo;
909 struct ebt_replace tmp;
910 struct ebt_table *t;
911 struct ebt_counter *counterstmp = NULL;
912 /* used to be able to unlock earlier */
913 struct ebt_table_info *table;
915 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
916 return -EFAULT;
918 if (len != sizeof(tmp) + tmp.entries_size) {
919 BUGPRINT("Wrong len argument\n");
920 return -EINVAL;
923 if (tmp.entries_size == 0) {
924 BUGPRINT("Entries_size never zero\n");
925 return -EINVAL;
927 countersize = COUNTER_OFFSET(tmp.nentries) * NR_CPUS;
928 newinfo = (struct ebt_table_info *)
929 vmalloc(sizeof(struct ebt_table_info) + countersize);
930 if (!newinfo)
931 return -ENOMEM;
933 if (countersize)
934 memset(newinfo->counters, 0, countersize);
936 newinfo->entries = (char *)vmalloc(tmp.entries_size);
937 if (!newinfo->entries) {
938 ret = -ENOMEM;
939 goto free_newinfo;
941 if (copy_from_user(
942 newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
943 BUGPRINT("Couldn't copy entries from userspace\n");
944 ret = -EFAULT;
945 goto free_entries;
948 /* the user wants counters back
949 the check on the size is done later, when we have the lock */
950 if (tmp.num_counters) {
951 counterstmp = (struct ebt_counter *)
952 vmalloc(tmp.num_counters * sizeof(struct ebt_counter));
953 if (!counterstmp) {
954 ret = -ENOMEM;
955 goto free_entries;
958 else
959 counterstmp = NULL;
961 /* this can get initialized by translate_table() */
962 newinfo->chainstack = NULL;
963 ret = translate_table(&tmp, newinfo);
965 if (ret != 0)
966 goto free_counterstmp;
968 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
969 if (!t) {
970 ret = -ENOENT;
971 goto free_iterate;
974 /* the table doesn't like it */
975 if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
976 goto free_unlock;
978 if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
979 BUGPRINT("Wrong nr. of counters requested\n");
980 ret = -EINVAL;
981 goto free_unlock;
984 /* we have the mutex lock, so no danger in reading this pointer */
985 table = t->private;
986 /* make sure the table can only be rmmod'ed if it contains no rules */
987 if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
988 ret = -ENOENT;
989 goto free_unlock;
990 } else if (table->nentries && !newinfo->nentries)
991 module_put(t->me);
992 /* we need an atomic snapshot of the counters */
993 write_lock_bh(&t->lock);
994 if (tmp.num_counters)
995 get_counters(t->private->counters, counterstmp,
996 t->private->nentries);
998 t->private = newinfo;
999 write_unlock_bh(&t->lock);
1000 up(&ebt_mutex);
1001 /* so, a user can change the chains while having messed up her counter
1002 allocation. Only reason why this is done is because this way the lock
1003 is held only once, while this doesn't bring the kernel into a
1004 dangerous state. */
1005 if (tmp.num_counters &&
1006 copy_to_user(tmp.counters, counterstmp,
1007 tmp.num_counters * sizeof(struct ebt_counter))) {
1008 BUGPRINT("Couldn't copy counters to userspace\n");
1009 ret = -EFAULT;
1011 else
1012 ret = 0;
1014 /* decrease module count and free resources */
1015 EBT_ENTRY_ITERATE(table->entries, table->entries_size,
1016 ebt_cleanup_entry, NULL);
1018 vfree(table->entries);
1019 if (table->chainstack) {
1020 for (i = 0; i < NR_CPUS; i++)
1021 vfree(table->chainstack[i]);
1022 vfree(table->chainstack);
1024 vfree(table);
1026 if (counterstmp)
1027 vfree(counterstmp);
1028 return ret;
1030 free_unlock:
1031 up(&ebt_mutex);
1032 free_iterate:
1033 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1034 ebt_cleanup_entry, NULL);
1035 free_counterstmp:
1036 if (counterstmp)
1037 vfree(counterstmp);
1038 /* can be initialized in translate_table() */
1039 if (newinfo->chainstack) {
1040 for (i = 0; i < NR_CPUS; i++)
1041 vfree(newinfo->chainstack[i]);
1042 vfree(newinfo->chainstack);
1044 free_entries:
1045 if (newinfo->entries)
1046 vfree(newinfo->entries);
1047 free_newinfo:
1048 if (newinfo)
1049 vfree(newinfo);
1050 return ret;
1053 int ebt_register_target(struct ebt_target *target)
1055 int ret;
1057 ret = down_interruptible(&ebt_mutex);
1058 if (ret != 0)
1059 return ret;
1060 if (!list_named_insert(&ebt_targets, target)) {
1061 up(&ebt_mutex);
1062 return -EEXIST;
1064 up(&ebt_mutex);
1066 return 0;
1069 void ebt_unregister_target(struct ebt_target *target)
1071 down(&ebt_mutex);
1072 LIST_DELETE(&ebt_targets, target);
1073 up(&ebt_mutex);
1076 int ebt_register_match(struct ebt_match *match)
1078 int ret;
1080 ret = down_interruptible(&ebt_mutex);
1081 if (ret != 0)
1082 return ret;
1083 if (!list_named_insert(&ebt_matches, match)) {
1084 up(&ebt_mutex);
1085 return -EEXIST;
1087 up(&ebt_mutex);
1089 return 0;
1092 void ebt_unregister_match(struct ebt_match *match)
1094 down(&ebt_mutex);
1095 LIST_DELETE(&ebt_matches, match);
1096 up(&ebt_mutex);
1099 int ebt_register_watcher(struct ebt_watcher *watcher)
1101 int ret;
1103 ret = down_interruptible(&ebt_mutex);
1104 if (ret != 0)
1105 return ret;
1106 if (!list_named_insert(&ebt_watchers, watcher)) {
1107 up(&ebt_mutex);
1108 return -EEXIST;
1110 up(&ebt_mutex);
1112 return 0;
1115 void ebt_unregister_watcher(struct ebt_watcher *watcher)
1117 down(&ebt_mutex);
1118 LIST_DELETE(&ebt_watchers, watcher);
1119 up(&ebt_mutex);
1122 int ebt_register_table(struct ebt_table *table)
1124 struct ebt_table_info *newinfo;
1125 int ret, i, countersize;
1127 if (!table || !table->table ||!table->table->entries ||
1128 table->table->entries_size == 0 ||
1129 table->table->counters || table->private) {
1130 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1131 return -EINVAL;
1134 countersize = COUNTER_OFFSET(table->table->nentries) * NR_CPUS;
1135 newinfo = (struct ebt_table_info *)
1136 vmalloc(sizeof(struct ebt_table_info) + countersize);
1137 ret = -ENOMEM;
1138 if (!newinfo)
1139 return -ENOMEM;
1141 newinfo->entries = (char *)vmalloc(table->table->entries_size);
1142 if (!(newinfo->entries))
1143 goto free_newinfo;
1145 memcpy(newinfo->entries, table->table->entries,
1146 table->table->entries_size);
1148 if (countersize)
1149 memset(newinfo->counters, 0, countersize);
1151 /* fill in newinfo and parse the entries */
1152 newinfo->chainstack = NULL;
1153 ret = translate_table(table->table, newinfo);
1154 if (ret != 0) {
1155 BUGPRINT("Translate_table failed\n");
1156 goto free_chainstack;
1159 if (table->check && table->check(newinfo, table->valid_hooks)) {
1160 BUGPRINT("The table doesn't like its own initial data, lol\n");
1161 return -EINVAL;
1164 table->private = newinfo;
1165 table->lock = RW_LOCK_UNLOCKED;
1166 ret = down_interruptible(&ebt_mutex);
1167 if (ret != 0)
1168 goto free_chainstack;
1170 if (list_named_find(&ebt_tables, table->name)) {
1171 ret = -EEXIST;
1172 BUGPRINT("Table name already exists\n");
1173 goto free_unlock;
1176 /* Hold a reference count if the chains aren't empty */
1177 if (newinfo->nentries && !try_module_get(table->me)) {
1178 ret = -ENOENT;
1179 goto free_unlock;
1181 list_prepend(&ebt_tables, table);
1182 up(&ebt_mutex);
1183 return 0;
1184 free_unlock:
1185 up(&ebt_mutex);
1186 free_chainstack:
1187 if (newinfo->chainstack) {
1188 for (i = 0; i < NR_CPUS; i++)
1189 vfree(newinfo->chainstack[i]);
1190 vfree(newinfo->chainstack);
1192 vfree(newinfo->entries);
1193 free_newinfo:
1194 vfree(newinfo);
1195 return ret;
1198 void ebt_unregister_table(struct ebt_table *table)
1200 int i;
1202 if (!table) {
1203 BUGPRINT("Request to unregister NULL table!!!\n");
1204 return;
1206 down(&ebt_mutex);
1207 LIST_DELETE(&ebt_tables, table);
1208 up(&ebt_mutex);
1209 if (table->private->entries)
1210 vfree(table->private->entries);
1211 if (table->private->chainstack) {
1212 for (i = 0; i < NR_CPUS; i++)
1213 vfree(table->private->chainstack[i]);
1214 vfree(table->private->chainstack);
1216 vfree(table->private);
1219 /* userspace just supplied us with counters */
1220 static int update_counters(void __user *user, unsigned int len)
1222 int i, ret;
1223 struct ebt_counter *tmp;
1224 struct ebt_replace hlp;
1225 struct ebt_table *t;
1227 if (copy_from_user(&hlp, user, sizeof(hlp)))
1228 return -EFAULT;
1230 if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
1231 return -EINVAL;
1232 if (hlp.num_counters == 0)
1233 return -EINVAL;
1235 if ( !(tmp = (struct ebt_counter *)
1236 vmalloc(hlp.num_counters * sizeof(struct ebt_counter))) ){
1237 MEMPRINT("Update_counters && nomemory\n");
1238 return -ENOMEM;
1241 t = find_table_lock(hlp.name, &ret, &ebt_mutex);
1242 if (!t)
1243 goto free_tmp;
1245 if (hlp.num_counters != t->private->nentries) {
1246 BUGPRINT("Wrong nr of counters\n");
1247 ret = -EINVAL;
1248 goto unlock_mutex;
1251 if ( copy_from_user(tmp, hlp.counters,
1252 hlp.num_counters * sizeof(struct ebt_counter)) ) {
1253 BUGPRINT("Updata_counters && !cfu\n");
1254 ret = -EFAULT;
1255 goto unlock_mutex;
1258 /* we want an atomic add of the counters */
1259 write_lock_bh(&t->lock);
1261 /* we add to the counters of the first cpu */
1262 for (i = 0; i < hlp.num_counters; i++) {
1263 t->private->counters[i].pcnt += tmp[i].pcnt;
1264 t->private->counters[i].bcnt += tmp[i].bcnt;
1267 write_unlock_bh(&t->lock);
1268 ret = 0;
1269 unlock_mutex:
1270 up(&ebt_mutex);
1271 free_tmp:
1272 vfree(tmp);
1273 return ret;
1276 static inline int ebt_make_matchname(struct ebt_entry_match *m,
1277 char *base, char *ubase)
1279 char *hlp = ubase - base + (char *)m;
1280 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
1281 return -EFAULT;
1282 return 0;
1285 static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
1286 char *base, char *ubase)
1288 char *hlp = ubase - base + (char *)w;
1289 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
1290 return -EFAULT;
1291 return 0;
1294 static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase)
1296 int ret;
1297 char *hlp;
1298 struct ebt_entry_target *t;
1300 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
1301 return 0;
1303 hlp = ubase - base + (char *)e + e->target_offset;
1304 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
1306 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
1307 if (ret != 0)
1308 return ret;
1309 ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
1310 if (ret != 0)
1311 return ret;
1312 if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN))
1313 return -EFAULT;
1314 return 0;
1317 /* called with ebt_mutex down */
1318 static int copy_everything_to_user(struct ebt_table *t, void __user *user,
1319 int *len, int cmd)
1321 struct ebt_replace tmp;
1322 struct ebt_counter *counterstmp, *oldcounters;
1323 unsigned int entries_size, nentries;
1324 char *entries;
1326 if (cmd == EBT_SO_GET_ENTRIES) {
1327 entries_size = t->private->entries_size;
1328 nentries = t->private->nentries;
1329 entries = t->private->entries;
1330 oldcounters = t->private->counters;
1331 } else {
1332 entries_size = t->table->entries_size;
1333 nentries = t->table->nentries;
1334 entries = t->table->entries;
1335 oldcounters = t->table->counters;
1338 if (copy_from_user(&tmp, user, sizeof(tmp))) {
1339 BUGPRINT("Cfu didn't work\n");
1340 return -EFAULT;
1343 if (*len != sizeof(struct ebt_replace) + entries_size +
1344 (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
1345 BUGPRINT("Wrong size\n");
1346 return -EINVAL;
1349 if (tmp.nentries != nentries) {
1350 BUGPRINT("Nentries wrong\n");
1351 return -EINVAL;
1354 if (tmp.entries_size != entries_size) {
1355 BUGPRINT("Wrong size\n");
1356 return -EINVAL;
1359 /* userspace might not need the counters */
1360 if (tmp.num_counters) {
1361 if (tmp.num_counters != nentries) {
1362 BUGPRINT("Num_counters wrong\n");
1363 return -EINVAL;
1365 counterstmp = (struct ebt_counter *)
1366 vmalloc(nentries * sizeof(struct ebt_counter));
1367 if (!counterstmp) {
1368 MEMPRINT("Couldn't copy counters, out of memory\n");
1369 return -ENOMEM;
1371 write_lock_bh(&t->lock);
1372 get_counters(oldcounters, counterstmp, nentries);
1373 write_unlock_bh(&t->lock);
1375 if (copy_to_user(tmp.counters, counterstmp,
1376 nentries * sizeof(struct ebt_counter))) {
1377 BUGPRINT("Couldn't copy counters to userspace\n");
1378 vfree(counterstmp);
1379 return -EFAULT;
1381 vfree(counterstmp);
1384 if (copy_to_user(tmp.entries, entries, entries_size)) {
1385 BUGPRINT("Couldn't copy entries to userspace\n");
1386 return -EFAULT;
1388 /* set the match/watcher/target names right */
1389 return EBT_ENTRY_ITERATE(entries, entries_size,
1390 ebt_make_names, entries, tmp.entries);
1393 static int do_ebt_set_ctl(struct sock *sk,
1394 int cmd, void __user *user, unsigned int len)
1396 int ret;
1398 switch(cmd) {
1399 case EBT_SO_SET_ENTRIES:
1400 ret = do_replace(user, len);
1401 break;
1402 case EBT_SO_SET_COUNTERS:
1403 ret = update_counters(user, len);
1404 break;
1405 default:
1406 ret = -EINVAL;
1408 return ret;
1411 static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1413 int ret;
1414 struct ebt_replace tmp;
1415 struct ebt_table *t;
1417 if (copy_from_user(&tmp, user, sizeof(tmp)))
1418 return -EFAULT;
1420 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
1421 if (!t)
1422 return ret;
1424 switch(cmd) {
1425 case EBT_SO_GET_INFO:
1426 case EBT_SO_GET_INIT_INFO:
1427 if (*len != sizeof(struct ebt_replace)){
1428 ret = -EINVAL;
1429 up(&ebt_mutex);
1430 break;
1432 if (cmd == EBT_SO_GET_INFO) {
1433 tmp.nentries = t->private->nentries;
1434 tmp.entries_size = t->private->entries_size;
1435 tmp.valid_hooks = t->valid_hooks;
1436 } else {
1437 tmp.nentries = t->table->nentries;
1438 tmp.entries_size = t->table->entries_size;
1439 tmp.valid_hooks = t->table->valid_hooks;
1441 up(&ebt_mutex);
1442 if (copy_to_user(user, &tmp, *len) != 0){
1443 BUGPRINT("c2u Didn't work\n");
1444 ret = -EFAULT;
1445 break;
1447 ret = 0;
1448 break;
1450 case EBT_SO_GET_ENTRIES:
1451 case EBT_SO_GET_INIT_ENTRIES:
1452 ret = copy_everything_to_user(t, user, len, cmd);
1453 up(&ebt_mutex);
1454 break;
1456 default:
1457 up(&ebt_mutex);
1458 ret = -EINVAL;
1461 return ret;
1464 static struct nf_sockopt_ops ebt_sockopts =
1465 { { NULL, NULL }, PF_INET, EBT_BASE_CTL, EBT_SO_SET_MAX + 1, do_ebt_set_ctl,
1466 EBT_BASE_CTL, EBT_SO_GET_MAX + 1, do_ebt_get_ctl, 0, NULL
1469 static int __init init(void)
1471 int ret;
1473 down(&ebt_mutex);
1474 list_named_insert(&ebt_targets, &ebt_standard_target);
1475 up(&ebt_mutex);
1476 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
1477 return ret;
1479 printk(KERN_NOTICE "Ebtables v2.0 registered\n");
1480 return 0;
1483 static void __exit fini(void)
1485 nf_unregister_sockopt(&ebt_sockopts);
1486 printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
1489 EXPORT_SYMBOL(ebt_register_table);
1490 EXPORT_SYMBOL(ebt_unregister_table);
1491 EXPORT_SYMBOL(ebt_register_match);
1492 EXPORT_SYMBOL(ebt_unregister_match);
1493 EXPORT_SYMBOL(ebt_register_watcher);
1494 EXPORT_SYMBOL(ebt_unregister_watcher);
1495 EXPORT_SYMBOL(ebt_register_target);
1496 EXPORT_SYMBOL(ebt_unregister_target);
1497 EXPORT_SYMBOL(ebt_do_table);
1498 module_init(init);
1499 module_exit(fini);
1500 MODULE_LICENSE("GPL");