blob: 3a13ed643459bc3d249d0b73b1c98a1d76e5a3c5 [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>
David S. Millerc8923c62005-10-13 14:41:23 -070029#include <linux/cpumask.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include <net/sock.h>
31/* needed for logical [in,out]-dev filtering */
32#include "../br_private.h"
33
34/* list_named_find */
35#define ASSERT_READ_LOCK(x)
36#define ASSERT_WRITE_LOCK(x)
37#include <linux/netfilter_ipv4/listhelp.h>
Ingo Molnar57b47a52006-03-20 22:35:41 -080038#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070039
40#if 0
41/* use this for remote debugging
42 * Copyright (C) 1998 by Ori Pomerantz
43 * Print the string to the appropriate tty, the one
44 * the current task uses
45 */
46static void print_string(char *str)
47{
48 struct tty_struct *my_tty;
49
50 /* The tty for the current task */
51 my_tty = current->signal->tty;
52 if (my_tty != NULL) {
53 my_tty->driver->write(my_tty, 0, str, strlen(str));
54 my_tty->driver->write(my_tty, 0, "\015\012", 2);
55 }
56}
57
58#define BUGPRINT(args) print_string(args);
59#else
60#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\
61 "report to author: "format, ## args)
62/* #define BUGPRINT(format, args...) */
63#endif
64#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\
65 ": out of memory: "format, ## args)
66/* #define MEMPRINT(format, args...) */
67
68
69
70/*
71 * Each cpu has its own set of counters, so there is no need for write_lock in
72 * the softirq
73 * For reading or updating the counters, the user context needs to
74 * get a write_lock
75 */
76
77/* The size of each set of counters is altered to get cache alignment */
78#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
79#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))
80#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \
81 COUNTER_OFFSET(n) * cpu))
82
83
84
Ingo Molnar57b47a52006-03-20 22:35:41 -080085static DEFINE_MUTEX(ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086static LIST_HEAD(ebt_tables);
87static LIST_HEAD(ebt_targets);
88static LIST_HEAD(ebt_matches);
89static LIST_HEAD(ebt_watchers);
90
91static struct ebt_target ebt_standard_target =
92{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL};
93
94static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
95 const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in,
96 const struct net_device *out)
97{
98 w->u.watcher->watcher(skb, hooknr, in, out, w->data,
99 w->watcher_size);
100 /* watchers don't give a verdict */
101 return 0;
102}
103
104static inline int ebt_do_match (struct ebt_entry_match *m,
105 const struct sk_buff *skb, const struct net_device *in,
106 const struct net_device *out)
107{
108 return m->u.match->match(skb, in, out, m->data,
109 m->match_size);
110}
111
112static inline int ebt_dev_check(char *entry, const struct net_device *device)
113{
114 int i = 0;
115 char *devname = device->name;
116
117 if (*entry == '\0')
118 return 0;
119 if (!device)
120 return 1;
121 /* 1 is the wildcard token */
122 while (entry[i] != '\0' && entry[i] != 1 && entry[i] == devname[i])
123 i++;
124 return (devname[i] != entry[i] && entry[i] != 1);
125}
126
127#define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg))
128/* process standard matches */
129static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
130 const struct net_device *in, const struct net_device *out)
131{
132 int verdict, i;
133
134 if (e->bitmask & EBT_802_3) {
135 if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO))
136 return 1;
137 } else if (!(e->bitmask & EBT_NOPROTO) &&
138 FWINV2(e->ethproto != h->h_proto, EBT_IPROTO))
139 return 1;
140
141 if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN))
142 return 1;
143 if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
144 return 1;
145 if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check(
146 e->logical_in, in->br_port->br->dev), EBT_ILOGICALIN))
147 return 1;
148 if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check(
149 e->logical_out, out->br_port->br->dev), EBT_ILOGICALOUT))
150 return 1;
151
152 if (e->bitmask & EBT_SOURCEMAC) {
153 verdict = 0;
154 for (i = 0; i < 6; i++)
155 verdict |= (h->h_source[i] ^ e->sourcemac[i]) &
156 e->sourcemsk[i];
157 if (FWINV2(verdict != 0, EBT_ISOURCE) )
158 return 1;
159 }
160 if (e->bitmask & EBT_DESTMAC) {
161 verdict = 0;
162 for (i = 0; i < 6; i++)
163 verdict |= (h->h_dest[i] ^ e->destmac[i]) &
164 e->destmsk[i];
165 if (FWINV2(verdict != 0, EBT_IDEST) )
166 return 1;
167 }
168 return 0;
169}
170
171/* Do some firewalling */
172unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
173 const struct net_device *in, const struct net_device *out,
174 struct ebt_table *table)
175{
176 int i, nentries;
177 struct ebt_entry *point;
178 struct ebt_counter *counter_base, *cb_base;
179 struct ebt_entry_target *t;
180 int verdict, sp = 0;
181 struct ebt_chainstack *cs;
182 struct ebt_entries *chaininfo;
183 char *base;
184 struct ebt_table_info *private;
185
186 read_lock_bh(&table->lock);
187 private = table->private;
188 cb_base = COUNTER_BASE(private->counters, private->nentries,
189 smp_processor_id());
190 if (private->chainstack)
191 cs = private->chainstack[smp_processor_id()];
192 else
193 cs = NULL;
194 chaininfo = private->hook_entry[hook];
195 nentries = private->hook_entry[hook]->nentries;
196 point = (struct ebt_entry *)(private->hook_entry[hook]->data);
197 counter_base = cb_base + private->hook_entry[hook]->counter_offset;
198 /* base for chain jumps */
199 base = private->entries;
200 i = 0;
201 while (i < nentries) {
202 if (ebt_basic_match(point, eth_hdr(*pskb), in, out))
203 goto letscontinue;
204
205 if (EBT_MATCH_ITERATE(point, ebt_do_match, *pskb, in, out) != 0)
206 goto letscontinue;
207
208 /* increase counter */
209 (*(counter_base + i)).pcnt++;
210 (*(counter_base + i)).bcnt+=(**pskb).len;
211
212 /* these should only watch: not modify, nor tell us
213 what to do with the packet */
214 EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, hook, in,
215 out);
216
217 t = (struct ebt_entry_target *)
218 (((char *)point) + point->target_offset);
219 /* standard target */
220 if (!t->u.target->target)
221 verdict = ((struct ebt_standard_target *)t)->verdict;
222 else
223 verdict = t->u.target->target(pskb, hook,
224 in, out, t->data, t->target_size);
225 if (verdict == EBT_ACCEPT) {
226 read_unlock_bh(&table->lock);
227 return NF_ACCEPT;
228 }
229 if (verdict == EBT_DROP) {
230 read_unlock_bh(&table->lock);
231 return NF_DROP;
232 }
233 if (verdict == EBT_RETURN) {
234letsreturn:
235#ifdef CONFIG_NETFILTER_DEBUG
236 if (sp == 0) {
237 BUGPRINT("RETURN on base chain");
238 /* act like this is EBT_CONTINUE */
239 goto letscontinue;
240 }
241#endif
242 sp--;
243 /* put all the local variables right */
244 i = cs[sp].n;
245 chaininfo = cs[sp].chaininfo;
246 nentries = chaininfo->nentries;
247 point = cs[sp].e;
248 counter_base = cb_base +
249 chaininfo->counter_offset;
250 continue;
251 }
252 if (verdict == EBT_CONTINUE)
253 goto letscontinue;
254#ifdef CONFIG_NETFILTER_DEBUG
255 if (verdict < 0) {
256 BUGPRINT("bogus standard verdict\n");
257 read_unlock_bh(&table->lock);
258 return NF_DROP;
259 }
260#endif
261 /* jump to a udc */
262 cs[sp].n = i + 1;
263 cs[sp].chaininfo = chaininfo;
264 cs[sp].e = (struct ebt_entry *)
265 (((char *)point) + point->next_offset);
266 i = 0;
267 chaininfo = (struct ebt_entries *) (base + verdict);
268#ifdef CONFIG_NETFILTER_DEBUG
269 if (chaininfo->distinguisher) {
270 BUGPRINT("jump to non-chain\n");
271 read_unlock_bh(&table->lock);
272 return NF_DROP;
273 }
274#endif
275 nentries = chaininfo->nentries;
276 point = (struct ebt_entry *)chaininfo->data;
277 counter_base = cb_base + chaininfo->counter_offset;
278 sp++;
279 continue;
280letscontinue:
281 point = (struct ebt_entry *)
282 (((char *)point) + point->next_offset);
283 i++;
284 }
285
286 /* I actually like this :) */
287 if (chaininfo->policy == EBT_RETURN)
288 goto letsreturn;
289 if (chaininfo->policy == EBT_ACCEPT) {
290 read_unlock_bh(&table->lock);
291 return NF_ACCEPT;
292 }
293 read_unlock_bh(&table->lock);
294 return NF_DROP;
295}
296
297/* If it succeeds, returns element and locks mutex */
298static inline void *
299find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
Ingo Molnar57b47a52006-03-20 22:35:41 -0800300 struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301{
302 void *ret;
303
Ingo Molnar57b47a52006-03-20 22:35:41 -0800304 *error = mutex_lock_interruptible(mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 if (*error != 0)
306 return NULL;
307
308 ret = list_named_find(head, name);
309 if (!ret) {
310 *error = -ENOENT;
Ingo Molnar57b47a52006-03-20 22:35:41 -0800311 mutex_unlock(mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 }
313 return ret;
314}
315
316#ifndef CONFIG_KMOD
317#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
318#else
319static void *
320find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
Ingo Molnar57b47a52006-03-20 22:35:41 -0800321 int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322{
323 void *ret;
324
325 ret = find_inlist_lock_noload(head, name, error, mutex);
326 if (!ret) {
327 request_module("%s%s", prefix, name);
328 ret = find_inlist_lock_noload(head, name, error, mutex);
329 }
330 return ret;
331}
332#endif
333
334static inline struct ebt_table *
Ingo Molnar57b47a52006-03-20 22:35:41 -0800335find_table_lock(const char *name, int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336{
337 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
338}
339
340static inline struct ebt_match *
Ingo Molnar57b47a52006-03-20 22:35:41 -0800341find_match_lock(const char *name, int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342{
343 return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
344}
345
346static inline struct ebt_watcher *
Ingo Molnar57b47a52006-03-20 22:35:41 -0800347find_watcher_lock(const char *name, int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348{
349 return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
350}
351
352static inline struct ebt_target *
Ingo Molnar57b47a52006-03-20 22:35:41 -0800353find_target_lock(const char *name, int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354{
355 return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
356}
357
358static inline int
359ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
360 const char *name, unsigned int hookmask, unsigned int *cnt)
361{
362 struct ebt_match *match;
363 int ret;
364
365 if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) >
366 ((char *)e) + e->watchers_offset)
367 return -EINVAL;
368 match = find_match_lock(m->u.name, &ret, &ebt_mutex);
369 if (!match)
370 return ret;
371 m->u.match = match;
372 if (!try_module_get(match->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800373 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 return -ENOENT;
375 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800376 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 if (match->check &&
378 match->check(name, hookmask, e, m->data, m->match_size) != 0) {
379 BUGPRINT("match->check failed\n");
380 module_put(match->me);
381 return -EINVAL;
382 }
383 (*cnt)++;
384 return 0;
385}
386
387static inline int
388ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
389 const char *name, unsigned int hookmask, unsigned int *cnt)
390{
391 struct ebt_watcher *watcher;
392 int ret;
393
394 if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) >
395 ((char *)e) + e->target_offset)
396 return -EINVAL;
397 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
398 if (!watcher)
399 return ret;
400 w->u.watcher = watcher;
401 if (!try_module_get(watcher->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800402 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 return -ENOENT;
404 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800405 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 if (watcher->check &&
407 watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) {
408 BUGPRINT("watcher->check failed\n");
409 module_put(watcher->me);
410 return -EINVAL;
411 }
412 (*cnt)++;
413 return 0;
414}
415
416/*
417 * this one is very careful, as it is the first function
418 * to parse the userspace data
419 */
420static inline int
421ebt_check_entry_size_and_hooks(struct ebt_entry *e,
422 struct ebt_table_info *newinfo, char *base, char *limit,
423 struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt,
424 unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks)
425{
426 int i;
427
428 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
429 if ((valid_hooks & (1 << i)) == 0)
430 continue;
431 if ( (char *)hook_entries[i] - base ==
432 (char *)e - newinfo->entries)
433 break;
434 }
435 /* beginning of a new chain
436 if i == NF_BR_NUMHOOKS it must be a user defined chain */
437 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
438 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) {
439 /* we make userspace set this right,
440 so there is no misunderstanding */
441 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
442 "in distinguisher\n");
443 return -EINVAL;
444 }
445 /* this checks if the previous chain has as many entries
446 as it said it has */
447 if (*n != *cnt) {
448 BUGPRINT("nentries does not equal the nr of entries "
449 "in the chain\n");
450 return -EINVAL;
451 }
452 /* before we look at the struct, be sure it is not too big */
453 if ((char *)hook_entries[i] + sizeof(struct ebt_entries)
454 > limit) {
455 BUGPRINT("entries_size too small\n");
456 return -EINVAL;
457 }
458 if (((struct ebt_entries *)e)->policy != EBT_DROP &&
459 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
460 /* only RETURN from udc */
461 if (i != NF_BR_NUMHOOKS ||
462 ((struct ebt_entries *)e)->policy != EBT_RETURN) {
463 BUGPRINT("bad policy\n");
464 return -EINVAL;
465 }
466 }
467 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
468 (*udc_cnt)++;
469 else
470 newinfo->hook_entry[i] = (struct ebt_entries *)e;
471 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
472 BUGPRINT("counter_offset != totalcnt");
473 return -EINVAL;
474 }
475 *n = ((struct ebt_entries *)e)->nentries;
476 *cnt = 0;
477 return 0;
478 }
479 /* a plain old entry, heh */
480 if (sizeof(struct ebt_entry) > e->watchers_offset ||
481 e->watchers_offset > e->target_offset ||
482 e->target_offset >= e->next_offset) {
483 BUGPRINT("entry offsets not in right order\n");
484 return -EINVAL;
485 }
486 /* this is not checked anywhere else */
487 if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) {
488 BUGPRINT("target size too small\n");
489 return -EINVAL;
490 }
491
492 (*cnt)++;
493 (*totalcnt)++;
494 return 0;
495}
496
497struct ebt_cl_stack
498{
499 struct ebt_chainstack cs;
500 int from;
501 unsigned int hookmask;
502};
503
504/*
505 * we need these positions to check that the jumps to a different part of the
506 * entries is a jump to the beginning of a new chain.
507 */
508static inline int
509ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
510 struct ebt_entries **hook_entries, unsigned int *n, unsigned int valid_hooks,
511 struct ebt_cl_stack *udc)
512{
513 int i;
514
515 /* we're only interested in chain starts */
516 if (e->bitmask & EBT_ENTRY_OR_ENTRIES)
517 return 0;
518 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
519 if ((valid_hooks & (1 << i)) == 0)
520 continue;
521 if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
522 break;
523 }
524 /* only care about udc */
525 if (i != NF_BR_NUMHOOKS)
526 return 0;
527
528 udc[*n].cs.chaininfo = (struct ebt_entries *)e;
529 /* these initialisations are depended on later in check_chainloops() */
530 udc[*n].cs.n = 0;
531 udc[*n].hookmask = 0;
532
533 (*n)++;
534 return 0;
535}
536
537static inline int
538ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
539{
540 if (i && (*i)-- == 0)
541 return 1;
542 if (m->u.match->destroy)
543 m->u.match->destroy(m->data, m->match_size);
544 module_put(m->u.match->me);
545
546 return 0;
547}
548
549static inline int
550ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
551{
552 if (i && (*i)-- == 0)
553 return 1;
554 if (w->u.watcher->destroy)
555 w->u.watcher->destroy(w->data, w->watcher_size);
556 module_put(w->u.watcher->me);
557
558 return 0;
559}
560
561static inline int
562ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
563{
564 struct ebt_entry_target *t;
565
566 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
567 return 0;
568 /* we're done */
569 if (cnt && (*cnt)-- == 0)
570 return 1;
571 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
572 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
573 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
574 if (t->u.target->destroy)
575 t->u.target->destroy(t->data, t->target_size);
576 module_put(t->u.target->me);
577
578 return 0;
579}
580
581static inline int
582ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
583 const char *name, unsigned int *cnt, unsigned int valid_hooks,
584 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
585{
586 struct ebt_entry_target *t;
587 struct ebt_target *target;
588 unsigned int i, j, hook = 0, hookmask = 0;
589 int ret;
590
591 /* don't mess with the struct ebt_entries */
592 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
593 return 0;
594
595 if (e->bitmask & ~EBT_F_MASK) {
596 BUGPRINT("Unknown flag for bitmask\n");
597 return -EINVAL;
598 }
599 if (e->invflags & ~EBT_INV_MASK) {
600 BUGPRINT("Unknown flag for inv bitmask\n");
601 return -EINVAL;
602 }
603 if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) {
604 BUGPRINT("NOPROTO & 802_3 not allowed\n");
605 return -EINVAL;
606 }
607 /* what hook do we belong to? */
608 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
609 if ((valid_hooks & (1 << i)) == 0)
610 continue;
611 if ((char *)newinfo->hook_entry[i] < (char *)e)
612 hook = i;
613 else
614 break;
615 }
616 /* (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on
617 a base chain */
618 if (i < NF_BR_NUMHOOKS)
619 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
620 else {
621 for (i = 0; i < udc_cnt; i++)
622 if ((char *)(cl_s[i].cs.chaininfo) > (char *)e)
623 break;
624 if (i == 0)
625 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
626 else
627 hookmask = cl_s[i - 1].hookmask;
628 }
629 i = 0;
630 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
631 if (ret != 0)
632 goto cleanup_matches;
633 j = 0;
634 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
635 if (ret != 0)
636 goto cleanup_watchers;
637 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
638 target = find_target_lock(t->u.name, &ret, &ebt_mutex);
639 if (!target)
640 goto cleanup_watchers;
641 if (!try_module_get(target->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800642 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 ret = -ENOENT;
644 goto cleanup_watchers;
645 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800646 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
648 t->u.target = target;
649 if (t->u.target == &ebt_standard_target) {
650 if (e->target_offset + sizeof(struct ebt_standard_target) >
651 e->next_offset) {
652 BUGPRINT("Standard target size too big\n");
653 ret = -EFAULT;
654 goto cleanup_watchers;
655 }
656 if (((struct ebt_standard_target *)t)->verdict <
657 -NUM_STANDARD_TARGETS) {
658 BUGPRINT("Invalid standard target\n");
659 ret = -EFAULT;
660 goto cleanup_watchers;
661 }
662 } else if ((e->target_offset + t->target_size +
663 sizeof(struct ebt_entry_target) > e->next_offset) ||
664 (t->u.target->check &&
665 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
666 module_put(t->u.target->me);
667 ret = -EFAULT;
668 goto cleanup_watchers;
669 }
670 (*cnt)++;
671 return 0;
672cleanup_watchers:
673 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j);
674cleanup_matches:
675 EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i);
676 return ret;
677}
678
679/*
680 * checks for loops and sets the hook mask for udc
681 * the hook mask for udc tells us from which base chains the udc can be
682 * accessed. This mask is a parameter to the check() functions of the extensions
683 */
684static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s,
685 unsigned int udc_cnt, unsigned int hooknr, char *base)
686{
687 int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict;
688 struct ebt_entry *e = (struct ebt_entry *)chain->data;
689 struct ebt_entry_target *t;
690
691 while (pos < nentries || chain_nr != -1) {
692 /* end of udc, go back one 'recursion' step */
693 if (pos == nentries) {
694 /* put back values of the time when this chain was called */
695 e = cl_s[chain_nr].cs.e;
696 if (cl_s[chain_nr].from != -1)
697 nentries =
698 cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries;
699 else
700 nentries = chain->nentries;
701 pos = cl_s[chain_nr].cs.n;
702 /* make sure we won't see a loop that isn't one */
703 cl_s[chain_nr].cs.n = 0;
704 chain_nr = cl_s[chain_nr].from;
705 if (pos == nentries)
706 continue;
707 }
708 t = (struct ebt_entry_target *)
709 (((char *)e) + e->target_offset);
710 if (strcmp(t->u.name, EBT_STANDARD_TARGET))
711 goto letscontinue;
712 if (e->target_offset + sizeof(struct ebt_standard_target) >
713 e->next_offset) {
714 BUGPRINT("Standard target size too big\n");
715 return -1;
716 }
717 verdict = ((struct ebt_standard_target *)t)->verdict;
718 if (verdict >= 0) { /* jump to another chain */
719 struct ebt_entries *hlp2 =
720 (struct ebt_entries *)(base + verdict);
721 for (i = 0; i < udc_cnt; i++)
722 if (hlp2 == cl_s[i].cs.chaininfo)
723 break;
724 /* bad destination or loop */
725 if (i == udc_cnt) {
726 BUGPRINT("bad destination\n");
727 return -1;
728 }
729 if (cl_s[i].cs.n) {
730 BUGPRINT("loop\n");
731 return -1;
732 }
733 /* this can't be 0, so the above test is correct */
734 cl_s[i].cs.n = pos + 1;
735 pos = 0;
736 cl_s[i].cs.e = ((void *)e + e->next_offset);
737 e = (struct ebt_entry *)(hlp2->data);
738 nentries = hlp2->nentries;
739 cl_s[i].from = chain_nr;
740 chain_nr = i;
741 /* this udc is accessible from the base chain for hooknr */
742 cl_s[i].hookmask |= (1 << hooknr);
743 continue;
744 }
745letscontinue:
746 e = (void *)e + e->next_offset;
747 pos++;
748 }
749 return 0;
750}
751
752/* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
753static int translate_table(struct ebt_replace *repl,
754 struct ebt_table_info *newinfo)
755{
756 unsigned int i, j, k, udc_cnt;
757 int ret;
758 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
759
760 i = 0;
761 while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i)))
762 i++;
763 if (i == NF_BR_NUMHOOKS) {
764 BUGPRINT("No valid hooks specified\n");
765 return -EINVAL;
766 }
767 if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) {
768 BUGPRINT("Chains don't start at beginning\n");
769 return -EINVAL;
770 }
771 /* make sure chains are ordered after each other in same order
772 as their corresponding hooks */
773 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
774 if (!(repl->valid_hooks & (1 << j)))
775 continue;
776 if ( repl->hook_entry[j] <= repl->hook_entry[i] ) {
777 BUGPRINT("Hook order must be followed\n");
778 return -EINVAL;
779 }
780 i = j;
781 }
782
783 for (i = 0; i < NF_BR_NUMHOOKS; i++)
784 newinfo->hook_entry[i] = NULL;
785
786 newinfo->entries_size = repl->entries_size;
787 newinfo->nentries = repl->nentries;
788
789 /* do some early checkings and initialize some things */
790 i = 0; /* holds the expected nr. of entries for the chain */
791 j = 0; /* holds the up to now counted entries for the chain */
792 k = 0; /* holds the total nr. of entries, should equal
793 newinfo->nentries afterwards */
794 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
795 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
796 ebt_check_entry_size_and_hooks, newinfo, repl->entries,
797 repl->entries + repl->entries_size, repl->hook_entry, &i, &j, &k,
798 &udc_cnt, repl->valid_hooks);
799
800 if (ret != 0)
801 return ret;
802
803 if (i != j) {
804 BUGPRINT("nentries does not equal the nr of entries in the "
805 "(last) chain\n");
806 return -EINVAL;
807 }
808 if (k != newinfo->nentries) {
809 BUGPRINT("Total nentries is wrong\n");
810 return -EINVAL;
811 }
812
813 /* check if all valid hooks have a chain */
814 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
815 if (newinfo->hook_entry[i] == NULL &&
816 (repl->valid_hooks & (1 << i))) {
817 BUGPRINT("Valid hook without chain\n");
818 return -EINVAL;
819 }
820 }
821
822 /* get the location of the udc, put them in an array
823 while we're at it, allocate the chainstack */
824 if (udc_cnt) {
825 /* this will get free'd in do_replace()/ebt_register_table()
826 if an error occurs */
Jayachandran C7ad4d2f2006-04-11 17:25:38 -0700827 newinfo->chainstack =
828 vmalloc((highest_possible_processor_id()+1)
829 * sizeof(*(newinfo->chainstack)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 if (!newinfo->chainstack)
831 return -ENOMEM;
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -0700832 for_each_possible_cpu(i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 newinfo->chainstack[i] =
Jayachandran C18bc89a2006-04-20 00:14:49 -0700834 vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0])));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 if (!newinfo->chainstack[i]) {
836 while (i)
837 vfree(newinfo->chainstack[--i]);
838 vfree(newinfo->chainstack);
839 newinfo->chainstack = NULL;
840 return -ENOMEM;
841 }
842 }
843
Jayachandran C18bc89a2006-04-20 00:14:49 -0700844 cl_s = vmalloc(udc_cnt * sizeof(*cl_s));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 if (!cl_s)
846 return -ENOMEM;
847 i = 0; /* the i'th udc */
848 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
849 ebt_get_udc_positions, newinfo, repl->hook_entry, &i,
850 repl->valid_hooks, cl_s);
851 /* sanity check */
852 if (i != udc_cnt) {
853 BUGPRINT("i != udc_cnt\n");
854 vfree(cl_s);
855 return -EFAULT;
856 }
857 }
858
859 /* Check for loops */
860 for (i = 0; i < NF_BR_NUMHOOKS; i++)
861 if (repl->valid_hooks & (1 << i))
862 if (check_chainloops(newinfo->hook_entry[i],
863 cl_s, udc_cnt, i, newinfo->entries)) {
James Lamanna68d31872005-06-22 22:12:57 -0700864 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 return -EINVAL;
866 }
867
868 /* we now know the following (along with E=mc²):
869 - the nr of entries in each chain is right
870 - the size of the allocated space is right
871 - all valid hooks have a corresponding chain
872 - there are no loops
873 - wrong data can still be on the level of a single entry
874 - could be there are jumps to places that are not the
875 beginning of a chain. This can only occur in chains that
876 are not accessible from any base chains, so we don't care. */
877
878 /* used to know what we need to clean up if something goes wrong */
879 i = 0;
880 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
881 ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks,
882 cl_s, udc_cnt);
883 if (ret != 0) {
884 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
885 ebt_cleanup_entry, &i);
886 }
James Lamanna68d31872005-06-22 22:12:57 -0700887 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 return ret;
889}
890
891/* called under write_lock */
892static void get_counters(struct ebt_counter *oldcounters,
893 struct ebt_counter *counters, unsigned int nentries)
894{
895 int i, cpu;
896 struct ebt_counter *counter_base;
897
898 /* counters of cpu 0 */
899 memcpy(counters, oldcounters,
David S. Millerc8923c62005-10-13 14:41:23 -0700900 sizeof(struct ebt_counter) * nentries);
901
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 /* add other counters to those of cpu 0 */
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -0700903 for_each_possible_cpu(cpu) {
David S. Millerc8923c62005-10-13 14:41:23 -0700904 if (cpu == 0)
905 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
907 for (i = 0; i < nentries; i++) {
908 counters[i].pcnt += counter_base[i].pcnt;
909 counters[i].bcnt += counter_base[i].bcnt;
910 }
911 }
912}
913
914/* replace the table */
915static int do_replace(void __user *user, unsigned int len)
916{
917 int ret, i, countersize;
918 struct ebt_table_info *newinfo;
919 struct ebt_replace tmp;
920 struct ebt_table *t;
921 struct ebt_counter *counterstmp = NULL;
922 /* used to be able to unlock earlier */
923 struct ebt_table_info *table;
924
925 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
926 return -EFAULT;
927
928 if (len != sizeof(tmp) + tmp.entries_size) {
929 BUGPRINT("Wrong len argument\n");
930 return -EINVAL;
931 }
932
933 if (tmp.entries_size == 0) {
934 BUGPRINT("Entries_size never zero\n");
935 return -EINVAL;
936 }
Kirill Korotaevee4bb812006-02-04 02:16:56 -0800937 /* overflow check */
938 if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
939 SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
940 return -ENOMEM;
941 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
942 return -ENOMEM;
943
David S. Millerc8923c62005-10-13 14:41:23 -0700944 countersize = COUNTER_OFFSET(tmp.nentries) *
945 (highest_possible_processor_id()+1);
Jayachandran C18bc89a2006-04-20 00:14:49 -0700946 newinfo = vmalloc(sizeof(*newinfo) + countersize);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 if (!newinfo)
948 return -ENOMEM;
949
950 if (countersize)
951 memset(newinfo->counters, 0, countersize);
952
Kris Katterjohn8b3a7002006-01-11 15:56:43 -0800953 newinfo->entries = vmalloc(tmp.entries_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 if (!newinfo->entries) {
955 ret = -ENOMEM;
956 goto free_newinfo;
957 }
958 if (copy_from_user(
959 newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
960 BUGPRINT("Couldn't copy entries from userspace\n");
961 ret = -EFAULT;
962 goto free_entries;
963 }
964
965 /* the user wants counters back
966 the check on the size is done later, when we have the lock */
967 if (tmp.num_counters) {
Jayachandran C18bc89a2006-04-20 00:14:49 -0700968 counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 if (!counterstmp) {
970 ret = -ENOMEM;
971 goto free_entries;
972 }
973 }
974 else
975 counterstmp = NULL;
976
977 /* this can get initialized by translate_table() */
978 newinfo->chainstack = NULL;
979 ret = translate_table(&tmp, newinfo);
980
981 if (ret != 0)
982 goto free_counterstmp;
983
984 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
985 if (!t) {
986 ret = -ENOENT;
987 goto free_iterate;
988 }
989
990 /* the table doesn't like it */
991 if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
992 goto free_unlock;
993
994 if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
995 BUGPRINT("Wrong nr. of counters requested\n");
996 ret = -EINVAL;
997 goto free_unlock;
998 }
999
1000 /* we have the mutex lock, so no danger in reading this pointer */
1001 table = t->private;
1002 /* make sure the table can only be rmmod'ed if it contains no rules */
1003 if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
1004 ret = -ENOENT;
1005 goto free_unlock;
1006 } else if (table->nentries && !newinfo->nentries)
1007 module_put(t->me);
1008 /* we need an atomic snapshot of the counters */
1009 write_lock_bh(&t->lock);
1010 if (tmp.num_counters)
1011 get_counters(t->private->counters, counterstmp,
1012 t->private->nentries);
1013
1014 t->private = newinfo;
1015 write_unlock_bh(&t->lock);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001016 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 /* so, a user can change the chains while having messed up her counter
1018 allocation. Only reason why this is done is because this way the lock
1019 is held only once, while this doesn't bring the kernel into a
1020 dangerous state. */
1021 if (tmp.num_counters &&
1022 copy_to_user(tmp.counters, counterstmp,
1023 tmp.num_counters * sizeof(struct ebt_counter))) {
1024 BUGPRINT("Couldn't copy counters to userspace\n");
1025 ret = -EFAULT;
1026 }
1027 else
1028 ret = 0;
1029
1030 /* decrease module count and free resources */
1031 EBT_ENTRY_ITERATE(table->entries, table->entries_size,
1032 ebt_cleanup_entry, NULL);
1033
1034 vfree(table->entries);
1035 if (table->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001036 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 vfree(table->chainstack[i]);
1038 vfree(table->chainstack);
1039 }
1040 vfree(table);
1041
James Lamanna68d31872005-06-22 22:12:57 -07001042 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043 return ret;
1044
1045free_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001046 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047free_iterate:
1048 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1049 ebt_cleanup_entry, NULL);
1050free_counterstmp:
James Lamanna68d31872005-06-22 22:12:57 -07001051 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 /* can be initialized in translate_table() */
1053 if (newinfo->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001054 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 vfree(newinfo->chainstack[i]);
1056 vfree(newinfo->chainstack);
1057 }
1058free_entries:
James Lamanna68d31872005-06-22 22:12:57 -07001059 vfree(newinfo->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060free_newinfo:
James Lamanna68d31872005-06-22 22:12:57 -07001061 vfree(newinfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 return ret;
1063}
1064
1065int ebt_register_target(struct ebt_target *target)
1066{
1067 int ret;
1068
Ingo Molnar57b47a52006-03-20 22:35:41 -08001069 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 if (ret != 0)
1071 return ret;
1072 if (!list_named_insert(&ebt_targets, target)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -08001073 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 return -EEXIST;
1075 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001076 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
1078 return 0;
1079}
1080
1081void ebt_unregister_target(struct ebt_target *target)
1082{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001083 mutex_lock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 LIST_DELETE(&ebt_targets, target);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001085 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086}
1087
1088int ebt_register_match(struct ebt_match *match)
1089{
1090 int ret;
1091
Ingo Molnar57b47a52006-03-20 22:35:41 -08001092 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 if (ret != 0)
1094 return ret;
1095 if (!list_named_insert(&ebt_matches, match)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -08001096 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 return -EEXIST;
1098 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001099 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
1101 return 0;
1102}
1103
1104void ebt_unregister_match(struct ebt_match *match)
1105{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001106 mutex_lock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 LIST_DELETE(&ebt_matches, match);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001108 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109}
1110
1111int ebt_register_watcher(struct ebt_watcher *watcher)
1112{
1113 int ret;
1114
Ingo Molnar57b47a52006-03-20 22:35:41 -08001115 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 if (ret != 0)
1117 return ret;
1118 if (!list_named_insert(&ebt_watchers, watcher)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -08001119 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 return -EEXIST;
1121 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001122 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123
1124 return 0;
1125}
1126
1127void ebt_unregister_watcher(struct ebt_watcher *watcher)
1128{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001129 mutex_lock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 LIST_DELETE(&ebt_watchers, watcher);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001131 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132}
1133
1134int ebt_register_table(struct ebt_table *table)
1135{
1136 struct ebt_table_info *newinfo;
1137 int ret, i, countersize;
1138
1139 if (!table || !table->table ||!table->table->entries ||
1140 table->table->entries_size == 0 ||
1141 table->table->counters || table->private) {
1142 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1143 return -EINVAL;
1144 }
1145
David S. Millerc8923c62005-10-13 14:41:23 -07001146 countersize = COUNTER_OFFSET(table->table->nentries) *
1147 (highest_possible_processor_id()+1);
Jayachandran C18bc89a2006-04-20 00:14:49 -07001148 newinfo = vmalloc(sizeof(*newinfo) + countersize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 ret = -ENOMEM;
1150 if (!newinfo)
1151 return -ENOMEM;
1152
Kris Katterjohn8b3a7002006-01-11 15:56:43 -08001153 newinfo->entries = vmalloc(table->table->entries_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 if (!(newinfo->entries))
1155 goto free_newinfo;
1156
1157 memcpy(newinfo->entries, table->table->entries,
1158 table->table->entries_size);
1159
1160 if (countersize)
1161 memset(newinfo->counters, 0, countersize);
1162
1163 /* fill in newinfo and parse the entries */
1164 newinfo->chainstack = NULL;
1165 ret = translate_table(table->table, newinfo);
1166 if (ret != 0) {
1167 BUGPRINT("Translate_table failed\n");
1168 goto free_chainstack;
1169 }
1170
1171 if (table->check && table->check(newinfo, table->valid_hooks)) {
1172 BUGPRINT("The table doesn't like its own initial data, lol\n");
1173 return -EINVAL;
1174 }
1175
1176 table->private = newinfo;
1177 rwlock_init(&table->lock);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001178 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 if (ret != 0)
1180 goto free_chainstack;
1181
1182 if (list_named_find(&ebt_tables, table->name)) {
1183 ret = -EEXIST;
1184 BUGPRINT("Table name already exists\n");
1185 goto free_unlock;
1186 }
1187
1188 /* Hold a reference count if the chains aren't empty */
1189 if (newinfo->nentries && !try_module_get(table->me)) {
1190 ret = -ENOENT;
1191 goto free_unlock;
1192 }
1193 list_prepend(&ebt_tables, table);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001194 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 return 0;
1196free_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001197 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198free_chainstack:
1199 if (newinfo->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001200 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 vfree(newinfo->chainstack[i]);
1202 vfree(newinfo->chainstack);
1203 }
1204 vfree(newinfo->entries);
1205free_newinfo:
1206 vfree(newinfo);
1207 return ret;
1208}
1209
1210void ebt_unregister_table(struct ebt_table *table)
1211{
1212 int i;
1213
1214 if (!table) {
1215 BUGPRINT("Request to unregister NULL table!!!\n");
1216 return;
1217 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001218 mutex_lock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 LIST_DELETE(&ebt_tables, table);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001220 mutex_unlock(&ebt_mutex);
James Lamanna68d31872005-06-22 22:12:57 -07001221 vfree(table->private->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 if (table->private->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001223 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 vfree(table->private->chainstack[i]);
1225 vfree(table->private->chainstack);
1226 }
1227 vfree(table->private);
1228}
1229
1230/* userspace just supplied us with counters */
1231static int update_counters(void __user *user, unsigned int len)
1232{
1233 int i, ret;
1234 struct ebt_counter *tmp;
1235 struct ebt_replace hlp;
1236 struct ebt_table *t;
1237
1238 if (copy_from_user(&hlp, user, sizeof(hlp)))
1239 return -EFAULT;
1240
1241 if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
1242 return -EINVAL;
1243 if (hlp.num_counters == 0)
1244 return -EINVAL;
1245
Jayachandran C18bc89a2006-04-20 00:14:49 -07001246 if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 MEMPRINT("Update_counters && nomemory\n");
1248 return -ENOMEM;
1249 }
1250
1251 t = find_table_lock(hlp.name, &ret, &ebt_mutex);
1252 if (!t)
1253 goto free_tmp;
1254
1255 if (hlp.num_counters != t->private->nentries) {
1256 BUGPRINT("Wrong nr of counters\n");
1257 ret = -EINVAL;
1258 goto unlock_mutex;
1259 }
1260
1261 if ( copy_from_user(tmp, hlp.counters,
1262 hlp.num_counters * sizeof(struct ebt_counter)) ) {
1263 BUGPRINT("Updata_counters && !cfu\n");
1264 ret = -EFAULT;
1265 goto unlock_mutex;
1266 }
1267
1268 /* we want an atomic add of the counters */
1269 write_lock_bh(&t->lock);
1270
1271 /* we add to the counters of the first cpu */
1272 for (i = 0; i < hlp.num_counters; i++) {
1273 t->private->counters[i].pcnt += tmp[i].pcnt;
1274 t->private->counters[i].bcnt += tmp[i].bcnt;
1275 }
1276
1277 write_unlock_bh(&t->lock);
1278 ret = 0;
1279unlock_mutex:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001280 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281free_tmp:
1282 vfree(tmp);
1283 return ret;
1284}
1285
1286static inline int ebt_make_matchname(struct ebt_entry_match *m,
1287 char *base, char *ubase)
1288{
1289 char *hlp = ubase - base + (char *)m;
1290 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
1291 return -EFAULT;
1292 return 0;
1293}
1294
1295static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
1296 char *base, char *ubase)
1297{
1298 char *hlp = ubase - base + (char *)w;
1299 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
1300 return -EFAULT;
1301 return 0;
1302}
1303
1304static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase)
1305{
1306 int ret;
1307 char *hlp;
1308 struct ebt_entry_target *t;
1309
1310 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
1311 return 0;
1312
1313 hlp = ubase - base + (char *)e + e->target_offset;
1314 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
1315
1316 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
1317 if (ret != 0)
1318 return ret;
1319 ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
1320 if (ret != 0)
1321 return ret;
1322 if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN))
1323 return -EFAULT;
1324 return 0;
1325}
1326
Ingo Molnar57b47a52006-03-20 22:35:41 -08001327/* called with ebt_mutex locked */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328static int copy_everything_to_user(struct ebt_table *t, void __user *user,
1329 int *len, int cmd)
1330{
1331 struct ebt_replace tmp;
1332 struct ebt_counter *counterstmp, *oldcounters;
1333 unsigned int entries_size, nentries;
1334 char *entries;
1335
1336 if (cmd == EBT_SO_GET_ENTRIES) {
1337 entries_size = t->private->entries_size;
1338 nentries = t->private->nentries;
1339 entries = t->private->entries;
1340 oldcounters = t->private->counters;
1341 } else {
1342 entries_size = t->table->entries_size;
1343 nentries = t->table->nentries;
1344 entries = t->table->entries;
1345 oldcounters = t->table->counters;
1346 }
1347
1348 if (copy_from_user(&tmp, user, sizeof(tmp))) {
1349 BUGPRINT("Cfu didn't work\n");
1350 return -EFAULT;
1351 }
1352
1353 if (*len != sizeof(struct ebt_replace) + entries_size +
1354 (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
1355 BUGPRINT("Wrong size\n");
1356 return -EINVAL;
1357 }
1358
1359 if (tmp.nentries != nentries) {
1360 BUGPRINT("Nentries wrong\n");
1361 return -EINVAL;
1362 }
1363
1364 if (tmp.entries_size != entries_size) {
1365 BUGPRINT("Wrong size\n");
1366 return -EINVAL;
1367 }
1368
1369 /* userspace might not need the counters */
1370 if (tmp.num_counters) {
1371 if (tmp.num_counters != nentries) {
1372 BUGPRINT("Num_counters wrong\n");
1373 return -EINVAL;
1374 }
Jayachandran C18bc89a2006-04-20 00:14:49 -07001375 counterstmp = vmalloc(nentries * sizeof(*counterstmp));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 if (!counterstmp) {
1377 MEMPRINT("Couldn't copy counters, out of memory\n");
1378 return -ENOMEM;
1379 }
1380 write_lock_bh(&t->lock);
1381 get_counters(oldcounters, counterstmp, nentries);
1382 write_unlock_bh(&t->lock);
1383
1384 if (copy_to_user(tmp.counters, counterstmp,
1385 nentries * sizeof(struct ebt_counter))) {
1386 BUGPRINT("Couldn't copy counters to userspace\n");
1387 vfree(counterstmp);
1388 return -EFAULT;
1389 }
1390 vfree(counterstmp);
1391 }
1392
1393 if (copy_to_user(tmp.entries, entries, entries_size)) {
1394 BUGPRINT("Couldn't copy entries to userspace\n");
1395 return -EFAULT;
1396 }
1397 /* set the match/watcher/target names right */
1398 return EBT_ENTRY_ITERATE(entries, entries_size,
1399 ebt_make_names, entries, tmp.entries);
1400}
1401
1402static int do_ebt_set_ctl(struct sock *sk,
1403 int cmd, void __user *user, unsigned int len)
1404{
1405 int ret;
1406
1407 switch(cmd) {
1408 case EBT_SO_SET_ENTRIES:
1409 ret = do_replace(user, len);
1410 break;
1411 case EBT_SO_SET_COUNTERS:
1412 ret = update_counters(user, len);
1413 break;
1414 default:
1415 ret = -EINVAL;
1416 }
1417 return ret;
1418}
1419
1420static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1421{
1422 int ret;
1423 struct ebt_replace tmp;
1424 struct ebt_table *t;
1425
1426 if (copy_from_user(&tmp, user, sizeof(tmp)))
1427 return -EFAULT;
1428
1429 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
1430 if (!t)
1431 return ret;
1432
1433 switch(cmd) {
1434 case EBT_SO_GET_INFO:
1435 case EBT_SO_GET_INIT_INFO:
1436 if (*len != sizeof(struct ebt_replace)){
1437 ret = -EINVAL;
Ingo Molnar57b47a52006-03-20 22:35:41 -08001438 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 break;
1440 }
1441 if (cmd == EBT_SO_GET_INFO) {
1442 tmp.nentries = t->private->nentries;
1443 tmp.entries_size = t->private->entries_size;
1444 tmp.valid_hooks = t->valid_hooks;
1445 } else {
1446 tmp.nentries = t->table->nentries;
1447 tmp.entries_size = t->table->entries_size;
1448 tmp.valid_hooks = t->table->valid_hooks;
1449 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001450 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 if (copy_to_user(user, &tmp, *len) != 0){
1452 BUGPRINT("c2u Didn't work\n");
1453 ret = -EFAULT;
1454 break;
1455 }
1456 ret = 0;
1457 break;
1458
1459 case EBT_SO_GET_ENTRIES:
1460 case EBT_SO_GET_INIT_ENTRIES:
1461 ret = copy_everything_to_user(t, user, len, cmd);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001462 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 break;
1464
1465 default:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001466 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 ret = -EINVAL;
1468 }
1469
1470 return ret;
1471}
1472
1473static struct nf_sockopt_ops ebt_sockopts =
Andrew Morton74ca4e5a2006-03-20 22:55:02 -08001474{
1475 .pf = PF_INET,
1476 .set_optmin = EBT_BASE_CTL,
1477 .set_optmax = EBT_SO_SET_MAX + 1,
1478 .set = do_ebt_set_ctl,
1479 .get_optmin = EBT_BASE_CTL,
1480 .get_optmax = EBT_SO_GET_MAX + 1,
1481 .get = do_ebt_get_ctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482};
1483
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001484static int __init ebtables_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485{
1486 int ret;
1487
Ingo Molnar57b47a52006-03-20 22:35:41 -08001488 mutex_lock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 list_named_insert(&ebt_targets, &ebt_standard_target);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001490 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
1492 return ret;
1493
1494 printk(KERN_NOTICE "Ebtables v2.0 registered\n");
1495 return 0;
1496}
1497
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001498static void __exit ebtables_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499{
1500 nf_unregister_sockopt(&ebt_sockopts);
1501 printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
1502}
1503
1504EXPORT_SYMBOL(ebt_register_table);
1505EXPORT_SYMBOL(ebt_unregister_table);
1506EXPORT_SYMBOL(ebt_register_match);
1507EXPORT_SYMBOL(ebt_unregister_match);
1508EXPORT_SYMBOL(ebt_register_watcher);
1509EXPORT_SYMBOL(ebt_unregister_watcher);
1510EXPORT_SYMBOL(ebt_register_target);
1511EXPORT_SYMBOL(ebt_unregister_target);
1512EXPORT_SYMBOL(ebt_do_table);
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001513module_init(ebtables_init);
1514module_exit(ebtables_fini);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515MODULE_LICENSE("GPL");