blob: c4540144f0f4384356a6ce72b6dd01bddcf7a83f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * ebtables
3 *
4 * Author:
5 * Bart De Schuymer <bdschuym@pandora.be>
6 *
7 * ebtables.c,v 2.0, July, 2002
8 *
9 * This code is stongly inspired on the iptables code which is
10 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
11 *
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.
16 */
17
18/* used for print_string */
19#include <linux/sched.h>
20#include <linux/tty.h>
21
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"
32
33/* list_named_find */
34#define ASSERT_READ_LOCK(x)
35#define ASSERT_WRITE_LOCK(x)
36#include <linux/netfilter_ipv4/listhelp.h>
37
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
43 */
44static void print_string(char *str)
45{
46 struct tty_struct *my_tty;
47
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);
53 }
54}
55
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...) */
65
66
67
68/*
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
73 */
74
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))
80
81
82
83static DECLARE_MUTEX(ebt_mutex);
84static LIST_HEAD(ebt_tables);
85static LIST_HEAD(ebt_targets);
86static LIST_HEAD(ebt_matches);
87static LIST_HEAD(ebt_watchers);
88
89static struct ebt_target ebt_standard_target =
90{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL};
91
92static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
93 const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in,
94 const struct net_device *out)
95{
96 w->u.watcher->watcher(skb, hooknr, in, out, w->data,
97 w->watcher_size);
98 /* watchers don't give a verdict */
99 return 0;
100}
101
102static 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)
105{
106 return m->u.match->match(skb, in, out, m->data,
107 m->match_size);
108}
109
110static inline int ebt_dev_check(char *entry, const struct net_device *device)
111{
112 int i = 0;
113 char *devname = device->name;
114
115 if (*entry == '\0')
116 return 0;
117 if (!device)
118 return 1;
119 /* 1 is the wildcard token */
120 while (entry[i] != '\0' && entry[i] != 1 && entry[i] == devname[i])
121 i++;
122 return (devname[i] != entry[i] && entry[i] != 1);
123}
124
125#define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg))
126/* process standard matches */
127static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
128 const struct net_device *in, const struct net_device *out)
129{
130 int verdict, i;
131
132 if (e->bitmask & EBT_802_3) {
133 if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO))
134 return 1;
135 } else if (!(e->bitmask & EBT_NOPROTO) &&
136 FWINV2(e->ethproto != h->h_proto, EBT_IPROTO))
137 return 1;
138
139 if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN))
140 return 1;
141 if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
142 return 1;
143 if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check(
144 e->logical_in, in->br_port->br->dev), EBT_ILOGICALIN))
145 return 1;
146 if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check(
147 e->logical_out, out->br_port->br->dev), EBT_ILOGICALOUT))
148 return 1;
149
150 if (e->bitmask & EBT_SOURCEMAC) {
151 verdict = 0;
152 for (i = 0; i < 6; i++)
153 verdict |= (h->h_source[i] ^ e->sourcemac[i]) &
154 e->sourcemsk[i];
155 if (FWINV2(verdict != 0, EBT_ISOURCE) )
156 return 1;
157 }
158 if (e->bitmask & EBT_DESTMAC) {
159 verdict = 0;
160 for (i = 0; i < 6; i++)
161 verdict |= (h->h_dest[i] ^ e->destmac[i]) &
162 e->destmsk[i];
163 if (FWINV2(verdict != 0, EBT_IDEST) )
164 return 1;
165 }
166 return 0;
167}
168
169/* Do some firewalling */
170unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
171 const struct net_device *in, const struct net_device *out,
172 struct ebt_table *table)
173{
174 int i, nentries;
175 struct ebt_entry *point;
176 struct ebt_counter *counter_base, *cb_base;
177 struct ebt_entry_target *t;
178 int verdict, sp = 0;
179 struct ebt_chainstack *cs;
180 struct ebt_entries *chaininfo;
181 char *base;
182 struct ebt_table_info *private;
183
184 read_lock_bh(&table->lock);
185 private = table->private;
186 cb_base = COUNTER_BASE(private->counters, private->nentries,
187 smp_processor_id());
188 if (private->chainstack)
189 cs = private->chainstack[smp_processor_id()];
190 else
191 cs = NULL;
192 chaininfo = private->hook_entry[hook];
193 nentries = private->hook_entry[hook]->nentries;
194 point = (struct ebt_entry *)(private->hook_entry[hook]->data);
195 counter_base = cb_base + private->hook_entry[hook]->counter_offset;
196 /* base for chain jumps */
197 base = private->entries;
198 i = 0;
199 while (i < nentries) {
200 if (ebt_basic_match(point, eth_hdr(*pskb), in, out))
201 goto letscontinue;
202
203 if (EBT_MATCH_ITERATE(point, ebt_do_match, *pskb, in, out) != 0)
204 goto letscontinue;
205
206 /* increase counter */
207 (*(counter_base + i)).pcnt++;
208 (*(counter_base + i)).bcnt+=(**pskb).len;
209
210 /* these should only watch: not modify, nor tell us
211 what to do with the packet */
212 EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, hook, in,
213 out);
214
215 t = (struct ebt_entry_target *)
216 (((char *)point) + point->target_offset);
217 /* standard target */
218 if (!t->u.target->target)
219 verdict = ((struct ebt_standard_target *)t)->verdict;
220 else
221 verdict = t->u.target->target(pskb, hook,
222 in, out, t->data, t->target_size);
223 if (verdict == EBT_ACCEPT) {
224 read_unlock_bh(&table->lock);
225 return NF_ACCEPT;
226 }
227 if (verdict == EBT_DROP) {
228 read_unlock_bh(&table->lock);
229 return NF_DROP;
230 }
231 if (verdict == EBT_RETURN) {
232letsreturn:
233#ifdef CONFIG_NETFILTER_DEBUG
234 if (sp == 0) {
235 BUGPRINT("RETURN on base chain");
236 /* act like this is EBT_CONTINUE */
237 goto letscontinue;
238 }
239#endif
240 sp--;
241 /* put all the local variables right */
242 i = cs[sp].n;
243 chaininfo = cs[sp].chaininfo;
244 nentries = chaininfo->nentries;
245 point = cs[sp].e;
246 counter_base = cb_base +
247 chaininfo->counter_offset;
248 continue;
249 }
250 if (verdict == EBT_CONTINUE)
251 goto letscontinue;
252#ifdef CONFIG_NETFILTER_DEBUG
253 if (verdict < 0) {
254 BUGPRINT("bogus standard verdict\n");
255 read_unlock_bh(&table->lock);
256 return NF_DROP;
257 }
258#endif
259 /* jump to a udc */
260 cs[sp].n = i + 1;
261 cs[sp].chaininfo = chaininfo;
262 cs[sp].e = (struct ebt_entry *)
263 (((char *)point) + point->next_offset);
264 i = 0;
265 chaininfo = (struct ebt_entries *) (base + verdict);
266#ifdef CONFIG_NETFILTER_DEBUG
267 if (chaininfo->distinguisher) {
268 BUGPRINT("jump to non-chain\n");
269 read_unlock_bh(&table->lock);
270 return NF_DROP;
271 }
272#endif
273 nentries = chaininfo->nentries;
274 point = (struct ebt_entry *)chaininfo->data;
275 counter_base = cb_base + chaininfo->counter_offset;
276 sp++;
277 continue;
278letscontinue:
279 point = (struct ebt_entry *)
280 (((char *)point) + point->next_offset);
281 i++;
282 }
283
284 /* I actually like this :) */
285 if (chaininfo->policy == EBT_RETURN)
286 goto letsreturn;
287 if (chaininfo->policy == EBT_ACCEPT) {
288 read_unlock_bh(&table->lock);
289 return NF_ACCEPT;
290 }
291 read_unlock_bh(&table->lock);
292 return NF_DROP;
293}
294
295/* If it succeeds, returns element and locks mutex */
296static inline void *
297find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
298 struct semaphore *mutex)
299{
300 void *ret;
301
302 *error = down_interruptible(mutex);
303 if (*error != 0)
304 return NULL;
305
306 ret = list_named_find(head, name);
307 if (!ret) {
308 *error = -ENOENT;
309 up(mutex);
310 }
311 return ret;
312}
313
314#ifndef CONFIG_KMOD
315#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
316#else
317static void *
318find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
319 int *error, struct semaphore *mutex)
320{
321 void *ret;
322
323 ret = find_inlist_lock_noload(head, name, error, mutex);
324 if (!ret) {
325 request_module("%s%s", prefix, name);
326 ret = find_inlist_lock_noload(head, name, error, mutex);
327 }
328 return ret;
329}
330#endif
331
332static inline struct ebt_table *
333find_table_lock(const char *name, int *error, struct semaphore *mutex)
334{
335 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
336}
337
338static inline struct ebt_match *
339find_match_lock(const char *name, int *error, struct semaphore *mutex)
340{
341 return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
342}
343
344static inline struct ebt_watcher *
345find_watcher_lock(const char *name, int *error, struct semaphore *mutex)
346{
347 return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
348}
349
350static inline struct ebt_target *
351find_target_lock(const char *name, int *error, struct semaphore *mutex)
352{
353 return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
354}
355
356static inline int
357ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
358 const char *name, unsigned int hookmask, unsigned int *cnt)
359{
360 struct ebt_match *match;
361 int ret;
362
363 if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) >
364 ((char *)e) + e->watchers_offset)
365 return -EINVAL;
366 match = find_match_lock(m->u.name, &ret, &ebt_mutex);
367 if (!match)
368 return ret;
369 m->u.match = match;
370 if (!try_module_get(match->me)) {
371 up(&ebt_mutex);
372 return -ENOENT;
373 }
374 up(&ebt_mutex);
375 if (match->check &&
376 match->check(name, hookmask, e, m->data, m->match_size) != 0) {
377 BUGPRINT("match->check failed\n");
378 module_put(match->me);
379 return -EINVAL;
380 }
381 (*cnt)++;
382 return 0;
383}
384
385static inline int
386ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
387 const char *name, unsigned int hookmask, unsigned int *cnt)
388{
389 struct ebt_watcher *watcher;
390 int ret;
391
392 if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) >
393 ((char *)e) + e->target_offset)
394 return -EINVAL;
395 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
396 if (!watcher)
397 return ret;
398 w->u.watcher = watcher;
399 if (!try_module_get(watcher->me)) {
400 up(&ebt_mutex);
401 return -ENOENT;
402 }
403 up(&ebt_mutex);
404 if (watcher->check &&
405 watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) {
406 BUGPRINT("watcher->check failed\n");
407 module_put(watcher->me);
408 return -EINVAL;
409 }
410 (*cnt)++;
411 return 0;
412}
413
414/*
415 * this one is very careful, as it is the first function
416 * to parse the userspace data
417 */
418static inline int
419ebt_check_entry_size_and_hooks(struct ebt_entry *e,
420 struct ebt_table_info *newinfo, char *base, char *limit,
421 struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt,
422 unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks)
423{
424 int i;
425
426 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
427 if ((valid_hooks & (1 << i)) == 0)
428 continue;
429 if ( (char *)hook_entries[i] - base ==
430 (char *)e - newinfo->entries)
431 break;
432 }
433 /* beginning of a new chain
434 if i == NF_BR_NUMHOOKS it must be a user defined chain */
435 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
436 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) {
437 /* we make userspace set this right,
438 so there is no misunderstanding */
439 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
440 "in distinguisher\n");
441 return -EINVAL;
442 }
443 /* this checks if the previous chain has as many entries
444 as it said it has */
445 if (*n != *cnt) {
446 BUGPRINT("nentries does not equal the nr of entries "
447 "in the chain\n");
448 return -EINVAL;
449 }
450 /* before we look at the struct, be sure it is not too big */
451 if ((char *)hook_entries[i] + sizeof(struct ebt_entries)
452 > limit) {
453 BUGPRINT("entries_size too small\n");
454 return -EINVAL;
455 }
456 if (((struct ebt_entries *)e)->policy != EBT_DROP &&
457 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
458 /* only RETURN from udc */
459 if (i != NF_BR_NUMHOOKS ||
460 ((struct ebt_entries *)e)->policy != EBT_RETURN) {
461 BUGPRINT("bad policy\n");
462 return -EINVAL;
463 }
464 }
465 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
466 (*udc_cnt)++;
467 else
468 newinfo->hook_entry[i] = (struct ebt_entries *)e;
469 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
470 BUGPRINT("counter_offset != totalcnt");
471 return -EINVAL;
472 }
473 *n = ((struct ebt_entries *)e)->nentries;
474 *cnt = 0;
475 return 0;
476 }
477 /* a plain old entry, heh */
478 if (sizeof(struct ebt_entry) > e->watchers_offset ||
479 e->watchers_offset > e->target_offset ||
480 e->target_offset >= e->next_offset) {
481 BUGPRINT("entry offsets not in right order\n");
482 return -EINVAL;
483 }
484 /* this is not checked anywhere else */
485 if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) {
486 BUGPRINT("target size too small\n");
487 return -EINVAL;
488 }
489
490 (*cnt)++;
491 (*totalcnt)++;
492 return 0;
493}
494
495struct ebt_cl_stack
496{
497 struct ebt_chainstack cs;
498 int from;
499 unsigned int hookmask;
500};
501
502/*
503 * we need these positions to check that the jumps to a different part of the
504 * entries is a jump to the beginning of a new chain.
505 */
506static inline int
507ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
508 struct ebt_entries **hook_entries, unsigned int *n, unsigned int valid_hooks,
509 struct ebt_cl_stack *udc)
510{
511 int i;
512
513 /* we're only interested in chain starts */
514 if (e->bitmask & EBT_ENTRY_OR_ENTRIES)
515 return 0;
516 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
517 if ((valid_hooks & (1 << i)) == 0)
518 continue;
519 if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
520 break;
521 }
522 /* only care about udc */
523 if (i != NF_BR_NUMHOOKS)
524 return 0;
525
526 udc[*n].cs.chaininfo = (struct ebt_entries *)e;
527 /* these initialisations are depended on later in check_chainloops() */
528 udc[*n].cs.n = 0;
529 udc[*n].hookmask = 0;
530
531 (*n)++;
532 return 0;
533}
534
535static inline int
536ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
537{
538 if (i && (*i)-- == 0)
539 return 1;
540 if (m->u.match->destroy)
541 m->u.match->destroy(m->data, m->match_size);
542 module_put(m->u.match->me);
543
544 return 0;
545}
546
547static inline int
548ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
549{
550 if (i && (*i)-- == 0)
551 return 1;
552 if (w->u.watcher->destroy)
553 w->u.watcher->destroy(w->data, w->watcher_size);
554 module_put(w->u.watcher->me);
555
556 return 0;
557}
558
559static inline int
560ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
561{
562 struct ebt_entry_target *t;
563
564 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
565 return 0;
566 /* we're done */
567 if (cnt && (*cnt)-- == 0)
568 return 1;
569 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
570 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
571 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
572 if (t->u.target->destroy)
573 t->u.target->destroy(t->data, t->target_size);
574 module_put(t->u.target->me);
575
576 return 0;
577}
578
579static inline int
580ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
581 const char *name, unsigned int *cnt, unsigned int valid_hooks,
582 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
583{
584 struct ebt_entry_target *t;
585 struct ebt_target *target;
586 unsigned int i, j, hook = 0, hookmask = 0;
587 int ret;
588
589 /* don't mess with the struct ebt_entries */
590 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
591 return 0;
592
593 if (e->bitmask & ~EBT_F_MASK) {
594 BUGPRINT("Unknown flag for bitmask\n");
595 return -EINVAL;
596 }
597 if (e->invflags & ~EBT_INV_MASK) {
598 BUGPRINT("Unknown flag for inv bitmask\n");
599 return -EINVAL;
600 }
601 if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) {
602 BUGPRINT("NOPROTO & 802_3 not allowed\n");
603 return -EINVAL;
604 }
605 /* what hook do we belong to? */
606 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
607 if ((valid_hooks & (1 << i)) == 0)
608 continue;
609 if ((char *)newinfo->hook_entry[i] < (char *)e)
610 hook = i;
611 else
612 break;
613 }
614 /* (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on
615 a base chain */
616 if (i < NF_BR_NUMHOOKS)
617 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
618 else {
619 for (i = 0; i < udc_cnt; i++)
620 if ((char *)(cl_s[i].cs.chaininfo) > (char *)e)
621 break;
622 if (i == 0)
623 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
624 else
625 hookmask = cl_s[i - 1].hookmask;
626 }
627 i = 0;
628 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
629 if (ret != 0)
630 goto cleanup_matches;
631 j = 0;
632 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
633 if (ret != 0)
634 goto cleanup_watchers;
635 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
636 target = find_target_lock(t->u.name, &ret, &ebt_mutex);
637 if (!target)
638 goto cleanup_watchers;
639 if (!try_module_get(target->me)) {
640 up(&ebt_mutex);
641 ret = -ENOENT;
642 goto cleanup_watchers;
643 }
644 up(&ebt_mutex);
645
646 t->u.target = target;
647 if (t->u.target == &ebt_standard_target) {
648 if (e->target_offset + sizeof(struct ebt_standard_target) >
649 e->next_offset) {
650 BUGPRINT("Standard target size too big\n");
651 ret = -EFAULT;
652 goto cleanup_watchers;
653 }
654 if (((struct ebt_standard_target *)t)->verdict <
655 -NUM_STANDARD_TARGETS) {
656 BUGPRINT("Invalid standard target\n");
657 ret = -EFAULT;
658 goto cleanup_watchers;
659 }
660 } else if ((e->target_offset + t->target_size +
661 sizeof(struct ebt_entry_target) > e->next_offset) ||
662 (t->u.target->check &&
663 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
664 module_put(t->u.target->me);
665 ret = -EFAULT;
666 goto cleanup_watchers;
667 }
668 (*cnt)++;
669 return 0;
670cleanup_watchers:
671 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j);
672cleanup_matches:
673 EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i);
674 return ret;
675}
676
677/*
678 * checks for loops and sets the hook mask for udc
679 * the hook mask for udc tells us from which base chains the udc can be
680 * accessed. This mask is a parameter to the check() functions of the extensions
681 */
682static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s,
683 unsigned int udc_cnt, unsigned int hooknr, char *base)
684{
685 int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict;
686 struct ebt_entry *e = (struct ebt_entry *)chain->data;
687 struct ebt_entry_target *t;
688
689 while (pos < nentries || chain_nr != -1) {
690 /* end of udc, go back one 'recursion' step */
691 if (pos == nentries) {
692 /* put back values of the time when this chain was called */
693 e = cl_s[chain_nr].cs.e;
694 if (cl_s[chain_nr].from != -1)
695 nentries =
696 cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries;
697 else
698 nentries = chain->nentries;
699 pos = cl_s[chain_nr].cs.n;
700 /* make sure we won't see a loop that isn't one */
701 cl_s[chain_nr].cs.n = 0;
702 chain_nr = cl_s[chain_nr].from;
703 if (pos == nentries)
704 continue;
705 }
706 t = (struct ebt_entry_target *)
707 (((char *)e) + e->target_offset);
708 if (strcmp(t->u.name, EBT_STANDARD_TARGET))
709 goto letscontinue;
710 if (e->target_offset + sizeof(struct ebt_standard_target) >
711 e->next_offset) {
712 BUGPRINT("Standard target size too big\n");
713 return -1;
714 }
715 verdict = ((struct ebt_standard_target *)t)->verdict;
716 if (verdict >= 0) { /* jump to another chain */
717 struct ebt_entries *hlp2 =
718 (struct ebt_entries *)(base + verdict);
719 for (i = 0; i < udc_cnt; i++)
720 if (hlp2 == cl_s[i].cs.chaininfo)
721 break;
722 /* bad destination or loop */
723 if (i == udc_cnt) {
724 BUGPRINT("bad destination\n");
725 return -1;
726 }
727 if (cl_s[i].cs.n) {
728 BUGPRINT("loop\n");
729 return -1;
730 }
731 /* this can't be 0, so the above test is correct */
732 cl_s[i].cs.n = pos + 1;
733 pos = 0;
734 cl_s[i].cs.e = ((void *)e + e->next_offset);
735 e = (struct ebt_entry *)(hlp2->data);
736 nentries = hlp2->nentries;
737 cl_s[i].from = chain_nr;
738 chain_nr = i;
739 /* this udc is accessible from the base chain for hooknr */
740 cl_s[i].hookmask |= (1 << hooknr);
741 continue;
742 }
743letscontinue:
744 e = (void *)e + e->next_offset;
745 pos++;
746 }
747 return 0;
748}
749
750/* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
751static int translate_table(struct ebt_replace *repl,
752 struct ebt_table_info *newinfo)
753{
754 unsigned int i, j, k, udc_cnt;
755 int ret;
756 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
757
758 i = 0;
759 while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i)))
760 i++;
761 if (i == NF_BR_NUMHOOKS) {
762 BUGPRINT("No valid hooks specified\n");
763 return -EINVAL;
764 }
765 if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) {
766 BUGPRINT("Chains don't start at beginning\n");
767 return -EINVAL;
768 }
769 /* make sure chains are ordered after each other in same order
770 as their corresponding hooks */
771 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
772 if (!(repl->valid_hooks & (1 << j)))
773 continue;
774 if ( repl->hook_entry[j] <= repl->hook_entry[i] ) {
775 BUGPRINT("Hook order must be followed\n");
776 return -EINVAL;
777 }
778 i = j;
779 }
780
781 for (i = 0; i < NF_BR_NUMHOOKS; i++)
782 newinfo->hook_entry[i] = NULL;
783
784 newinfo->entries_size = repl->entries_size;
785 newinfo->nentries = repl->nentries;
786
787 /* do some early checkings and initialize some things */
788 i = 0; /* holds the expected nr. of entries for the chain */
789 j = 0; /* holds the up to now counted entries for the chain */
790 k = 0; /* holds the total nr. of entries, should equal
791 newinfo->nentries afterwards */
792 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
793 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
794 ebt_check_entry_size_and_hooks, newinfo, repl->entries,
795 repl->entries + repl->entries_size, repl->hook_entry, &i, &j, &k,
796 &udc_cnt, repl->valid_hooks);
797
798 if (ret != 0)
799 return ret;
800
801 if (i != j) {
802 BUGPRINT("nentries does not equal the nr of entries in the "
803 "(last) chain\n");
804 return -EINVAL;
805 }
806 if (k != newinfo->nentries) {
807 BUGPRINT("Total nentries is wrong\n");
808 return -EINVAL;
809 }
810
811 /* check if all valid hooks have a chain */
812 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
813 if (newinfo->hook_entry[i] == NULL &&
814 (repl->valid_hooks & (1 << i))) {
815 BUGPRINT("Valid hook without chain\n");
816 return -EINVAL;
817 }
818 }
819
820 /* get the location of the udc, put them in an array
821 while we're at it, allocate the chainstack */
822 if (udc_cnt) {
823 /* this will get free'd in do_replace()/ebt_register_table()
824 if an error occurs */
825 newinfo->chainstack = (struct ebt_chainstack **)
826 vmalloc(num_possible_cpus() * sizeof(struct ebt_chainstack));
827 if (!newinfo->chainstack)
828 return -ENOMEM;
829 for (i = 0; i < num_possible_cpus(); i++) {
830 newinfo->chainstack[i] =
831 vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
832 if (!newinfo->chainstack[i]) {
833 while (i)
834 vfree(newinfo->chainstack[--i]);
835 vfree(newinfo->chainstack);
836 newinfo->chainstack = NULL;
837 return -ENOMEM;
838 }
839 }
840
841 cl_s = (struct ebt_cl_stack *)
842 vmalloc(udc_cnt * sizeof(struct ebt_cl_stack));
843 if (!cl_s)
844 return -ENOMEM;
845 i = 0; /* the i'th udc */
846 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
847 ebt_get_udc_positions, newinfo, repl->hook_entry, &i,
848 repl->valid_hooks, cl_s);
849 /* sanity check */
850 if (i != udc_cnt) {
851 BUGPRINT("i != udc_cnt\n");
852 vfree(cl_s);
853 return -EFAULT;
854 }
855 }
856
857 /* Check for loops */
858 for (i = 0; i < NF_BR_NUMHOOKS; i++)
859 if (repl->valid_hooks & (1 << i))
860 if (check_chainloops(newinfo->hook_entry[i],
861 cl_s, udc_cnt, i, newinfo->entries)) {
James Lamanna68d31872005-06-22 22:12:57 -0700862 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 return -EINVAL;
864 }
865
866 /* we now know the following (along with E=mc²):
867 - the nr of entries in each chain is right
868 - the size of the allocated space is right
869 - all valid hooks have a corresponding chain
870 - there are no loops
871 - wrong data can still be on the level of a single entry
872 - could be there are jumps to places that are not the
873 beginning of a chain. This can only occur in chains that
874 are not accessible from any base chains, so we don't care. */
875
876 /* used to know what we need to clean up if something goes wrong */
877 i = 0;
878 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
879 ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks,
880 cl_s, udc_cnt);
881 if (ret != 0) {
882 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
883 ebt_cleanup_entry, &i);
884 }
James Lamanna68d31872005-06-22 22:12:57 -0700885 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 return ret;
887}
888
889/* called under write_lock */
890static void get_counters(struct ebt_counter *oldcounters,
891 struct ebt_counter *counters, unsigned int nentries)
892{
893 int i, cpu;
894 struct ebt_counter *counter_base;
895
896 /* counters of cpu 0 */
897 memcpy(counters, oldcounters,
898 sizeof(struct ebt_counter) * nentries);
899 /* add other counters to those of cpu 0 */
900 for (cpu = 1; cpu < num_possible_cpus(); cpu++) {
901 counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
902 for (i = 0; i < nentries; i++) {
903 counters[i].pcnt += counter_base[i].pcnt;
904 counters[i].bcnt += counter_base[i].bcnt;
905 }
906 }
907}
908
909/* replace the table */
910static int do_replace(void __user *user, unsigned int len)
911{
912 int ret, i, countersize;
913 struct ebt_table_info *newinfo;
914 struct ebt_replace tmp;
915 struct ebt_table *t;
916 struct ebt_counter *counterstmp = NULL;
917 /* used to be able to unlock earlier */
918 struct ebt_table_info *table;
919
920 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
921 return -EFAULT;
922
923 if (len != sizeof(tmp) + tmp.entries_size) {
924 BUGPRINT("Wrong len argument\n");
925 return -EINVAL;
926 }
927
928 if (tmp.entries_size == 0) {
929 BUGPRINT("Entries_size never zero\n");
930 return -EINVAL;
931 }
932 countersize = COUNTER_OFFSET(tmp.nentries) * num_possible_cpus();
933 newinfo = (struct ebt_table_info *)
934 vmalloc(sizeof(struct ebt_table_info) + countersize);
935 if (!newinfo)
936 return -ENOMEM;
937
938 if (countersize)
939 memset(newinfo->counters, 0, countersize);
940
941 newinfo->entries = (char *)vmalloc(tmp.entries_size);
942 if (!newinfo->entries) {
943 ret = -ENOMEM;
944 goto free_newinfo;
945 }
946 if (copy_from_user(
947 newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
948 BUGPRINT("Couldn't copy entries from userspace\n");
949 ret = -EFAULT;
950 goto free_entries;
951 }
952
953 /* the user wants counters back
954 the check on the size is done later, when we have the lock */
955 if (tmp.num_counters) {
956 counterstmp = (struct ebt_counter *)
957 vmalloc(tmp.num_counters * sizeof(struct ebt_counter));
958 if (!counterstmp) {
959 ret = -ENOMEM;
960 goto free_entries;
961 }
962 }
963 else
964 counterstmp = NULL;
965
966 /* this can get initialized by translate_table() */
967 newinfo->chainstack = NULL;
968 ret = translate_table(&tmp, newinfo);
969
970 if (ret != 0)
971 goto free_counterstmp;
972
973 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
974 if (!t) {
975 ret = -ENOENT;
976 goto free_iterate;
977 }
978
979 /* the table doesn't like it */
980 if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
981 goto free_unlock;
982
983 if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
984 BUGPRINT("Wrong nr. of counters requested\n");
985 ret = -EINVAL;
986 goto free_unlock;
987 }
988
989 /* we have the mutex lock, so no danger in reading this pointer */
990 table = t->private;
991 /* make sure the table can only be rmmod'ed if it contains no rules */
992 if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
993 ret = -ENOENT;
994 goto free_unlock;
995 } else if (table->nentries && !newinfo->nentries)
996 module_put(t->me);
997 /* we need an atomic snapshot of the counters */
998 write_lock_bh(&t->lock);
999 if (tmp.num_counters)
1000 get_counters(t->private->counters, counterstmp,
1001 t->private->nentries);
1002
1003 t->private = newinfo;
1004 write_unlock_bh(&t->lock);
1005 up(&ebt_mutex);
1006 /* so, a user can change the chains while having messed up her counter
1007 allocation. Only reason why this is done is because this way the lock
1008 is held only once, while this doesn't bring the kernel into a
1009 dangerous state. */
1010 if (tmp.num_counters &&
1011 copy_to_user(tmp.counters, counterstmp,
1012 tmp.num_counters * sizeof(struct ebt_counter))) {
1013 BUGPRINT("Couldn't copy counters to userspace\n");
1014 ret = -EFAULT;
1015 }
1016 else
1017 ret = 0;
1018
1019 /* decrease module count and free resources */
1020 EBT_ENTRY_ITERATE(table->entries, table->entries_size,
1021 ebt_cleanup_entry, NULL);
1022
1023 vfree(table->entries);
1024 if (table->chainstack) {
1025 for (i = 0; i < num_possible_cpus(); i++)
1026 vfree(table->chainstack[i]);
1027 vfree(table->chainstack);
1028 }
1029 vfree(table);
1030
James Lamanna68d31872005-06-22 22:12:57 -07001031 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 return ret;
1033
1034free_unlock:
1035 up(&ebt_mutex);
1036free_iterate:
1037 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1038 ebt_cleanup_entry, NULL);
1039free_counterstmp:
James Lamanna68d31872005-06-22 22:12:57 -07001040 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 /* can be initialized in translate_table() */
1042 if (newinfo->chainstack) {
1043 for (i = 0; i < num_possible_cpus(); i++)
1044 vfree(newinfo->chainstack[i]);
1045 vfree(newinfo->chainstack);
1046 }
1047free_entries:
James Lamanna68d31872005-06-22 22:12:57 -07001048 vfree(newinfo->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049free_newinfo:
James Lamanna68d31872005-06-22 22:12:57 -07001050 vfree(newinfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 return ret;
1052}
1053
1054int ebt_register_target(struct ebt_target *target)
1055{
1056 int ret;
1057
1058 ret = down_interruptible(&ebt_mutex);
1059 if (ret != 0)
1060 return ret;
1061 if (!list_named_insert(&ebt_targets, target)) {
1062 up(&ebt_mutex);
1063 return -EEXIST;
1064 }
1065 up(&ebt_mutex);
1066
1067 return 0;
1068}
1069
1070void ebt_unregister_target(struct ebt_target *target)
1071{
1072 down(&ebt_mutex);
1073 LIST_DELETE(&ebt_targets, target);
1074 up(&ebt_mutex);
1075}
1076
1077int ebt_register_match(struct ebt_match *match)
1078{
1079 int ret;
1080
1081 ret = down_interruptible(&ebt_mutex);
1082 if (ret != 0)
1083 return ret;
1084 if (!list_named_insert(&ebt_matches, match)) {
1085 up(&ebt_mutex);
1086 return -EEXIST;
1087 }
1088 up(&ebt_mutex);
1089
1090 return 0;
1091}
1092
1093void ebt_unregister_match(struct ebt_match *match)
1094{
1095 down(&ebt_mutex);
1096 LIST_DELETE(&ebt_matches, match);
1097 up(&ebt_mutex);
1098}
1099
1100int ebt_register_watcher(struct ebt_watcher *watcher)
1101{
1102 int ret;
1103
1104 ret = down_interruptible(&ebt_mutex);
1105 if (ret != 0)
1106 return ret;
1107 if (!list_named_insert(&ebt_watchers, watcher)) {
1108 up(&ebt_mutex);
1109 return -EEXIST;
1110 }
1111 up(&ebt_mutex);
1112
1113 return 0;
1114}
1115
1116void ebt_unregister_watcher(struct ebt_watcher *watcher)
1117{
1118 down(&ebt_mutex);
1119 LIST_DELETE(&ebt_watchers, watcher);
1120 up(&ebt_mutex);
1121}
1122
1123int ebt_register_table(struct ebt_table *table)
1124{
1125 struct ebt_table_info *newinfo;
1126 int ret, i, countersize;
1127
1128 if (!table || !table->table ||!table->table->entries ||
1129 table->table->entries_size == 0 ||
1130 table->table->counters || table->private) {
1131 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1132 return -EINVAL;
1133 }
1134
1135 countersize = COUNTER_OFFSET(table->table->nentries) * num_possible_cpus();
1136 newinfo = (struct ebt_table_info *)
1137 vmalloc(sizeof(struct ebt_table_info) + countersize);
1138 ret = -ENOMEM;
1139 if (!newinfo)
1140 return -ENOMEM;
1141
1142 newinfo->entries = (char *)vmalloc(table->table->entries_size);
1143 if (!(newinfo->entries))
1144 goto free_newinfo;
1145
1146 memcpy(newinfo->entries, table->table->entries,
1147 table->table->entries_size);
1148
1149 if (countersize)
1150 memset(newinfo->counters, 0, countersize);
1151
1152 /* fill in newinfo and parse the entries */
1153 newinfo->chainstack = NULL;
1154 ret = translate_table(table->table, newinfo);
1155 if (ret != 0) {
1156 BUGPRINT("Translate_table failed\n");
1157 goto free_chainstack;
1158 }
1159
1160 if (table->check && table->check(newinfo, table->valid_hooks)) {
1161 BUGPRINT("The table doesn't like its own initial data, lol\n");
1162 return -EINVAL;
1163 }
1164
1165 table->private = newinfo;
1166 rwlock_init(&table->lock);
1167 ret = down_interruptible(&ebt_mutex);
1168 if (ret != 0)
1169 goto free_chainstack;
1170
1171 if (list_named_find(&ebt_tables, table->name)) {
1172 ret = -EEXIST;
1173 BUGPRINT("Table name already exists\n");
1174 goto free_unlock;
1175 }
1176
1177 /* Hold a reference count if the chains aren't empty */
1178 if (newinfo->nentries && !try_module_get(table->me)) {
1179 ret = -ENOENT;
1180 goto free_unlock;
1181 }
1182 list_prepend(&ebt_tables, table);
1183 up(&ebt_mutex);
1184 return 0;
1185free_unlock:
1186 up(&ebt_mutex);
1187free_chainstack:
1188 if (newinfo->chainstack) {
1189 for (i = 0; i < num_possible_cpus(); i++)
1190 vfree(newinfo->chainstack[i]);
1191 vfree(newinfo->chainstack);
1192 }
1193 vfree(newinfo->entries);
1194free_newinfo:
1195 vfree(newinfo);
1196 return ret;
1197}
1198
1199void ebt_unregister_table(struct ebt_table *table)
1200{
1201 int i;
1202
1203 if (!table) {
1204 BUGPRINT("Request to unregister NULL table!!!\n");
1205 return;
1206 }
1207 down(&ebt_mutex);
1208 LIST_DELETE(&ebt_tables, table);
1209 up(&ebt_mutex);
James Lamanna68d31872005-06-22 22:12:57 -07001210 vfree(table->private->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 if (table->private->chainstack) {
1212 for (i = 0; i < num_possible_cpus(); i++)
1213 vfree(table->private->chainstack[i]);
1214 vfree(table->private->chainstack);
1215 }
1216 vfree(table->private);
1217}
1218
1219/* userspace just supplied us with counters */
1220static int update_counters(void __user *user, unsigned int len)
1221{
1222 int i, ret;
1223 struct ebt_counter *tmp;
1224 struct ebt_replace hlp;
1225 struct ebt_table *t;
1226
1227 if (copy_from_user(&hlp, user, sizeof(hlp)))
1228 return -EFAULT;
1229
1230 if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
1231 return -EINVAL;
1232 if (hlp.num_counters == 0)
1233 return -EINVAL;
1234
1235 if ( !(tmp = (struct ebt_counter *)
1236 vmalloc(hlp.num_counters * sizeof(struct ebt_counter))) ){
1237 MEMPRINT("Update_counters && nomemory\n");
1238 return -ENOMEM;
1239 }
1240
1241 t = find_table_lock(hlp.name, &ret, &ebt_mutex);
1242 if (!t)
1243 goto free_tmp;
1244
1245 if (hlp.num_counters != t->private->nentries) {
1246 BUGPRINT("Wrong nr of counters\n");
1247 ret = -EINVAL;
1248 goto unlock_mutex;
1249 }
1250
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;
1256 }
1257
1258 /* we want an atomic add of the counters */
1259 write_lock_bh(&t->lock);
1260
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;
1265 }
1266
1267 write_unlock_bh(&t->lock);
1268 ret = 0;
1269unlock_mutex:
1270 up(&ebt_mutex);
1271free_tmp:
1272 vfree(tmp);
1273 return ret;
1274}
1275
1276static inline int ebt_make_matchname(struct ebt_entry_match *m,
1277 char *base, char *ubase)
1278{
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;
1283}
1284
1285static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
1286 char *base, char *ubase)
1287{
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;
1292}
1293
1294static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase)
1295{
1296 int ret;
1297 char *hlp;
1298 struct ebt_entry_target *t;
1299
1300 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
1301 return 0;
1302
1303 hlp = ubase - base + (char *)e + e->target_offset;
1304 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
1305
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;
1315}
1316
1317/* called with ebt_mutex down */
1318static int copy_everything_to_user(struct ebt_table *t, void __user *user,
1319 int *len, int cmd)
1320{
1321 struct ebt_replace tmp;
1322 struct ebt_counter *counterstmp, *oldcounters;
1323 unsigned int entries_size, nentries;
1324 char *entries;
1325
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;
1336 }
1337
1338 if (copy_from_user(&tmp, user, sizeof(tmp))) {
1339 BUGPRINT("Cfu didn't work\n");
1340 return -EFAULT;
1341 }
1342
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;
1347 }
1348
1349 if (tmp.nentries != nentries) {
1350 BUGPRINT("Nentries wrong\n");
1351 return -EINVAL;
1352 }
1353
1354 if (tmp.entries_size != entries_size) {
1355 BUGPRINT("Wrong size\n");
1356 return -EINVAL;
1357 }
1358
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;
1364 }
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;
1370 }
1371 write_lock_bh(&t->lock);
1372 get_counters(oldcounters, counterstmp, nentries);
1373 write_unlock_bh(&t->lock);
1374
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;
1380 }
1381 vfree(counterstmp);
1382 }
1383
1384 if (copy_to_user(tmp.entries, entries, entries_size)) {
1385 BUGPRINT("Couldn't copy entries to userspace\n");
1386 return -EFAULT;
1387 }
1388 /* set the match/watcher/target names right */
1389 return EBT_ENTRY_ITERATE(entries, entries_size,
1390 ebt_make_names, entries, tmp.entries);
1391}
1392
1393static int do_ebt_set_ctl(struct sock *sk,
1394 int cmd, void __user *user, unsigned int len)
1395{
1396 int ret;
1397
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;
1407 }
1408 return ret;
1409}
1410
1411static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1412{
1413 int ret;
1414 struct ebt_replace tmp;
1415 struct ebt_table *t;
1416
1417 if (copy_from_user(&tmp, user, sizeof(tmp)))
1418 return -EFAULT;
1419
1420 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
1421 if (!t)
1422 return ret;
1423
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;
1431 }
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;
1440 }
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;
1446 }
1447 ret = 0;
1448 break;
1449
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;
1455
1456 default:
1457 up(&ebt_mutex);
1458 ret = -EINVAL;
1459 }
1460
1461 return ret;
1462}
1463
1464static 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
1467};
1468
1469static int __init init(void)
1470{
1471 int ret;
1472
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;
1478
1479 printk(KERN_NOTICE "Ebtables v2.0 registered\n");
1480 return 0;
1481}
1482
1483static void __exit fini(void)
1484{
1485 nf_unregister_sockopt(&ebt_sockopts);
1486 printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
1487}
1488
1489EXPORT_SYMBOL(ebt_register_table);
1490EXPORT_SYMBOL(ebt_unregister_table);
1491EXPORT_SYMBOL(ebt_register_match);
1492EXPORT_SYMBOL(ebt_unregister_match);
1493EXPORT_SYMBOL(ebt_register_watcher);
1494EXPORT_SYMBOL(ebt_unregister_watcher);
1495EXPORT_SYMBOL(ebt_register_target);
1496EXPORT_SYMBOL(ebt_unregister_target);
1497EXPORT_SYMBOL(ebt_do_table);
1498module_init(init);
1499module_exit(fini);
1500MODULE_LICENSE("GPL");