netfilter: xtables: add const qualifiers
[linux-2.6/kvm.git] / net / bridge / netfilter / ebtables.c
blobbcdf02d866b8d879f658ea20a635ed0a51836b08
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.
19 #include <linux/kmod.h>
20 #include <linux/module.h>
21 #include <linux/vmalloc.h>
22 #include <linux/netfilter/x_tables.h>
23 #include <linux/netfilter_bridge/ebtables.h>
24 #include <linux/spinlock.h>
25 #include <linux/mutex.h>
26 #include <asm/uaccess.h>
27 #include <linux/smp.h>
28 #include <linux/cpumask.h>
29 #include <net/sock.h>
30 /* needed for logical [in,out]-dev filtering */
31 #include "../br_private.h"
33 #define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\
34 "report to author: "format, ## args)
35 /* #define BUGPRINT(format, args...) */
36 #define MEMPRINT(format, args...) printk("kernel msg: ebtables "\
37 ": out of memory: "format, ## args)
38 /* #define MEMPRINT(format, args...) */
43 * Each cpu has its own set of counters, so there is no need for write_lock in
44 * the softirq
45 * For reading or updating the counters, the user context needs to
46 * get a write_lock
49 /* The size of each set of counters is altered to get cache alignment */
50 #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
51 #define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))
52 #define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \
53 COUNTER_OFFSET(n) * cpu))
57 static DEFINE_MUTEX(ebt_mutex);
59 static struct xt_target ebt_standard_target = {
60 .name = "standard",
61 .revision = 0,
62 .family = NFPROTO_BRIDGE,
63 .targetsize = sizeof(int),
66 static inline int
67 ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
68 struct xt_target_param *par)
70 par->target = w->u.watcher;
71 par->targinfo = w->data;
72 w->u.watcher->target(skb, par);
73 /* watchers don't give a verdict */
74 return 0;
77 static inline int ebt_do_match (struct ebt_entry_match *m,
78 const struct sk_buff *skb, struct xt_match_param *par)
80 par->match = m->u.match;
81 par->matchinfo = m->data;
82 return m->u.match->match(skb, par) ? EBT_MATCH : EBT_NOMATCH;
85 static inline int
86 ebt_dev_check(const char *entry, const struct net_device *device)
88 int i = 0;
89 const char *devname;
91 if (*entry == '\0')
92 return 0;
93 if (!device)
94 return 1;
95 devname = device->name;
96 /* 1 is the wildcard token */
97 while (entry[i] != '\0' && entry[i] != 1 && entry[i] == devname[i])
98 i++;
99 return (devname[i] != entry[i] && entry[i] != 1);
102 #define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg))
103 /* process standard matches */
104 static inline int
105 ebt_basic_match(const struct ebt_entry *e, const struct ethhdr *h,
106 const struct net_device *in, const struct net_device *out)
108 int verdict, i;
110 if (e->bitmask & EBT_802_3) {
111 if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO))
112 return 1;
113 } else if (!(e->bitmask & EBT_NOPROTO) &&
114 FWINV2(e->ethproto != h->h_proto, EBT_IPROTO))
115 return 1;
117 if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN))
118 return 1;
119 if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
120 return 1;
121 if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check(
122 e->logical_in, in->br_port->br->dev), EBT_ILOGICALIN))
123 return 1;
124 if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check(
125 e->logical_out, out->br_port->br->dev), EBT_ILOGICALOUT))
126 return 1;
128 if (e->bitmask & EBT_SOURCEMAC) {
129 verdict = 0;
130 for (i = 0; i < 6; i++)
131 verdict |= (h->h_source[i] ^ e->sourcemac[i]) &
132 e->sourcemsk[i];
133 if (FWINV2(verdict != 0, EBT_ISOURCE) )
134 return 1;
136 if (e->bitmask & EBT_DESTMAC) {
137 verdict = 0;
138 for (i = 0; i < 6; i++)
139 verdict |= (h->h_dest[i] ^ e->destmac[i]) &
140 e->destmsk[i];
141 if (FWINV2(verdict != 0, EBT_IDEST) )
142 return 1;
144 return 0;
147 static inline __pure
148 struct ebt_entry *ebt_next_entry(const struct ebt_entry *entry)
150 return (void *)entry + entry->next_offset;
153 /* Do some firewalling */
154 unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
155 const struct net_device *in, const struct net_device *out,
156 struct ebt_table *table)
158 int i, nentries;
159 struct ebt_entry *point;
160 struct ebt_counter *counter_base, *cb_base;
161 const struct ebt_entry_target *t;
162 int verdict, sp = 0;
163 struct ebt_chainstack *cs;
164 struct ebt_entries *chaininfo;
165 const char *base;
166 const struct ebt_table_info *private;
167 bool hotdrop = false;
168 struct xt_match_param mtpar;
169 struct xt_target_param tgpar;
171 mtpar.family = tgpar.family = NFPROTO_BRIDGE;
172 mtpar.in = tgpar.in = in;
173 mtpar.out = tgpar.out = out;
174 mtpar.hotdrop = &hotdrop;
175 mtpar.hooknum = tgpar.hooknum = hook;
177 read_lock_bh(&table->lock);
178 private = table->private;
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(skb), in, out))
194 goto letscontinue;
196 if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &mtpar) != 0)
197 goto letscontinue;
198 if (hotdrop) {
199 read_unlock_bh(&table->lock);
200 return NF_DROP;
203 /* increase counter */
204 (*(counter_base + i)).pcnt++;
205 (*(counter_base + i)).bcnt += skb->len;
207 /* these should only watch: not modify, nor tell us
208 what to do with the packet */
209 EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &tgpar);
211 t = (struct ebt_entry_target *)
212 (((char *)point) + point->target_offset);
213 /* standard target */
214 if (!t->u.target->target)
215 verdict = ((struct ebt_standard_target *)t)->verdict;
216 else {
217 tgpar.target = t->u.target;
218 tgpar.targinfo = t->data;
219 verdict = t->u.target->target(skb, &tgpar);
221 if (verdict == EBT_ACCEPT) {
222 read_unlock_bh(&table->lock);
223 return NF_ACCEPT;
225 if (verdict == EBT_DROP) {
226 read_unlock_bh(&table->lock);
227 return NF_DROP;
229 if (verdict == EBT_RETURN) {
230 letsreturn:
231 #ifdef CONFIG_NETFILTER_DEBUG
232 if (sp == 0) {
233 BUGPRINT("RETURN on base chain");
234 /* act like this is EBT_CONTINUE */
235 goto letscontinue;
237 #endif
238 sp--;
239 /* put all the local variables right */
240 i = cs[sp].n;
241 chaininfo = cs[sp].chaininfo;
242 nentries = chaininfo->nentries;
243 point = cs[sp].e;
244 counter_base = cb_base +
245 chaininfo->counter_offset;
246 continue;
248 if (verdict == EBT_CONTINUE)
249 goto letscontinue;
250 #ifdef CONFIG_NETFILTER_DEBUG
251 if (verdict < 0) {
252 BUGPRINT("bogus standard verdict\n");
253 read_unlock_bh(&table->lock);
254 return NF_DROP;
256 #endif
257 /* jump to a udc */
258 cs[sp].n = i + 1;
259 cs[sp].chaininfo = chaininfo;
260 cs[sp].e = ebt_next_entry(point);
261 i = 0;
262 chaininfo = (struct ebt_entries *) (base + verdict);
263 #ifdef CONFIG_NETFILTER_DEBUG
264 if (chaininfo->distinguisher) {
265 BUGPRINT("jump to non-chain\n");
266 read_unlock_bh(&table->lock);
267 return NF_DROP;
269 #endif
270 nentries = chaininfo->nentries;
271 point = (struct ebt_entry *)chaininfo->data;
272 counter_base = cb_base + chaininfo->counter_offset;
273 sp++;
274 continue;
275 letscontinue:
276 point = ebt_next_entry(point);
277 i++;
280 /* I actually like this :) */
281 if (chaininfo->policy == EBT_RETURN)
282 goto letsreturn;
283 if (chaininfo->policy == EBT_ACCEPT) {
284 read_unlock_bh(&table->lock);
285 return NF_ACCEPT;
287 read_unlock_bh(&table->lock);
288 return NF_DROP;
291 /* If it succeeds, returns element and locks mutex */
292 static inline void *
293 find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
294 struct mutex *mutex)
296 struct {
297 struct list_head list;
298 char name[EBT_FUNCTION_MAXNAMELEN];
299 } *e;
301 *error = mutex_lock_interruptible(mutex);
302 if (*error != 0)
303 return NULL;
305 list_for_each_entry(e, head, list) {
306 if (strcmp(e->name, name) == 0)
307 return e;
309 *error = -ENOENT;
310 mutex_unlock(mutex);
311 return NULL;
314 static void *
315 find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
316 int *error, struct mutex *mutex)
318 return try_then_request_module(
319 find_inlist_lock_noload(head, name, error, mutex),
320 "%s%s", prefix, name);
323 static inline struct ebt_table *
324 find_table_lock(struct net *net, const char *name, int *error,
325 struct mutex *mutex)
327 return find_inlist_lock(&net->xt.tables[NFPROTO_BRIDGE], name,
328 "ebtable_", error, mutex);
331 static inline int
332 ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
333 unsigned int *cnt)
335 const struct ebt_entry *e = par->entryinfo;
336 struct xt_match *match;
337 size_t left = ((char *)e + e->watchers_offset) - (char *)m;
338 int ret;
340 if (left < sizeof(struct ebt_entry_match) ||
341 left - sizeof(struct ebt_entry_match) < m->match_size)
342 return -EINVAL;
344 match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE,
345 m->u.name, 0), "ebt_%s", m->u.name);
346 if (IS_ERR(match))
347 return PTR_ERR(match);
348 if (match == NULL)
349 return -ENOENT;
350 m->u.match = match;
352 par->match = match;
353 par->matchinfo = m->data;
354 ret = xt_check_match(par, m->match_size,
355 e->ethproto, e->invflags & EBT_IPROTO);
356 if (ret < 0) {
357 module_put(match->me);
358 return ret;
361 (*cnt)++;
362 return 0;
365 static inline int
366 ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
367 unsigned int *cnt)
369 const struct ebt_entry *e = par->entryinfo;
370 struct xt_target *watcher;
371 size_t left = ((char *)e + e->target_offset) - (char *)w;
372 int ret;
374 if (left < sizeof(struct ebt_entry_watcher) ||
375 left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
376 return -EINVAL;
378 watcher = try_then_request_module(
379 xt_find_target(NFPROTO_BRIDGE, w->u.name, 0),
380 "ebt_%s", w->u.name);
381 if (IS_ERR(watcher))
382 return PTR_ERR(watcher);
383 if (watcher == NULL)
384 return -ENOENT;
385 w->u.watcher = watcher;
387 par->target = watcher;
388 par->targinfo = w->data;
389 ret = xt_check_target(par, w->watcher_size,
390 e->ethproto, e->invflags & EBT_IPROTO);
391 if (ret < 0) {
392 module_put(watcher->me);
393 return ret;
396 (*cnt)++;
397 return 0;
400 static int ebt_verify_pointers(const struct ebt_replace *repl,
401 struct ebt_table_info *newinfo)
403 unsigned int limit = repl->entries_size;
404 unsigned int valid_hooks = repl->valid_hooks;
405 unsigned int offset = 0;
406 int i;
408 for (i = 0; i < NF_BR_NUMHOOKS; i++)
409 newinfo->hook_entry[i] = NULL;
411 newinfo->entries_size = repl->entries_size;
412 newinfo->nentries = repl->nentries;
414 while (offset < limit) {
415 size_t left = limit - offset;
416 struct ebt_entry *e = (void *)newinfo->entries + offset;
418 if (left < sizeof(unsigned int))
419 break;
421 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
422 if ((valid_hooks & (1 << i)) == 0)
423 continue;
424 if ((char __user *)repl->hook_entry[i] ==
425 repl->entries + offset)
426 break;
429 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
430 if (e->bitmask != 0) {
431 /* we make userspace set this right,
432 so there is no misunderstanding */
433 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
434 "in distinguisher\n");
435 return -EINVAL;
437 if (i != NF_BR_NUMHOOKS)
438 newinfo->hook_entry[i] = (struct ebt_entries *)e;
439 if (left < sizeof(struct ebt_entries))
440 break;
441 offset += sizeof(struct ebt_entries);
442 } else {
443 if (left < sizeof(struct ebt_entry))
444 break;
445 if (left < e->next_offset)
446 break;
447 offset += e->next_offset;
450 if (offset != limit) {
451 BUGPRINT("entries_size too small\n");
452 return -EINVAL;
455 /* check if all valid hooks have a chain */
456 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
457 if (!newinfo->hook_entry[i] &&
458 (valid_hooks & (1 << i))) {
459 BUGPRINT("Valid hook without chain\n");
460 return -EINVAL;
463 return 0;
467 * this one is very careful, as it is the first function
468 * to parse the userspace data
470 static inline int
471 ebt_check_entry_size_and_hooks(const struct ebt_entry *e,
472 const struct ebt_table_info *newinfo,
473 unsigned int *n, unsigned int *cnt,
474 unsigned int *totalcnt, unsigned int *udc_cnt)
476 int i;
478 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
479 if ((void *)e == (void *)newinfo->hook_entry[i])
480 break;
482 /* beginning of a new chain
483 if i == NF_BR_NUMHOOKS it must be a user defined chain */
484 if (i != NF_BR_NUMHOOKS || !e->bitmask) {
485 /* this checks if the previous chain has as many entries
486 as it said it has */
487 if (*n != *cnt) {
488 BUGPRINT("nentries does not equal the nr of entries "
489 "in the chain\n");
490 return -EINVAL;
492 if (((struct ebt_entries *)e)->policy != EBT_DROP &&
493 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
494 /* only RETURN from udc */
495 if (i != NF_BR_NUMHOOKS ||
496 ((struct ebt_entries *)e)->policy != EBT_RETURN) {
497 BUGPRINT("bad policy\n");
498 return -EINVAL;
501 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
502 (*udc_cnt)++;
503 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
504 BUGPRINT("counter_offset != totalcnt");
505 return -EINVAL;
507 *n = ((struct ebt_entries *)e)->nentries;
508 *cnt = 0;
509 return 0;
511 /* a plain old entry, heh */
512 if (sizeof(struct ebt_entry) > e->watchers_offset ||
513 e->watchers_offset > e->target_offset ||
514 e->target_offset >= e->next_offset) {
515 BUGPRINT("entry offsets not in right order\n");
516 return -EINVAL;
518 /* this is not checked anywhere else */
519 if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) {
520 BUGPRINT("target size too small\n");
521 return -EINVAL;
523 (*cnt)++;
524 (*totalcnt)++;
525 return 0;
528 struct ebt_cl_stack
530 struct ebt_chainstack cs;
531 int from;
532 unsigned int hookmask;
536 * we need these positions to check that the jumps to a different part of the
537 * entries is a jump to the beginning of a new chain.
539 static inline int
540 ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
541 unsigned int *n, struct ebt_cl_stack *udc)
543 int i;
545 /* we're only interested in chain starts */
546 if (e->bitmask)
547 return 0;
548 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
549 if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
550 break;
552 /* only care about udc */
553 if (i != NF_BR_NUMHOOKS)
554 return 0;
556 udc[*n].cs.chaininfo = (struct ebt_entries *)e;
557 /* these initialisations are depended on later in check_chainloops() */
558 udc[*n].cs.n = 0;
559 udc[*n].hookmask = 0;
561 (*n)++;
562 return 0;
565 static inline int
566 ebt_cleanup_match(struct ebt_entry_match *m, struct net *net, unsigned int *i)
568 struct xt_mtdtor_param par;
570 if (i && (*i)-- == 0)
571 return 1;
573 par.net = net;
574 par.match = m->u.match;
575 par.matchinfo = m->data;
576 par.family = NFPROTO_BRIDGE;
577 if (par.match->destroy != NULL)
578 par.match->destroy(&par);
579 module_put(par.match->me);
580 return 0;
583 static inline int
584 ebt_cleanup_watcher(struct ebt_entry_watcher *w, struct net *net, unsigned int *i)
586 struct xt_tgdtor_param par;
588 if (i && (*i)-- == 0)
589 return 1;
591 par.net = net;
592 par.target = w->u.watcher;
593 par.targinfo = w->data;
594 par.family = NFPROTO_BRIDGE;
595 if (par.target->destroy != NULL)
596 par.target->destroy(&par);
597 module_put(par.target->me);
598 return 0;
601 static inline int
602 ebt_cleanup_entry(struct ebt_entry *e, struct net *net, unsigned int *cnt)
604 struct xt_tgdtor_param par;
605 struct ebt_entry_target *t;
607 if (e->bitmask == 0)
608 return 0;
609 /* we're done */
610 if (cnt && (*cnt)-- == 0)
611 return 1;
612 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, net, NULL);
613 EBT_MATCH_ITERATE(e, ebt_cleanup_match, net, NULL);
614 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
616 par.net = net;
617 par.target = t->u.target;
618 par.targinfo = t->data;
619 par.family = NFPROTO_BRIDGE;
620 if (par.target->destroy != NULL)
621 par.target->destroy(&par);
622 module_put(par.target->me);
623 return 0;
626 static inline int
627 ebt_check_entry(struct ebt_entry *e, struct net *net,
628 const struct ebt_table_info *newinfo,
629 const char *name, unsigned int *cnt,
630 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
632 struct ebt_entry_target *t;
633 struct xt_target *target;
634 unsigned int i, j, hook = 0, hookmask = 0;
635 size_t gap;
636 int ret;
637 struct xt_mtchk_param mtpar;
638 struct xt_tgchk_param tgpar;
640 /* don't mess with the struct ebt_entries */
641 if (e->bitmask == 0)
642 return 0;
644 if (e->bitmask & ~EBT_F_MASK) {
645 BUGPRINT("Unknown flag for bitmask\n");
646 return -EINVAL;
648 if (e->invflags & ~EBT_INV_MASK) {
649 BUGPRINT("Unknown flag for inv bitmask\n");
650 return -EINVAL;
652 if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) {
653 BUGPRINT("NOPROTO & 802_3 not allowed\n");
654 return -EINVAL;
656 /* what hook do we belong to? */
657 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
658 if (!newinfo->hook_entry[i])
659 continue;
660 if ((char *)newinfo->hook_entry[i] < (char *)e)
661 hook = i;
662 else
663 break;
665 /* (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on
666 a base chain */
667 if (i < NF_BR_NUMHOOKS)
668 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
669 else {
670 for (i = 0; i < udc_cnt; i++)
671 if ((char *)(cl_s[i].cs.chaininfo) > (char *)e)
672 break;
673 if (i == 0)
674 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
675 else
676 hookmask = cl_s[i - 1].hookmask;
678 i = 0;
680 mtpar.net = tgpar.net = net;
681 mtpar.table = tgpar.table = name;
682 mtpar.entryinfo = tgpar.entryinfo = e;
683 mtpar.hook_mask = tgpar.hook_mask = hookmask;
684 mtpar.family = tgpar.family = NFPROTO_BRIDGE;
685 ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
686 if (ret != 0)
687 goto cleanup_matches;
688 j = 0;
689 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, &tgpar, &j);
690 if (ret != 0)
691 goto cleanup_watchers;
692 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
693 gap = e->next_offset - e->target_offset;
695 target = try_then_request_module(
696 xt_find_target(NFPROTO_BRIDGE, t->u.name, 0),
697 "ebt_%s", t->u.name);
698 if (IS_ERR(target)) {
699 ret = PTR_ERR(target);
700 goto cleanup_watchers;
701 } else if (target == NULL) {
702 ret = -ENOENT;
703 goto cleanup_watchers;
706 t->u.target = target;
707 if (t->u.target == &ebt_standard_target) {
708 if (gap < sizeof(struct ebt_standard_target)) {
709 BUGPRINT("Standard target size too big\n");
710 ret = -EFAULT;
711 goto cleanup_watchers;
713 if (((struct ebt_standard_target *)t)->verdict <
714 -NUM_STANDARD_TARGETS) {
715 BUGPRINT("Invalid standard target\n");
716 ret = -EFAULT;
717 goto cleanup_watchers;
719 } else if (t->target_size > gap - sizeof(struct ebt_entry_target)) {
720 module_put(t->u.target->me);
721 ret = -EFAULT;
722 goto cleanup_watchers;
725 tgpar.target = target;
726 tgpar.targinfo = t->data;
727 ret = xt_check_target(&tgpar, t->target_size,
728 e->ethproto, e->invflags & EBT_IPROTO);
729 if (ret < 0) {
730 module_put(target->me);
731 goto cleanup_watchers;
733 (*cnt)++;
734 return 0;
735 cleanup_watchers:
736 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, net, &j);
737 cleanup_matches:
738 EBT_MATCH_ITERATE(e, ebt_cleanup_match, net, &i);
739 return ret;
743 * checks for loops and sets the hook mask for udc
744 * the hook mask for udc tells us from which base chains the udc can be
745 * accessed. This mask is a parameter to the check() functions of the extensions
747 static int check_chainloops(const struct ebt_entries *chain, struct ebt_cl_stack *cl_s,
748 unsigned int udc_cnt, unsigned int hooknr, char *base)
750 int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict;
751 const struct ebt_entry *e = (struct ebt_entry *)chain->data;
752 const struct ebt_entry_target *t;
754 while (pos < nentries || chain_nr != -1) {
755 /* end of udc, go back one 'recursion' step */
756 if (pos == nentries) {
757 /* put back values of the time when this chain was called */
758 e = cl_s[chain_nr].cs.e;
759 if (cl_s[chain_nr].from != -1)
760 nentries =
761 cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries;
762 else
763 nentries = chain->nentries;
764 pos = cl_s[chain_nr].cs.n;
765 /* make sure we won't see a loop that isn't one */
766 cl_s[chain_nr].cs.n = 0;
767 chain_nr = cl_s[chain_nr].from;
768 if (pos == nentries)
769 continue;
771 t = (struct ebt_entry_target *)
772 (((char *)e) + e->target_offset);
773 if (strcmp(t->u.name, EBT_STANDARD_TARGET))
774 goto letscontinue;
775 if (e->target_offset + sizeof(struct ebt_standard_target) >
776 e->next_offset) {
777 BUGPRINT("Standard target size too big\n");
778 return -1;
780 verdict = ((struct ebt_standard_target *)t)->verdict;
781 if (verdict >= 0) { /* jump to another chain */
782 struct ebt_entries *hlp2 =
783 (struct ebt_entries *)(base + verdict);
784 for (i = 0; i < udc_cnt; i++)
785 if (hlp2 == cl_s[i].cs.chaininfo)
786 break;
787 /* bad destination or loop */
788 if (i == udc_cnt) {
789 BUGPRINT("bad destination\n");
790 return -1;
792 if (cl_s[i].cs.n) {
793 BUGPRINT("loop\n");
794 return -1;
796 if (cl_s[i].hookmask & (1 << hooknr))
797 goto letscontinue;
798 /* this can't be 0, so the loop test is correct */
799 cl_s[i].cs.n = pos + 1;
800 pos = 0;
801 cl_s[i].cs.e = ebt_next_entry(e);
802 e = (struct ebt_entry *)(hlp2->data);
803 nentries = hlp2->nentries;
804 cl_s[i].from = chain_nr;
805 chain_nr = i;
806 /* this udc is accessible from the base chain for hooknr */
807 cl_s[i].hookmask |= (1 << hooknr);
808 continue;
810 letscontinue:
811 e = ebt_next_entry(e);
812 pos++;
814 return 0;
817 /* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
818 static int translate_table(struct net *net, const char *name,
819 struct ebt_table_info *newinfo)
821 unsigned int i, j, k, udc_cnt;
822 int ret;
823 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
825 i = 0;
826 while (i < NF_BR_NUMHOOKS && !newinfo->hook_entry[i])
827 i++;
828 if (i == NF_BR_NUMHOOKS) {
829 BUGPRINT("No valid hooks specified\n");
830 return -EINVAL;
832 if (newinfo->hook_entry[i] != (struct ebt_entries *)newinfo->entries) {
833 BUGPRINT("Chains don't start at beginning\n");
834 return -EINVAL;
836 /* make sure chains are ordered after each other in same order
837 as their corresponding hooks */
838 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
839 if (!newinfo->hook_entry[j])
840 continue;
841 if (newinfo->hook_entry[j] <= newinfo->hook_entry[i]) {
842 BUGPRINT("Hook order must be followed\n");
843 return -EINVAL;
845 i = j;
848 /* do some early checkings and initialize some things */
849 i = 0; /* holds the expected nr. of entries for the chain */
850 j = 0; /* holds the up to now counted entries for the chain */
851 k = 0; /* holds the total nr. of entries, should equal
852 newinfo->nentries afterwards */
853 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
854 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
855 ebt_check_entry_size_and_hooks, newinfo,
856 &i, &j, &k, &udc_cnt);
858 if (ret != 0)
859 return ret;
861 if (i != j) {
862 BUGPRINT("nentries does not equal the nr of entries in the "
863 "(last) chain\n");
864 return -EINVAL;
866 if (k != newinfo->nentries) {
867 BUGPRINT("Total nentries is wrong\n");
868 return -EINVAL;
871 /* get the location of the udc, put them in an array
872 while we're at it, allocate the chainstack */
873 if (udc_cnt) {
874 /* this will get free'd in do_replace()/ebt_register_table()
875 if an error occurs */
876 newinfo->chainstack =
877 vmalloc(nr_cpu_ids * sizeof(*(newinfo->chainstack)));
878 if (!newinfo->chainstack)
879 return -ENOMEM;
880 for_each_possible_cpu(i) {
881 newinfo->chainstack[i] =
882 vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0])));
883 if (!newinfo->chainstack[i]) {
884 while (i)
885 vfree(newinfo->chainstack[--i]);
886 vfree(newinfo->chainstack);
887 newinfo->chainstack = NULL;
888 return -ENOMEM;
892 cl_s = vmalloc(udc_cnt * sizeof(*cl_s));
893 if (!cl_s)
894 return -ENOMEM;
895 i = 0; /* the i'th udc */
896 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
897 ebt_get_udc_positions, newinfo, &i, cl_s);
898 /* sanity check */
899 if (i != udc_cnt) {
900 BUGPRINT("i != udc_cnt\n");
901 vfree(cl_s);
902 return -EFAULT;
906 /* Check for loops */
907 for (i = 0; i < NF_BR_NUMHOOKS; i++)
908 if (newinfo->hook_entry[i])
909 if (check_chainloops(newinfo->hook_entry[i],
910 cl_s, udc_cnt, i, newinfo->entries)) {
911 vfree(cl_s);
912 return -EINVAL;
915 /* we now know the following (along with E=mc²):
916 - the nr of entries in each chain is right
917 - the size of the allocated space is right
918 - all valid hooks have a corresponding chain
919 - there are no loops
920 - wrong data can still be on the level of a single entry
921 - could be there are jumps to places that are not the
922 beginning of a chain. This can only occur in chains that
923 are not accessible from any base chains, so we don't care. */
925 /* used to know what we need to clean up if something goes wrong */
926 i = 0;
927 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
928 ebt_check_entry, net, newinfo, name, &i, cl_s, udc_cnt);
929 if (ret != 0) {
930 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
931 ebt_cleanup_entry, net, &i);
933 vfree(cl_s);
934 return ret;
937 /* called under write_lock */
938 static void get_counters(const struct ebt_counter *oldcounters,
939 struct ebt_counter *counters, unsigned int nentries)
941 int i, cpu;
942 struct ebt_counter *counter_base;
944 /* counters of cpu 0 */
945 memcpy(counters, oldcounters,
946 sizeof(struct ebt_counter) * nentries);
948 /* add other counters to those of cpu 0 */
949 for_each_possible_cpu(cpu) {
950 if (cpu == 0)
951 continue;
952 counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
953 for (i = 0; i < nentries; i++) {
954 counters[i].pcnt += counter_base[i].pcnt;
955 counters[i].bcnt += counter_base[i].bcnt;
960 /* replace the table */
961 static int do_replace(struct net *net, const void __user *user,
962 unsigned int len)
964 int ret, i, countersize;
965 struct ebt_table_info *newinfo;
966 struct ebt_replace tmp;
967 struct ebt_table *t;
968 struct ebt_counter *counterstmp = NULL;
969 /* used to be able to unlock earlier */
970 struct ebt_table_info *table;
972 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
973 return -EFAULT;
975 if (len != sizeof(tmp) + tmp.entries_size) {
976 BUGPRINT("Wrong len argument\n");
977 return -EINVAL;
980 if (tmp.entries_size == 0) {
981 BUGPRINT("Entries_size never zero\n");
982 return -EINVAL;
984 /* overflow check */
985 if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
986 SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
987 return -ENOMEM;
988 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
989 return -ENOMEM;
991 countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids;
992 newinfo = vmalloc(sizeof(*newinfo) + countersize);
993 if (!newinfo)
994 return -ENOMEM;
996 if (countersize)
997 memset(newinfo->counters, 0, countersize);
999 newinfo->entries = vmalloc(tmp.entries_size);
1000 if (!newinfo->entries) {
1001 ret = -ENOMEM;
1002 goto free_newinfo;
1004 if (copy_from_user(
1005 newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
1006 BUGPRINT("Couldn't copy entries from userspace\n");
1007 ret = -EFAULT;
1008 goto free_entries;
1011 /* the user wants counters back
1012 the check on the size is done later, when we have the lock */
1013 if (tmp.num_counters) {
1014 counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
1015 if (!counterstmp) {
1016 ret = -ENOMEM;
1017 goto free_entries;
1020 else
1021 counterstmp = NULL;
1023 /* this can get initialized by translate_table() */
1024 newinfo->chainstack = NULL;
1025 ret = ebt_verify_pointers(&tmp, newinfo);
1026 if (ret != 0)
1027 goto free_counterstmp;
1029 ret = translate_table(net, tmp.name, newinfo);
1031 if (ret != 0)
1032 goto free_counterstmp;
1034 t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
1035 if (!t) {
1036 ret = -ENOENT;
1037 goto free_iterate;
1040 /* the table doesn't like it */
1041 if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
1042 goto free_unlock;
1044 if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
1045 BUGPRINT("Wrong nr. of counters requested\n");
1046 ret = -EINVAL;
1047 goto free_unlock;
1050 /* we have the mutex lock, so no danger in reading this pointer */
1051 table = t->private;
1052 /* make sure the table can only be rmmod'ed if it contains no rules */
1053 if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
1054 ret = -ENOENT;
1055 goto free_unlock;
1056 } else if (table->nentries && !newinfo->nentries)
1057 module_put(t->me);
1058 /* we need an atomic snapshot of the counters */
1059 write_lock_bh(&t->lock);
1060 if (tmp.num_counters)
1061 get_counters(t->private->counters, counterstmp,
1062 t->private->nentries);
1064 t->private = newinfo;
1065 write_unlock_bh(&t->lock);
1066 mutex_unlock(&ebt_mutex);
1067 /* so, a user can change the chains while having messed up her counter
1068 allocation. Only reason why this is done is because this way the lock
1069 is held only once, while this doesn't bring the kernel into a
1070 dangerous state. */
1071 if (tmp.num_counters &&
1072 copy_to_user(tmp.counters, counterstmp,
1073 tmp.num_counters * sizeof(struct ebt_counter))) {
1074 BUGPRINT("Couldn't copy counters to userspace\n");
1075 ret = -EFAULT;
1077 else
1078 ret = 0;
1080 /* decrease module count and free resources */
1081 EBT_ENTRY_ITERATE(table->entries, table->entries_size,
1082 ebt_cleanup_entry, net, NULL);
1084 vfree(table->entries);
1085 if (table->chainstack) {
1086 for_each_possible_cpu(i)
1087 vfree(table->chainstack[i]);
1088 vfree(table->chainstack);
1090 vfree(table);
1092 vfree(counterstmp);
1093 return ret;
1095 free_unlock:
1096 mutex_unlock(&ebt_mutex);
1097 free_iterate:
1098 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1099 ebt_cleanup_entry, net, NULL);
1100 free_counterstmp:
1101 vfree(counterstmp);
1102 /* can be initialized in translate_table() */
1103 if (newinfo->chainstack) {
1104 for_each_possible_cpu(i)
1105 vfree(newinfo->chainstack[i]);
1106 vfree(newinfo->chainstack);
1108 free_entries:
1109 vfree(newinfo->entries);
1110 free_newinfo:
1111 vfree(newinfo);
1112 return ret;
1115 struct ebt_table *
1116 ebt_register_table(struct net *net, const struct ebt_table *input_table)
1118 struct ebt_table_info *newinfo;
1119 struct ebt_table *t, *table;
1120 struct ebt_replace_kernel *repl;
1121 int ret, i, countersize;
1122 void *p;
1124 if (input_table == NULL || (repl = input_table->table) == NULL ||
1125 repl->entries == 0 || repl->entries_size == 0 ||
1126 repl->counters != NULL || input_table->private != NULL) {
1127 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1128 return ERR_PTR(-EINVAL);
1131 /* Don't add one table to multiple lists. */
1132 table = kmemdup(input_table, sizeof(struct ebt_table), GFP_KERNEL);
1133 if (!table) {
1134 ret = -ENOMEM;
1135 goto out;
1138 countersize = COUNTER_OFFSET(repl->nentries) * nr_cpu_ids;
1139 newinfo = vmalloc(sizeof(*newinfo) + countersize);
1140 ret = -ENOMEM;
1141 if (!newinfo)
1142 goto free_table;
1144 p = vmalloc(repl->entries_size);
1145 if (!p)
1146 goto free_newinfo;
1148 memcpy(p, repl->entries, repl->entries_size);
1149 newinfo->entries = p;
1151 newinfo->entries_size = repl->entries_size;
1152 newinfo->nentries = repl->nentries;
1154 if (countersize)
1155 memset(newinfo->counters, 0, countersize);
1157 /* fill in newinfo and parse the entries */
1158 newinfo->chainstack = NULL;
1159 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
1160 if ((repl->valid_hooks & (1 << i)) == 0)
1161 newinfo->hook_entry[i] = NULL;
1162 else
1163 newinfo->hook_entry[i] = p +
1164 ((char *)repl->hook_entry[i] - repl->entries);
1166 ret = translate_table(net, repl->name, newinfo);
1167 if (ret != 0) {
1168 BUGPRINT("Translate_table failed\n");
1169 goto free_chainstack;
1172 if (table->check && table->check(newinfo, table->valid_hooks)) {
1173 BUGPRINT("The table doesn't like its own initial data, lol\n");
1174 return ERR_PTR(-EINVAL);
1177 table->private = newinfo;
1178 rwlock_init(&table->lock);
1179 ret = mutex_lock_interruptible(&ebt_mutex);
1180 if (ret != 0)
1181 goto free_chainstack;
1183 list_for_each_entry(t, &net->xt.tables[NFPROTO_BRIDGE], list) {
1184 if (strcmp(t->name, table->name) == 0) {
1185 ret = -EEXIST;
1186 BUGPRINT("Table name already exists\n");
1187 goto free_unlock;
1191 /* Hold a reference count if the chains aren't empty */
1192 if (newinfo->nentries && !try_module_get(table->me)) {
1193 ret = -ENOENT;
1194 goto free_unlock;
1196 list_add(&table->list, &net->xt.tables[NFPROTO_BRIDGE]);
1197 mutex_unlock(&ebt_mutex);
1198 return table;
1199 free_unlock:
1200 mutex_unlock(&ebt_mutex);
1201 free_chainstack:
1202 if (newinfo->chainstack) {
1203 for_each_possible_cpu(i)
1204 vfree(newinfo->chainstack[i]);
1205 vfree(newinfo->chainstack);
1207 vfree(newinfo->entries);
1208 free_newinfo:
1209 vfree(newinfo);
1210 free_table:
1211 kfree(table);
1212 out:
1213 return ERR_PTR(ret);
1216 void ebt_unregister_table(struct net *net, struct ebt_table *table)
1218 int i;
1220 if (!table) {
1221 BUGPRINT("Request to unregister NULL table!!!\n");
1222 return;
1224 mutex_lock(&ebt_mutex);
1225 list_del(&table->list);
1226 mutex_unlock(&ebt_mutex);
1227 EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
1228 ebt_cleanup_entry, net, NULL);
1229 if (table->private->nentries)
1230 module_put(table->me);
1231 vfree(table->private->entries);
1232 if (table->private->chainstack) {
1233 for_each_possible_cpu(i)
1234 vfree(table->private->chainstack[i]);
1235 vfree(table->private->chainstack);
1237 vfree(table->private);
1238 kfree(table);
1241 /* userspace just supplied us with counters */
1242 static int update_counters(struct net *net, const void __user *user,
1243 unsigned int len)
1245 int i, ret;
1246 struct ebt_counter *tmp;
1247 struct ebt_replace hlp;
1248 struct ebt_table *t;
1250 if (copy_from_user(&hlp, user, sizeof(hlp)))
1251 return -EFAULT;
1253 if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
1254 return -EINVAL;
1255 if (hlp.num_counters == 0)
1256 return -EINVAL;
1258 if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
1259 MEMPRINT("Update_counters && nomemory\n");
1260 return -ENOMEM;
1263 t = find_table_lock(net, hlp.name, &ret, &ebt_mutex);
1264 if (!t)
1265 goto free_tmp;
1267 if (hlp.num_counters != t->private->nentries) {
1268 BUGPRINT("Wrong nr of counters\n");
1269 ret = -EINVAL;
1270 goto unlock_mutex;
1273 if ( copy_from_user(tmp, hlp.counters,
1274 hlp.num_counters * sizeof(struct ebt_counter)) ) {
1275 BUGPRINT("Updata_counters && !cfu\n");
1276 ret = -EFAULT;
1277 goto unlock_mutex;
1280 /* we want an atomic add of the counters */
1281 write_lock_bh(&t->lock);
1283 /* we add to the counters of the first cpu */
1284 for (i = 0; i < hlp.num_counters; i++) {
1285 t->private->counters[i].pcnt += tmp[i].pcnt;
1286 t->private->counters[i].bcnt += tmp[i].bcnt;
1289 write_unlock_bh(&t->lock);
1290 ret = 0;
1291 unlock_mutex:
1292 mutex_unlock(&ebt_mutex);
1293 free_tmp:
1294 vfree(tmp);
1295 return ret;
1298 static inline int ebt_make_matchname(const struct ebt_entry_match *m,
1299 const char *base, char __user *ubase)
1301 char __user *hlp = ubase + ((char *)m - base);
1302 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
1303 return -EFAULT;
1304 return 0;
1307 static inline int ebt_make_watchername(const struct ebt_entry_watcher *w,
1308 const char *base, char __user *ubase)
1310 char __user *hlp = ubase + ((char *)w - base);
1311 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
1312 return -EFAULT;
1313 return 0;
1316 static inline int
1317 ebt_make_names(struct ebt_entry *e, const char *base, char __user *ubase)
1319 int ret;
1320 char __user *hlp;
1321 const struct ebt_entry_target *t;
1323 if (e->bitmask == 0)
1324 return 0;
1326 hlp = ubase + (((char *)e + e->target_offset) - base);
1327 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
1329 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
1330 if (ret != 0)
1331 return ret;
1332 ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
1333 if (ret != 0)
1334 return ret;
1335 if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN))
1336 return -EFAULT;
1337 return 0;
1340 /* called with ebt_mutex locked */
1341 static int copy_everything_to_user(struct ebt_table *t, void __user *user,
1342 const int *len, int cmd)
1344 struct ebt_replace tmp;
1345 struct ebt_counter *counterstmp;
1346 const struct ebt_counter *oldcounters;
1347 unsigned int entries_size, nentries;
1348 char *entries;
1350 if (cmd == EBT_SO_GET_ENTRIES) {
1351 entries_size = t->private->entries_size;
1352 nentries = t->private->nentries;
1353 entries = t->private->entries;
1354 oldcounters = t->private->counters;
1355 } else {
1356 entries_size = t->table->entries_size;
1357 nentries = t->table->nentries;
1358 entries = t->table->entries;
1359 oldcounters = t->table->counters;
1362 if (copy_from_user(&tmp, user, sizeof(tmp))) {
1363 BUGPRINT("Cfu didn't work\n");
1364 return -EFAULT;
1367 if (*len != sizeof(struct ebt_replace) + entries_size +
1368 (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
1369 BUGPRINT("Wrong size\n");
1370 return -EINVAL;
1373 if (tmp.nentries != nentries) {
1374 BUGPRINT("Nentries wrong\n");
1375 return -EINVAL;
1378 if (tmp.entries_size != entries_size) {
1379 BUGPRINT("Wrong size\n");
1380 return -EINVAL;
1383 /* userspace might not need the counters */
1384 if (tmp.num_counters) {
1385 if (tmp.num_counters != nentries) {
1386 BUGPRINT("Num_counters wrong\n");
1387 return -EINVAL;
1389 counterstmp = vmalloc(nentries * sizeof(*counterstmp));
1390 if (!counterstmp) {
1391 MEMPRINT("Couldn't copy counters, out of memory\n");
1392 return -ENOMEM;
1394 write_lock_bh(&t->lock);
1395 get_counters(oldcounters, counterstmp, nentries);
1396 write_unlock_bh(&t->lock);
1398 if (copy_to_user(tmp.counters, counterstmp,
1399 nentries * sizeof(struct ebt_counter))) {
1400 BUGPRINT("Couldn't copy counters to userspace\n");
1401 vfree(counterstmp);
1402 return -EFAULT;
1404 vfree(counterstmp);
1407 if (copy_to_user(tmp.entries, entries, entries_size)) {
1408 BUGPRINT("Couldn't copy entries to userspace\n");
1409 return -EFAULT;
1411 /* set the match/watcher/target names right */
1412 return EBT_ENTRY_ITERATE(entries, entries_size,
1413 ebt_make_names, entries, tmp.entries);
1416 static int do_ebt_set_ctl(struct sock *sk,
1417 int cmd, void __user *user, unsigned int len)
1419 int ret;
1421 if (!capable(CAP_NET_ADMIN))
1422 return -EPERM;
1424 switch(cmd) {
1425 case EBT_SO_SET_ENTRIES:
1426 ret = do_replace(sock_net(sk), user, len);
1427 break;
1428 case EBT_SO_SET_COUNTERS:
1429 ret = update_counters(sock_net(sk), user, len);
1430 break;
1431 default:
1432 ret = -EINVAL;
1434 return ret;
1437 static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1439 int ret;
1440 struct ebt_replace tmp;
1441 struct ebt_table *t;
1443 if (!capable(CAP_NET_ADMIN))
1444 return -EPERM;
1446 if (copy_from_user(&tmp, user, sizeof(tmp)))
1447 return -EFAULT;
1449 t = find_table_lock(sock_net(sk), tmp.name, &ret, &ebt_mutex);
1450 if (!t)
1451 return ret;
1453 switch(cmd) {
1454 case EBT_SO_GET_INFO:
1455 case EBT_SO_GET_INIT_INFO:
1456 if (*len != sizeof(struct ebt_replace)){
1457 ret = -EINVAL;
1458 mutex_unlock(&ebt_mutex);
1459 break;
1461 if (cmd == EBT_SO_GET_INFO) {
1462 tmp.nentries = t->private->nentries;
1463 tmp.entries_size = t->private->entries_size;
1464 tmp.valid_hooks = t->valid_hooks;
1465 } else {
1466 tmp.nentries = t->table->nentries;
1467 tmp.entries_size = t->table->entries_size;
1468 tmp.valid_hooks = t->table->valid_hooks;
1470 mutex_unlock(&ebt_mutex);
1471 if (copy_to_user(user, &tmp, *len) != 0){
1472 BUGPRINT("c2u Didn't work\n");
1473 ret = -EFAULT;
1474 break;
1476 ret = 0;
1477 break;
1479 case EBT_SO_GET_ENTRIES:
1480 case EBT_SO_GET_INIT_ENTRIES:
1481 ret = copy_everything_to_user(t, user, len, cmd);
1482 mutex_unlock(&ebt_mutex);
1483 break;
1485 default:
1486 mutex_unlock(&ebt_mutex);
1487 ret = -EINVAL;
1490 return ret;
1493 static struct nf_sockopt_ops ebt_sockopts =
1495 .pf = PF_INET,
1496 .set_optmin = EBT_BASE_CTL,
1497 .set_optmax = EBT_SO_SET_MAX + 1,
1498 .set = do_ebt_set_ctl,
1499 .get_optmin = EBT_BASE_CTL,
1500 .get_optmax = EBT_SO_GET_MAX + 1,
1501 .get = do_ebt_get_ctl,
1502 .owner = THIS_MODULE,
1505 static int __init ebtables_init(void)
1507 int ret;
1509 ret = xt_register_target(&ebt_standard_target);
1510 if (ret < 0)
1511 return ret;
1512 ret = nf_register_sockopt(&ebt_sockopts);
1513 if (ret < 0) {
1514 xt_unregister_target(&ebt_standard_target);
1515 return ret;
1518 printk(KERN_INFO "Ebtables v2.0 registered\n");
1519 return 0;
1522 static void __exit ebtables_fini(void)
1524 nf_unregister_sockopt(&ebt_sockopts);
1525 xt_unregister_target(&ebt_standard_target);
1526 printk(KERN_INFO "Ebtables v2.0 unregistered\n");
1529 EXPORT_SYMBOL(ebt_register_table);
1530 EXPORT_SYMBOL(ebt_unregister_table);
1531 EXPORT_SYMBOL(ebt_do_table);
1532 module_init(ebtables_init);
1533 module_exit(ebtables_fini);
1534 MODULE_LICENSE("GPL");