blob: 0dcebf20d6ce09fbbdd9fe414a28e238fd8f84ef [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>
Patrick McHardydf0933d2006-09-20 11:57:53 -070027#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <asm/uaccess.h>
29#include <linux/smp.h>
David S. Millerc8923c62005-10-13 14:41:23 -070030#include <linux/cpumask.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <net/sock.h>
32/* needed for logical [in,out]-dev filtering */
33#include "../br_private.h"
34
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\
36 "report to author: "format, ## args)
37/* #define BUGPRINT(format, args...) */
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\
39 ": out of memory: "format, ## args)
40/* #define MEMPRINT(format, args...) */
41
42
43
44/*
45 * Each cpu has its own set of counters, so there is no need for write_lock in
46 * the softirq
47 * For reading or updating the counters, the user context needs to
48 * get a write_lock
49 */
50
51/* The size of each set of counters is altered to get cache alignment */
52#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
53#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))
54#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \
55 COUNTER_OFFSET(n) * cpu))
56
57
58
Ingo Molnar57b47a52006-03-20 22:35:41 -080059static DEFINE_MUTEX(ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070060static LIST_HEAD(ebt_tables);
61static LIST_HEAD(ebt_targets);
62static LIST_HEAD(ebt_matches);
63static LIST_HEAD(ebt_watchers);
64
65static struct ebt_target ebt_standard_target =
66{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL};
67
68static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
69 const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in,
70 const struct net_device *out)
71{
72 w->u.watcher->watcher(skb, hooknr, in, out, w->data,
73 w->watcher_size);
74 /* watchers don't give a verdict */
75 return 0;
76}
77
78static inline int ebt_do_match (struct ebt_entry_match *m,
79 const struct sk_buff *skb, const struct net_device *in,
80 const struct net_device *out)
81{
82 return m->u.match->match(skb, in, out, m->data,
83 m->match_size);
84}
85
86static inline int ebt_dev_check(char *entry, const struct net_device *device)
87{
88 int i = 0;
Meelis Roos6f5b7ef2006-11-01 18:07:27 -080089 const char *devname = device->name;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
91 if (*entry == '\0')
92 return 0;
93 if (!device)
94 return 1;
95 /* 1 is the wildcard token */
96 while (entry[i] != '\0' && entry[i] != 1 && entry[i] == devname[i])
97 i++;
98 return (devname[i] != entry[i] && entry[i] != 1);
99}
100
101#define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg))
102/* process standard matches */
103static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
104 const struct net_device *in, const struct net_device *out)
105{
106 int verdict, i;
107
108 if (e->bitmask & EBT_802_3) {
109 if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO))
110 return 1;
111 } else if (!(e->bitmask & EBT_NOPROTO) &&
112 FWINV2(e->ethproto != h->h_proto, EBT_IPROTO))
113 return 1;
114
115 if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN))
116 return 1;
117 if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
118 return 1;
119 if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check(
120 e->logical_in, in->br_port->br->dev), EBT_ILOGICALIN))
121 return 1;
122 if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check(
123 e->logical_out, out->br_port->br->dev), EBT_ILOGICALOUT))
124 return 1;
125
126 if (e->bitmask & EBT_SOURCEMAC) {
127 verdict = 0;
128 for (i = 0; i < 6; i++)
129 verdict |= (h->h_source[i] ^ e->sourcemac[i]) &
130 e->sourcemsk[i];
131 if (FWINV2(verdict != 0, EBT_ISOURCE) )
132 return 1;
133 }
134 if (e->bitmask & EBT_DESTMAC) {
135 verdict = 0;
136 for (i = 0; i < 6; i++)
137 verdict |= (h->h_dest[i] ^ e->destmac[i]) &
138 e->destmsk[i];
139 if (FWINV2(verdict != 0, EBT_IDEST) )
140 return 1;
141 }
142 return 0;
143}
144
145/* Do some firewalling */
146unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
147 const struct net_device *in, const struct net_device *out,
148 struct ebt_table *table)
149{
150 int i, nentries;
151 struct ebt_entry *point;
152 struct ebt_counter *counter_base, *cb_base;
153 struct ebt_entry_target *t;
154 int verdict, sp = 0;
155 struct ebt_chainstack *cs;
156 struct ebt_entries *chaininfo;
157 char *base;
158 struct ebt_table_info *private;
159
160 read_lock_bh(&table->lock);
161 private = table->private;
162 cb_base = COUNTER_BASE(private->counters, private->nentries,
163 smp_processor_id());
164 if (private->chainstack)
165 cs = private->chainstack[smp_processor_id()];
166 else
167 cs = NULL;
168 chaininfo = private->hook_entry[hook];
169 nentries = private->hook_entry[hook]->nentries;
170 point = (struct ebt_entry *)(private->hook_entry[hook]->data);
171 counter_base = cb_base + private->hook_entry[hook]->counter_offset;
172 /* base for chain jumps */
173 base = private->entries;
174 i = 0;
175 while (i < nentries) {
176 if (ebt_basic_match(point, eth_hdr(*pskb), in, out))
177 goto letscontinue;
178
179 if (EBT_MATCH_ITERATE(point, ebt_do_match, *pskb, in, out) != 0)
180 goto letscontinue;
181
182 /* increase counter */
183 (*(counter_base + i)).pcnt++;
184 (*(counter_base + i)).bcnt+=(**pskb).len;
185
186 /* these should only watch: not modify, nor tell us
187 what to do with the packet */
188 EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, hook, in,
189 out);
190
191 t = (struct ebt_entry_target *)
192 (((char *)point) + point->target_offset);
193 /* standard target */
194 if (!t->u.target->target)
195 verdict = ((struct ebt_standard_target *)t)->verdict;
196 else
197 verdict = t->u.target->target(pskb, hook,
198 in, out, t->data, t->target_size);
199 if (verdict == EBT_ACCEPT) {
200 read_unlock_bh(&table->lock);
201 return NF_ACCEPT;
202 }
203 if (verdict == EBT_DROP) {
204 read_unlock_bh(&table->lock);
205 return NF_DROP;
206 }
207 if (verdict == EBT_RETURN) {
208letsreturn:
209#ifdef CONFIG_NETFILTER_DEBUG
210 if (sp == 0) {
211 BUGPRINT("RETURN on base chain");
212 /* act like this is EBT_CONTINUE */
213 goto letscontinue;
214 }
215#endif
216 sp--;
217 /* put all the local variables right */
218 i = cs[sp].n;
219 chaininfo = cs[sp].chaininfo;
220 nentries = chaininfo->nentries;
221 point = cs[sp].e;
222 counter_base = cb_base +
223 chaininfo->counter_offset;
224 continue;
225 }
226 if (verdict == EBT_CONTINUE)
227 goto letscontinue;
228#ifdef CONFIG_NETFILTER_DEBUG
229 if (verdict < 0) {
230 BUGPRINT("bogus standard verdict\n");
231 read_unlock_bh(&table->lock);
232 return NF_DROP;
233 }
234#endif
235 /* jump to a udc */
236 cs[sp].n = i + 1;
237 cs[sp].chaininfo = chaininfo;
238 cs[sp].e = (struct ebt_entry *)
239 (((char *)point) + point->next_offset);
240 i = 0;
241 chaininfo = (struct ebt_entries *) (base + verdict);
242#ifdef CONFIG_NETFILTER_DEBUG
243 if (chaininfo->distinguisher) {
244 BUGPRINT("jump to non-chain\n");
245 read_unlock_bh(&table->lock);
246 return NF_DROP;
247 }
248#endif
249 nentries = chaininfo->nentries;
250 point = (struct ebt_entry *)chaininfo->data;
251 counter_base = cb_base + chaininfo->counter_offset;
252 sp++;
253 continue;
254letscontinue:
255 point = (struct ebt_entry *)
256 (((char *)point) + point->next_offset);
257 i++;
258 }
259
260 /* I actually like this :) */
261 if (chaininfo->policy == EBT_RETURN)
262 goto letsreturn;
263 if (chaininfo->policy == EBT_ACCEPT) {
264 read_unlock_bh(&table->lock);
265 return NF_ACCEPT;
266 }
267 read_unlock_bh(&table->lock);
268 return NF_DROP;
269}
270
271/* If it succeeds, returns element and locks mutex */
272static inline void *
273find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
Ingo Molnar57b47a52006-03-20 22:35:41 -0800274 struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275{
Patrick McHardydf0933d2006-09-20 11:57:53 -0700276 struct {
277 struct list_head list;
278 char name[EBT_FUNCTION_MAXNAMELEN];
279 } *e;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280
Ingo Molnar57b47a52006-03-20 22:35:41 -0800281 *error = mutex_lock_interruptible(mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 if (*error != 0)
283 return NULL;
284
Patrick McHardydf0933d2006-09-20 11:57:53 -0700285 list_for_each_entry(e, head, list) {
286 if (strcmp(e->name, name) == 0)
287 return e;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 }
Patrick McHardydf0933d2006-09-20 11:57:53 -0700289 *error = -ENOENT;
290 mutex_unlock(mutex);
291 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292}
293
294#ifndef CONFIG_KMOD
295#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
296#else
297static void *
298find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
Ingo Molnar57b47a52006-03-20 22:35:41 -0800299 int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300{
301 void *ret;
302
303 ret = find_inlist_lock_noload(head, name, error, mutex);
304 if (!ret) {
305 request_module("%s%s", prefix, name);
306 ret = find_inlist_lock_noload(head, name, error, mutex);
307 }
308 return ret;
309}
310#endif
311
312static inline struct ebt_table *
Ingo Molnar57b47a52006-03-20 22:35:41 -0800313find_table_lock(const char *name, int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314{
315 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
316}
317
318static inline struct ebt_match *
Ingo Molnar57b47a52006-03-20 22:35:41 -0800319find_match_lock(const char *name, int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320{
321 return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
322}
323
324static inline struct ebt_watcher *
Ingo Molnar57b47a52006-03-20 22:35:41 -0800325find_watcher_lock(const char *name, int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326{
327 return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
328}
329
330static inline struct ebt_target *
Ingo Molnar57b47a52006-03-20 22:35:41 -0800331find_target_lock(const char *name, int *error, struct mutex *mutex)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332{
333 return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
334}
335
336static inline int
337ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
338 const char *name, unsigned int hookmask, unsigned int *cnt)
339{
340 struct ebt_match *match;
341 int ret;
342
343 if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) >
344 ((char *)e) + e->watchers_offset)
345 return -EINVAL;
346 match = find_match_lock(m->u.name, &ret, &ebt_mutex);
347 if (!match)
348 return ret;
349 m->u.match = match;
350 if (!try_module_get(match->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800351 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 return -ENOENT;
353 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800354 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 if (match->check &&
356 match->check(name, hookmask, e, m->data, m->match_size) != 0) {
357 BUGPRINT("match->check failed\n");
358 module_put(match->me);
359 return -EINVAL;
360 }
361 (*cnt)++;
362 return 0;
363}
364
365static inline int
366ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
367 const char *name, unsigned int hookmask, unsigned int *cnt)
368{
369 struct ebt_watcher *watcher;
370 int ret;
371
372 if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) >
373 ((char *)e) + e->target_offset)
374 return -EINVAL;
375 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
376 if (!watcher)
377 return ret;
378 w->u.watcher = watcher;
379 if (!try_module_get(watcher->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800380 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 return -ENOENT;
382 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800383 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 if (watcher->check &&
385 watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) {
386 BUGPRINT("watcher->check failed\n");
387 module_put(watcher->me);
388 return -EINVAL;
389 }
390 (*cnt)++;
391 return 0;
392}
393
394/*
395 * this one is very careful, as it is the first function
396 * to parse the userspace data
397 */
398static inline int
399ebt_check_entry_size_and_hooks(struct ebt_entry *e,
400 struct ebt_table_info *newinfo, char *base, char *limit,
401 struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt,
402 unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks)
403{
Al Virobb2ef252006-11-30 19:22:42 -0800404 unsigned int offset = (char *)e - newinfo->entries;
405 size_t left = (limit - base) - offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 int i;
407
Al Virobb2ef252006-11-30 19:22:42 -0800408 if (left < sizeof(unsigned int))
409 goto Esmall;
410
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
412 if ((valid_hooks & (1 << i)) == 0)
413 continue;
Al Virobb2ef252006-11-30 19:22:42 -0800414 if ((char *)hook_entries[i] == base + offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 break;
416 }
417 /* beginning of a new chain
418 if i == NF_BR_NUMHOOKS it must be a user defined chain */
419 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
420 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) {
421 /* we make userspace set this right,
422 so there is no misunderstanding */
423 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
424 "in distinguisher\n");
425 return -EINVAL;
426 }
427 /* this checks if the previous chain has as many entries
428 as it said it has */
429 if (*n != *cnt) {
430 BUGPRINT("nentries does not equal the nr of entries "
431 "in the chain\n");
432 return -EINVAL;
433 }
434 /* before we look at the struct, be sure it is not too big */
Al Virobb2ef252006-11-30 19:22:42 -0800435 if (left < sizeof(struct ebt_entries))
436 goto Esmall;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 if (((struct ebt_entries *)e)->policy != EBT_DROP &&
438 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
439 /* only RETURN from udc */
440 if (i != NF_BR_NUMHOOKS ||
441 ((struct ebt_entries *)e)->policy != EBT_RETURN) {
442 BUGPRINT("bad policy\n");
443 return -EINVAL;
444 }
445 }
446 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
447 (*udc_cnt)++;
448 else
449 newinfo->hook_entry[i] = (struct ebt_entries *)e;
450 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
451 BUGPRINT("counter_offset != totalcnt");
452 return -EINVAL;
453 }
454 *n = ((struct ebt_entries *)e)->nentries;
455 *cnt = 0;
456 return 0;
457 }
458 /* a plain old entry, heh */
Al Virobb2ef252006-11-30 19:22:42 -0800459 if (left < sizeof(struct ebt_entry))
460 goto Esmall;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 if (sizeof(struct ebt_entry) > e->watchers_offset ||
462 e->watchers_offset > e->target_offset ||
463 e->target_offset >= e->next_offset) {
464 BUGPRINT("entry offsets not in right order\n");
465 return -EINVAL;
466 }
467 /* this is not checked anywhere else */
468 if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) {
469 BUGPRINT("target size too small\n");
470 return -EINVAL;
471 }
Al Virobb2ef252006-11-30 19:22:42 -0800472 if (left < e->next_offset)
473 goto Esmall;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474
475 (*cnt)++;
476 (*totalcnt)++;
477 return 0;
Al Virobb2ef252006-11-30 19:22:42 -0800478
479Esmall:
480 BUGPRINT("entries_size too small\n");
481 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482}
483
484struct ebt_cl_stack
485{
486 struct ebt_chainstack cs;
487 int from;
488 unsigned int hookmask;
489};
490
491/*
492 * we need these positions to check that the jumps to a different part of the
493 * entries is a jump to the beginning of a new chain.
494 */
495static inline int
496ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
497 struct ebt_entries **hook_entries, unsigned int *n, unsigned int valid_hooks,
498 struct ebt_cl_stack *udc)
499{
500 int i;
501
502 /* we're only interested in chain starts */
503 if (e->bitmask & EBT_ENTRY_OR_ENTRIES)
504 return 0;
505 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
506 if ((valid_hooks & (1 << i)) == 0)
507 continue;
508 if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
509 break;
510 }
511 /* only care about udc */
512 if (i != NF_BR_NUMHOOKS)
513 return 0;
514
515 udc[*n].cs.chaininfo = (struct ebt_entries *)e;
516 /* these initialisations are depended on later in check_chainloops() */
517 udc[*n].cs.n = 0;
518 udc[*n].hookmask = 0;
519
520 (*n)++;
521 return 0;
522}
523
524static inline int
525ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
526{
527 if (i && (*i)-- == 0)
528 return 1;
529 if (m->u.match->destroy)
530 m->u.match->destroy(m->data, m->match_size);
531 module_put(m->u.match->me);
532
533 return 0;
534}
535
536static inline int
537ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
538{
539 if (i && (*i)-- == 0)
540 return 1;
541 if (w->u.watcher->destroy)
542 w->u.watcher->destroy(w->data, w->watcher_size);
543 module_put(w->u.watcher->me);
544
545 return 0;
546}
547
548static inline int
549ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
550{
551 struct ebt_entry_target *t;
552
553 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
554 return 0;
555 /* we're done */
556 if (cnt && (*cnt)-- == 0)
557 return 1;
558 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
559 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
560 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
561 if (t->u.target->destroy)
562 t->u.target->destroy(t->data, t->target_size);
563 module_put(t->u.target->me);
564
565 return 0;
566}
567
568static inline int
569ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
570 const char *name, unsigned int *cnt, unsigned int valid_hooks,
571 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
572{
573 struct ebt_entry_target *t;
574 struct ebt_target *target;
575 unsigned int i, j, hook = 0, hookmask = 0;
576 int ret;
577
578 /* don't mess with the struct ebt_entries */
579 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
580 return 0;
581
582 if (e->bitmask & ~EBT_F_MASK) {
583 BUGPRINT("Unknown flag for bitmask\n");
584 return -EINVAL;
585 }
586 if (e->invflags & ~EBT_INV_MASK) {
587 BUGPRINT("Unknown flag for inv bitmask\n");
588 return -EINVAL;
589 }
590 if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) {
591 BUGPRINT("NOPROTO & 802_3 not allowed\n");
592 return -EINVAL;
593 }
594 /* what hook do we belong to? */
595 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
596 if ((valid_hooks & (1 << i)) == 0)
597 continue;
598 if ((char *)newinfo->hook_entry[i] < (char *)e)
599 hook = i;
600 else
601 break;
602 }
603 /* (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on
604 a base chain */
605 if (i < NF_BR_NUMHOOKS)
606 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
607 else {
608 for (i = 0; i < udc_cnt; i++)
609 if ((char *)(cl_s[i].cs.chaininfo) > (char *)e)
610 break;
611 if (i == 0)
612 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
613 else
614 hookmask = cl_s[i - 1].hookmask;
615 }
616 i = 0;
617 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
618 if (ret != 0)
619 goto cleanup_matches;
620 j = 0;
621 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
622 if (ret != 0)
623 goto cleanup_watchers;
624 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
625 target = find_target_lock(t->u.name, &ret, &ebt_mutex);
626 if (!target)
627 goto cleanup_watchers;
628 if (!try_module_get(target->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800629 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 ret = -ENOENT;
631 goto cleanup_watchers;
632 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800633 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
635 t->u.target = target;
636 if (t->u.target == &ebt_standard_target) {
637 if (e->target_offset + sizeof(struct ebt_standard_target) >
638 e->next_offset) {
639 BUGPRINT("Standard target size too big\n");
640 ret = -EFAULT;
641 goto cleanup_watchers;
642 }
643 if (((struct ebt_standard_target *)t)->verdict <
644 -NUM_STANDARD_TARGETS) {
645 BUGPRINT("Invalid standard target\n");
646 ret = -EFAULT;
647 goto cleanup_watchers;
648 }
649 } else if ((e->target_offset + t->target_size +
650 sizeof(struct ebt_entry_target) > e->next_offset) ||
651 (t->u.target->check &&
652 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
653 module_put(t->u.target->me);
654 ret = -EFAULT;
655 goto cleanup_watchers;
656 }
657 (*cnt)++;
658 return 0;
659cleanup_watchers:
660 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j);
661cleanup_matches:
662 EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i);
663 return ret;
664}
665
666/*
667 * checks for loops and sets the hook mask for udc
668 * the hook mask for udc tells us from which base chains the udc can be
669 * accessed. This mask is a parameter to the check() functions of the extensions
670 */
671static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s,
672 unsigned int udc_cnt, unsigned int hooknr, char *base)
673{
674 int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict;
675 struct ebt_entry *e = (struct ebt_entry *)chain->data;
676 struct ebt_entry_target *t;
677
678 while (pos < nentries || chain_nr != -1) {
679 /* end of udc, go back one 'recursion' step */
680 if (pos == nentries) {
681 /* put back values of the time when this chain was called */
682 e = cl_s[chain_nr].cs.e;
683 if (cl_s[chain_nr].from != -1)
684 nentries =
685 cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries;
686 else
687 nentries = chain->nentries;
688 pos = cl_s[chain_nr].cs.n;
689 /* make sure we won't see a loop that isn't one */
690 cl_s[chain_nr].cs.n = 0;
691 chain_nr = cl_s[chain_nr].from;
692 if (pos == nentries)
693 continue;
694 }
695 t = (struct ebt_entry_target *)
696 (((char *)e) + e->target_offset);
697 if (strcmp(t->u.name, EBT_STANDARD_TARGET))
698 goto letscontinue;
699 if (e->target_offset + sizeof(struct ebt_standard_target) >
700 e->next_offset) {
701 BUGPRINT("Standard target size too big\n");
702 return -1;
703 }
704 verdict = ((struct ebt_standard_target *)t)->verdict;
705 if (verdict >= 0) { /* jump to another chain */
706 struct ebt_entries *hlp2 =
707 (struct ebt_entries *)(base + verdict);
708 for (i = 0; i < udc_cnt; i++)
709 if (hlp2 == cl_s[i].cs.chaininfo)
710 break;
711 /* bad destination or loop */
712 if (i == udc_cnt) {
713 BUGPRINT("bad destination\n");
714 return -1;
715 }
716 if (cl_s[i].cs.n) {
717 BUGPRINT("loop\n");
718 return -1;
719 }
720 /* this can't be 0, so the above test is correct */
721 cl_s[i].cs.n = pos + 1;
722 pos = 0;
723 cl_s[i].cs.e = ((void *)e + e->next_offset);
724 e = (struct ebt_entry *)(hlp2->data);
725 nentries = hlp2->nentries;
726 cl_s[i].from = chain_nr;
727 chain_nr = i;
728 /* this udc is accessible from the base chain for hooknr */
729 cl_s[i].hookmask |= (1 << hooknr);
730 continue;
731 }
732letscontinue:
733 e = (void *)e + e->next_offset;
734 pos++;
735 }
736 return 0;
737}
738
739/* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
740static int translate_table(struct ebt_replace *repl,
741 struct ebt_table_info *newinfo)
742{
743 unsigned int i, j, k, udc_cnt;
744 int ret;
745 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
746
747 i = 0;
748 while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i)))
749 i++;
750 if (i == NF_BR_NUMHOOKS) {
751 BUGPRINT("No valid hooks specified\n");
752 return -EINVAL;
753 }
754 if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) {
755 BUGPRINT("Chains don't start at beginning\n");
756 return -EINVAL;
757 }
758 /* make sure chains are ordered after each other in same order
759 as their corresponding hooks */
760 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
761 if (!(repl->valid_hooks & (1 << j)))
762 continue;
763 if ( repl->hook_entry[j] <= repl->hook_entry[i] ) {
764 BUGPRINT("Hook order must be followed\n");
765 return -EINVAL;
766 }
767 i = j;
768 }
769
770 for (i = 0; i < NF_BR_NUMHOOKS; i++)
771 newinfo->hook_entry[i] = NULL;
772
773 newinfo->entries_size = repl->entries_size;
774 newinfo->nentries = repl->nentries;
775
776 /* do some early checkings and initialize some things */
777 i = 0; /* holds the expected nr. of entries for the chain */
778 j = 0; /* holds the up to now counted entries for the chain */
779 k = 0; /* holds the total nr. of entries, should equal
780 newinfo->nentries afterwards */
781 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
782 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
783 ebt_check_entry_size_and_hooks, newinfo, repl->entries,
784 repl->entries + repl->entries_size, repl->hook_entry, &i, &j, &k,
785 &udc_cnt, repl->valid_hooks);
786
787 if (ret != 0)
788 return ret;
789
790 if (i != j) {
791 BUGPRINT("nentries does not equal the nr of entries in the "
792 "(last) chain\n");
793 return -EINVAL;
794 }
795 if (k != newinfo->nentries) {
796 BUGPRINT("Total nentries is wrong\n");
797 return -EINVAL;
798 }
799
800 /* check if all valid hooks have a chain */
801 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
802 if (newinfo->hook_entry[i] == NULL &&
803 (repl->valid_hooks & (1 << i))) {
804 BUGPRINT("Valid hook without chain\n");
805 return -EINVAL;
806 }
807 }
808
809 /* get the location of the udc, put them in an array
810 while we're at it, allocate the chainstack */
811 if (udc_cnt) {
812 /* this will get free'd in do_replace()/ebt_register_table()
813 if an error occurs */
Jayachandran C7ad4d2f2006-04-11 17:25:38 -0700814 newinfo->chainstack =
815 vmalloc((highest_possible_processor_id()+1)
816 * sizeof(*(newinfo->chainstack)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 if (!newinfo->chainstack)
818 return -ENOMEM;
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -0700819 for_each_possible_cpu(i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 newinfo->chainstack[i] =
Jayachandran C18bc89a2006-04-20 00:14:49 -0700821 vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0])));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 if (!newinfo->chainstack[i]) {
823 while (i)
824 vfree(newinfo->chainstack[--i]);
825 vfree(newinfo->chainstack);
826 newinfo->chainstack = NULL;
827 return -ENOMEM;
828 }
829 }
830
Jayachandran C18bc89a2006-04-20 00:14:49 -0700831 cl_s = vmalloc(udc_cnt * sizeof(*cl_s));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 if (!cl_s)
833 return -ENOMEM;
834 i = 0; /* the i'th udc */
835 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
836 ebt_get_udc_positions, newinfo, repl->hook_entry, &i,
837 repl->valid_hooks, cl_s);
838 /* sanity check */
839 if (i != udc_cnt) {
840 BUGPRINT("i != udc_cnt\n");
841 vfree(cl_s);
842 return -EFAULT;
843 }
844 }
845
846 /* Check for loops */
847 for (i = 0; i < NF_BR_NUMHOOKS; i++)
848 if (repl->valid_hooks & (1 << i))
849 if (check_chainloops(newinfo->hook_entry[i],
850 cl_s, udc_cnt, i, newinfo->entries)) {
James Lamanna68d31872005-06-22 22:12:57 -0700851 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 return -EINVAL;
853 }
854
855 /* we now know the following (along with E=mc²):
856 - the nr of entries in each chain is right
857 - the size of the allocated space is right
858 - all valid hooks have a corresponding chain
859 - there are no loops
860 - wrong data can still be on the level of a single entry
861 - could be there are jumps to places that are not the
862 beginning of a chain. This can only occur in chains that
863 are not accessible from any base chains, so we don't care. */
864
865 /* used to know what we need to clean up if something goes wrong */
866 i = 0;
867 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
868 ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks,
869 cl_s, udc_cnt);
870 if (ret != 0) {
871 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
872 ebt_cleanup_entry, &i);
873 }
James Lamanna68d31872005-06-22 22:12:57 -0700874 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 return ret;
876}
877
878/* called under write_lock */
879static void get_counters(struct ebt_counter *oldcounters,
880 struct ebt_counter *counters, unsigned int nentries)
881{
882 int i, cpu;
883 struct ebt_counter *counter_base;
884
885 /* counters of cpu 0 */
886 memcpy(counters, oldcounters,
David S. Millerc8923c62005-10-13 14:41:23 -0700887 sizeof(struct ebt_counter) * nentries);
888
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 /* add other counters to those of cpu 0 */
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -0700890 for_each_possible_cpu(cpu) {
David S. Millerc8923c62005-10-13 14:41:23 -0700891 if (cpu == 0)
892 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
894 for (i = 0; i < nentries; i++) {
895 counters[i].pcnt += counter_base[i].pcnt;
896 counters[i].bcnt += counter_base[i].bcnt;
897 }
898 }
899}
900
901/* replace the table */
902static int do_replace(void __user *user, unsigned int len)
903{
904 int ret, i, countersize;
905 struct ebt_table_info *newinfo;
906 struct ebt_replace tmp;
907 struct ebt_table *t;
908 struct ebt_counter *counterstmp = NULL;
909 /* used to be able to unlock earlier */
910 struct ebt_table_info *table;
911
912 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
913 return -EFAULT;
914
915 if (len != sizeof(tmp) + tmp.entries_size) {
916 BUGPRINT("Wrong len argument\n");
917 return -EINVAL;
918 }
919
920 if (tmp.entries_size == 0) {
921 BUGPRINT("Entries_size never zero\n");
922 return -EINVAL;
923 }
Kirill Korotaevee4bb812006-02-04 02:16:56 -0800924 /* overflow check */
925 if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
926 SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
927 return -ENOMEM;
928 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
929 return -ENOMEM;
930
David S. Millerc8923c62005-10-13 14:41:23 -0700931 countersize = COUNTER_OFFSET(tmp.nentries) *
932 (highest_possible_processor_id()+1);
Jayachandran C18bc89a2006-04-20 00:14:49 -0700933 newinfo = vmalloc(sizeof(*newinfo) + countersize);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 if (!newinfo)
935 return -ENOMEM;
936
937 if (countersize)
938 memset(newinfo->counters, 0, countersize);
939
Kris Katterjohn8b3a7002006-01-11 15:56:43 -0800940 newinfo->entries = vmalloc(tmp.entries_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941 if (!newinfo->entries) {
942 ret = -ENOMEM;
943 goto free_newinfo;
944 }
945 if (copy_from_user(
946 newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
947 BUGPRINT("Couldn't copy entries from userspace\n");
948 ret = -EFAULT;
949 goto free_entries;
950 }
951
952 /* the user wants counters back
953 the check on the size is done later, when we have the lock */
954 if (tmp.num_counters) {
Jayachandran C18bc89a2006-04-20 00:14:49 -0700955 counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 if (!counterstmp) {
957 ret = -ENOMEM;
958 goto free_entries;
959 }
960 }
961 else
962 counterstmp = NULL;
963
964 /* this can get initialized by translate_table() */
965 newinfo->chainstack = NULL;
966 ret = translate_table(&tmp, newinfo);
967
968 if (ret != 0)
969 goto free_counterstmp;
970
971 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
972 if (!t) {
973 ret = -ENOENT;
974 goto free_iterate;
975 }
976
977 /* the table doesn't like it */
978 if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
979 goto free_unlock;
980
981 if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
982 BUGPRINT("Wrong nr. of counters requested\n");
983 ret = -EINVAL;
984 goto free_unlock;
985 }
986
987 /* we have the mutex lock, so no danger in reading this pointer */
988 table = t->private;
989 /* make sure the table can only be rmmod'ed if it contains no rules */
990 if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
991 ret = -ENOENT;
992 goto free_unlock;
993 } else if (table->nentries && !newinfo->nentries)
994 module_put(t->me);
995 /* we need an atomic snapshot of the counters */
996 write_lock_bh(&t->lock);
997 if (tmp.num_counters)
998 get_counters(t->private->counters, counterstmp,
999 t->private->nentries);
1000
1001 t->private = newinfo;
1002 write_unlock_bh(&t->lock);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001003 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 /* so, a user can change the chains while having messed up her counter
1005 allocation. Only reason why this is done is because this way the lock
1006 is held only once, while this doesn't bring the kernel into a
1007 dangerous state. */
1008 if (tmp.num_counters &&
1009 copy_to_user(tmp.counters, counterstmp,
1010 tmp.num_counters * sizeof(struct ebt_counter))) {
1011 BUGPRINT("Couldn't copy counters to userspace\n");
1012 ret = -EFAULT;
1013 }
1014 else
1015 ret = 0;
1016
1017 /* decrease module count and free resources */
1018 EBT_ENTRY_ITERATE(table->entries, table->entries_size,
1019 ebt_cleanup_entry, NULL);
1020
1021 vfree(table->entries);
1022 if (table->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001023 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 vfree(table->chainstack[i]);
1025 vfree(table->chainstack);
1026 }
1027 vfree(table);
1028
James Lamanna68d31872005-06-22 22:12:57 -07001029 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 return ret;
1031
1032free_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001033 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034free_iterate:
1035 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1036 ebt_cleanup_entry, NULL);
1037free_counterstmp:
James Lamanna68d31872005-06-22 22:12:57 -07001038 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 /* can be initialized in translate_table() */
1040 if (newinfo->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001041 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 vfree(newinfo->chainstack[i]);
1043 vfree(newinfo->chainstack);
1044 }
1045free_entries:
James Lamanna68d31872005-06-22 22:12:57 -07001046 vfree(newinfo->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047free_newinfo:
James Lamanna68d31872005-06-22 22:12:57 -07001048 vfree(newinfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 return ret;
1050}
1051
1052int ebt_register_target(struct ebt_target *target)
1053{
Patrick McHardydf0933d2006-09-20 11:57:53 -07001054 struct ebt_target *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 int ret;
1056
Ingo Molnar57b47a52006-03-20 22:35:41 -08001057 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 if (ret != 0)
1059 return ret;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001060 list_for_each_entry(t, &ebt_targets, list) {
1061 if (strcmp(t->name, target->name) == 0) {
1062 mutex_unlock(&ebt_mutex);
1063 return -EEXIST;
1064 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001066 list_add(&target->list, &ebt_targets);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001067 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
1069 return 0;
1070}
1071
1072void ebt_unregister_target(struct ebt_target *target)
1073{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001074 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001075 list_del(&target->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001076 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077}
1078
1079int ebt_register_match(struct ebt_match *match)
1080{
Patrick McHardydf0933d2006-09-20 11:57:53 -07001081 struct ebt_match *m;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 int ret;
1083
Ingo Molnar57b47a52006-03-20 22:35:41 -08001084 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 if (ret != 0)
1086 return ret;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001087 list_for_each_entry(m, &ebt_matches, list) {
1088 if (strcmp(m->name, match->name) == 0) {
1089 mutex_unlock(&ebt_mutex);
1090 return -EEXIST;
1091 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001093 list_add(&match->list, &ebt_matches);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001094 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
1096 return 0;
1097}
1098
1099void ebt_unregister_match(struct ebt_match *match)
1100{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001101 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001102 list_del(&match->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001103 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104}
1105
1106int ebt_register_watcher(struct ebt_watcher *watcher)
1107{
Patrick McHardydf0933d2006-09-20 11:57:53 -07001108 struct ebt_watcher *w;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 int ret;
1110
Ingo Molnar57b47a52006-03-20 22:35:41 -08001111 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 if (ret != 0)
1113 return ret;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001114 list_for_each_entry(w, &ebt_watchers, list) {
1115 if (strcmp(w->name, watcher->name) == 0) {
1116 mutex_unlock(&ebt_mutex);
1117 return -EEXIST;
1118 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001120 list_add(&watcher->list, &ebt_watchers);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001121 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122
1123 return 0;
1124}
1125
1126void ebt_unregister_watcher(struct ebt_watcher *watcher)
1127{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001128 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001129 list_del(&watcher->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001130 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131}
1132
1133int ebt_register_table(struct ebt_table *table)
1134{
1135 struct ebt_table_info *newinfo;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001136 struct ebt_table *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 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
Patrick McHardydf0933d2006-09-20 11:57:53 -07001182 list_for_each_entry(t, &ebt_tables, list) {
1183 if (strcmp(t->name, table->name) == 0) {
1184 ret = -EEXIST;
1185 BUGPRINT("Table name already exists\n");
1186 goto free_unlock;
1187 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188 }
1189
1190 /* Hold a reference count if the chains aren't empty */
1191 if (newinfo->nentries && !try_module_get(table->me)) {
1192 ret = -ENOENT;
1193 goto free_unlock;
1194 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001195 list_add(&table->list, &ebt_tables);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001196 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 return 0;
1198free_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001199 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200free_chainstack:
1201 if (newinfo->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001202 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 vfree(newinfo->chainstack[i]);
1204 vfree(newinfo->chainstack);
1205 }
1206 vfree(newinfo->entries);
1207free_newinfo:
1208 vfree(newinfo);
1209 return ret;
1210}
1211
1212void ebt_unregister_table(struct ebt_table *table)
1213{
1214 int i;
1215
1216 if (!table) {
1217 BUGPRINT("Request to unregister NULL table!!!\n");
1218 return;
1219 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001220 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001221 list_del(&table->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001222 mutex_unlock(&ebt_mutex);
James Lamanna68d31872005-06-22 22:12:57 -07001223 vfree(table->private->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 if (table->private->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001225 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 vfree(table->private->chainstack[i]);
1227 vfree(table->private->chainstack);
1228 }
1229 vfree(table->private);
1230}
1231
1232/* userspace just supplied us with counters */
1233static int update_counters(void __user *user, unsigned int len)
1234{
1235 int i, ret;
1236 struct ebt_counter *tmp;
1237 struct ebt_replace hlp;
1238 struct ebt_table *t;
1239
1240 if (copy_from_user(&hlp, user, sizeof(hlp)))
1241 return -EFAULT;
1242
1243 if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
1244 return -EINVAL;
1245 if (hlp.num_counters == 0)
1246 return -EINVAL;
1247
Jayachandran C18bc89a2006-04-20 00:14:49 -07001248 if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 MEMPRINT("Update_counters && nomemory\n");
1250 return -ENOMEM;
1251 }
1252
1253 t = find_table_lock(hlp.name, &ret, &ebt_mutex);
1254 if (!t)
1255 goto free_tmp;
1256
1257 if (hlp.num_counters != t->private->nentries) {
1258 BUGPRINT("Wrong nr of counters\n");
1259 ret = -EINVAL;
1260 goto unlock_mutex;
1261 }
1262
1263 if ( copy_from_user(tmp, hlp.counters,
1264 hlp.num_counters * sizeof(struct ebt_counter)) ) {
1265 BUGPRINT("Updata_counters && !cfu\n");
1266 ret = -EFAULT;
1267 goto unlock_mutex;
1268 }
1269
1270 /* we want an atomic add of the counters */
1271 write_lock_bh(&t->lock);
1272
1273 /* we add to the counters of the first cpu */
1274 for (i = 0; i < hlp.num_counters; i++) {
1275 t->private->counters[i].pcnt += tmp[i].pcnt;
1276 t->private->counters[i].bcnt += tmp[i].bcnt;
1277 }
1278
1279 write_unlock_bh(&t->lock);
1280 ret = 0;
1281unlock_mutex:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001282 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283free_tmp:
1284 vfree(tmp);
1285 return ret;
1286}
1287
1288static inline int ebt_make_matchname(struct ebt_entry_match *m,
1289 char *base, char *ubase)
1290{
1291 char *hlp = ubase - base + (char *)m;
1292 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
1293 return -EFAULT;
1294 return 0;
1295}
1296
1297static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
1298 char *base, char *ubase)
1299{
1300 char *hlp = ubase - base + (char *)w;
1301 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
1302 return -EFAULT;
1303 return 0;
1304}
1305
1306static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase)
1307{
1308 int ret;
1309 char *hlp;
1310 struct ebt_entry_target *t;
1311
1312 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
1313 return 0;
1314
1315 hlp = ubase - base + (char *)e + e->target_offset;
1316 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
1317
1318 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
1319 if (ret != 0)
1320 return ret;
1321 ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
1322 if (ret != 0)
1323 return ret;
1324 if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN))
1325 return -EFAULT;
1326 return 0;
1327}
1328
Ingo Molnar57b47a52006-03-20 22:35:41 -08001329/* called with ebt_mutex locked */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330static int copy_everything_to_user(struct ebt_table *t, void __user *user,
1331 int *len, int cmd)
1332{
1333 struct ebt_replace tmp;
1334 struct ebt_counter *counterstmp, *oldcounters;
1335 unsigned int entries_size, nentries;
1336 char *entries;
1337
1338 if (cmd == EBT_SO_GET_ENTRIES) {
1339 entries_size = t->private->entries_size;
1340 nentries = t->private->nentries;
1341 entries = t->private->entries;
1342 oldcounters = t->private->counters;
1343 } else {
1344 entries_size = t->table->entries_size;
1345 nentries = t->table->nentries;
1346 entries = t->table->entries;
1347 oldcounters = t->table->counters;
1348 }
1349
1350 if (copy_from_user(&tmp, user, sizeof(tmp))) {
1351 BUGPRINT("Cfu didn't work\n");
1352 return -EFAULT;
1353 }
1354
1355 if (*len != sizeof(struct ebt_replace) + entries_size +
1356 (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
1357 BUGPRINT("Wrong size\n");
1358 return -EINVAL;
1359 }
1360
1361 if (tmp.nentries != nentries) {
1362 BUGPRINT("Nentries wrong\n");
1363 return -EINVAL;
1364 }
1365
1366 if (tmp.entries_size != entries_size) {
1367 BUGPRINT("Wrong size\n");
1368 return -EINVAL;
1369 }
1370
1371 /* userspace might not need the counters */
1372 if (tmp.num_counters) {
1373 if (tmp.num_counters != nentries) {
1374 BUGPRINT("Num_counters wrong\n");
1375 return -EINVAL;
1376 }
Jayachandran C18bc89a2006-04-20 00:14:49 -07001377 counterstmp = vmalloc(nentries * sizeof(*counterstmp));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 if (!counterstmp) {
1379 MEMPRINT("Couldn't copy counters, out of memory\n");
1380 return -ENOMEM;
1381 }
1382 write_lock_bh(&t->lock);
1383 get_counters(oldcounters, counterstmp, nentries);
1384 write_unlock_bh(&t->lock);
1385
1386 if (copy_to_user(tmp.counters, counterstmp,
1387 nentries * sizeof(struct ebt_counter))) {
1388 BUGPRINT("Couldn't copy counters to userspace\n");
1389 vfree(counterstmp);
1390 return -EFAULT;
1391 }
1392 vfree(counterstmp);
1393 }
1394
1395 if (copy_to_user(tmp.entries, entries, entries_size)) {
1396 BUGPRINT("Couldn't copy entries to userspace\n");
1397 return -EFAULT;
1398 }
1399 /* set the match/watcher/target names right */
1400 return EBT_ENTRY_ITERATE(entries, entries_size,
1401 ebt_make_names, entries, tmp.entries);
1402}
1403
1404static int do_ebt_set_ctl(struct sock *sk,
1405 int cmd, void __user *user, unsigned int len)
1406{
1407 int ret;
1408
1409 switch(cmd) {
1410 case EBT_SO_SET_ENTRIES:
1411 ret = do_replace(user, len);
1412 break;
1413 case EBT_SO_SET_COUNTERS:
1414 ret = update_counters(user, len);
1415 break;
1416 default:
1417 ret = -EINVAL;
1418 }
1419 return ret;
1420}
1421
1422static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1423{
1424 int ret;
1425 struct ebt_replace tmp;
1426 struct ebt_table *t;
1427
1428 if (copy_from_user(&tmp, user, sizeof(tmp)))
1429 return -EFAULT;
1430
1431 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
1432 if (!t)
1433 return ret;
1434
1435 switch(cmd) {
1436 case EBT_SO_GET_INFO:
1437 case EBT_SO_GET_INIT_INFO:
1438 if (*len != sizeof(struct ebt_replace)){
1439 ret = -EINVAL;
Ingo Molnar57b47a52006-03-20 22:35:41 -08001440 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 break;
1442 }
1443 if (cmd == EBT_SO_GET_INFO) {
1444 tmp.nentries = t->private->nentries;
1445 tmp.entries_size = t->private->entries_size;
1446 tmp.valid_hooks = t->valid_hooks;
1447 } else {
1448 tmp.nentries = t->table->nentries;
1449 tmp.entries_size = t->table->entries_size;
1450 tmp.valid_hooks = t->table->valid_hooks;
1451 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001452 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 if (copy_to_user(user, &tmp, *len) != 0){
1454 BUGPRINT("c2u Didn't work\n");
1455 ret = -EFAULT;
1456 break;
1457 }
1458 ret = 0;
1459 break;
1460
1461 case EBT_SO_GET_ENTRIES:
1462 case EBT_SO_GET_INIT_ENTRIES:
1463 ret = copy_everything_to_user(t, user, len, cmd);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001464 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 break;
1466
1467 default:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001468 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 ret = -EINVAL;
1470 }
1471
1472 return ret;
1473}
1474
1475static struct nf_sockopt_ops ebt_sockopts =
Andrew Morton74ca4e5a2006-03-20 22:55:02 -08001476{
1477 .pf = PF_INET,
1478 .set_optmin = EBT_BASE_CTL,
1479 .set_optmax = EBT_SO_SET_MAX + 1,
1480 .set = do_ebt_set_ctl,
1481 .get_optmin = EBT_BASE_CTL,
1482 .get_optmax = EBT_SO_GET_MAX + 1,
1483 .get = do_ebt_get_ctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484};
1485
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001486static int __init ebtables_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487{
1488 int ret;
1489
Ingo Molnar57b47a52006-03-20 22:35:41 -08001490 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001491 list_add(&ebt_standard_target.list, &ebt_targets);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001492 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
1494 return ret;
1495
1496 printk(KERN_NOTICE "Ebtables v2.0 registered\n");
1497 return 0;
1498}
1499
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001500static void __exit ebtables_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501{
1502 nf_unregister_sockopt(&ebt_sockopts);
1503 printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
1504}
1505
1506EXPORT_SYMBOL(ebt_register_table);
1507EXPORT_SYMBOL(ebt_unregister_table);
1508EXPORT_SYMBOL(ebt_register_match);
1509EXPORT_SYMBOL(ebt_unregister_match);
1510EXPORT_SYMBOL(ebt_register_watcher);
1511EXPORT_SYMBOL(ebt_unregister_watcher);
1512EXPORT_SYMBOL(ebt_register_target);
1513EXPORT_SYMBOL(ebt_unregister_target);
1514EXPORT_SYMBOL(ebt_do_table);
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001515module_init(ebtables_init);
1516module_exit(ebtables_fini);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517MODULE_LICENSE("GPL");