blob: e79c0fbd9e89f793435306e5d8313fa9bf843fe4 [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;
Al Viro14197d52006-11-30 19:25:21 -0800341 size_t left = ((char *)e + e->watchers_offset) - (char *)m;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 int ret;
343
Al Viro14197d52006-11-30 19:25:21 -0800344 if (left < sizeof(struct ebt_entry_match) ||
345 left - sizeof(struct ebt_entry_match) < m->match_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 return -EINVAL;
347 match = find_match_lock(m->u.name, &ret, &ebt_mutex);
348 if (!match)
349 return ret;
350 m->u.match = match;
351 if (!try_module_get(match->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800352 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 return -ENOENT;
354 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800355 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 if (match->check &&
357 match->check(name, hookmask, e, m->data, m->match_size) != 0) {
358 BUGPRINT("match->check failed\n");
359 module_put(match->me);
360 return -EINVAL;
361 }
362 (*cnt)++;
363 return 0;
364}
365
366static inline int
367ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
368 const char *name, unsigned int hookmask, unsigned int *cnt)
369{
370 struct ebt_watcher *watcher;
Al Viro14197d52006-11-30 19:25:21 -0800371 size_t left = ((char *)e + e->target_offset) - (char *)w;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 int ret;
373
Al Viro14197d52006-11-30 19:25:21 -0800374 if (left < sizeof(struct ebt_entry_watcher) ||
375 left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 return -EINVAL;
377 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
378 if (!watcher)
379 return ret;
380 w->u.watcher = watcher;
381 if (!try_module_get(watcher->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800382 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 return -ENOENT;
384 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800385 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 if (watcher->check &&
387 watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) {
388 BUGPRINT("watcher->check failed\n");
389 module_put(watcher->me);
390 return -EINVAL;
391 }
392 (*cnt)++;
393 return 0;
394}
395
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396static inline int
Al Viro22b440b2006-11-30 19:25:51 -0800397__ebt_verify_pointers(struct ebt_entry *e,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 struct ebt_table_info *newinfo, char *base, char *limit,
Al Viro22b440b2006-11-30 19:25:51 -0800399 struct ebt_entries **hook_entries,
400 unsigned int valid_hooks)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401{
Al Virobb2ef252006-11-30 19:22:42 -0800402 unsigned int offset = (char *)e - newinfo->entries;
403 size_t left = (limit - base) - offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 int i;
405
Al Virobb2ef252006-11-30 19:22:42 -0800406 if (left < sizeof(unsigned int))
407 goto Esmall;
408
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
410 if ((valid_hooks & (1 << i)) == 0)
411 continue;
Al Virobb2ef252006-11-30 19:22:42 -0800412 if ((char *)hook_entries[i] == base + offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 break;
414 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
Al Viro40642f92006-11-30 19:24:12 -0800416 if (e->bitmask != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 /* we make userspace set this right,
418 so there is no misunderstanding */
419 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
420 "in distinguisher\n");
421 return -EINVAL;
422 }
Al Viro22b440b2006-11-30 19:25:51 -0800423 if (left < sizeof(struct ebt_entries))
424 goto Esmall;
425 if (i != NF_BR_NUMHOOKS)
426 newinfo->hook_entry[i] = (struct ebt_entries *)e;
427 return 0;
428 }
429 if (left < sizeof(struct ebt_entry))
430 goto Esmall;
431 if (left < e->next_offset)
432 goto Esmall;
433 return 0;
434
435Esmall:
436 BUGPRINT("entries_size too small\n");
437 return -EINVAL;
438}
439
440/*
441 * this one is very careful, as it is the first function
442 * to parse the userspace data
443 */
444static inline int
445ebt_check_entry_size_and_hooks(struct ebt_entry *e,
446 struct ebt_table_info *newinfo, char *base,
447 struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt,
448 unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks)
449{
450 unsigned int offset = (char *)e - newinfo->entries;
451 int i;
452
453 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
454 if ((valid_hooks & (1 << i)) == 0)
455 continue;
456 if ((char *)hook_entries[i] == base + offset)
457 break;
458 }
459 /* beginning of a new chain
460 if i == NF_BR_NUMHOOKS it must be a user defined chain */
461 if (i != NF_BR_NUMHOOKS || !e->bitmask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 /* this checks if the previous chain has as many entries
463 as it said it has */
464 if (*n != *cnt) {
465 BUGPRINT("nentries does not equal the nr of entries "
466 "in the chain\n");
467 return -EINVAL;
468 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 if (((struct ebt_entries *)e)->policy != EBT_DROP &&
470 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
471 /* only RETURN from udc */
472 if (i != NF_BR_NUMHOOKS ||
473 ((struct ebt_entries *)e)->policy != EBT_RETURN) {
474 BUGPRINT("bad policy\n");
475 return -EINVAL;
476 }
477 }
478 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
479 (*udc_cnt)++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
481 BUGPRINT("counter_offset != totalcnt");
482 return -EINVAL;
483 }
484 *n = ((struct ebt_entries *)e)->nentries;
485 *cnt = 0;
486 return 0;
487 }
488 /* a plain old entry, heh */
489 if (sizeof(struct ebt_entry) > e->watchers_offset ||
490 e->watchers_offset > e->target_offset ||
491 e->target_offset >= e->next_offset) {
492 BUGPRINT("entry offsets not in right order\n");
493 return -EINVAL;
494 }
495 /* this is not checked anywhere else */
496 if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) {
497 BUGPRINT("target size too small\n");
498 return -EINVAL;
499 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 (*cnt)++;
501 (*totalcnt)++;
502 return 0;
503}
504
505struct ebt_cl_stack
506{
507 struct ebt_chainstack cs;
508 int from;
509 unsigned int hookmask;
510};
511
512/*
513 * we need these positions to check that the jumps to a different part of the
514 * entries is a jump to the beginning of a new chain.
515 */
516static inline int
517ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
518 struct ebt_entries **hook_entries, unsigned int *n, unsigned int valid_hooks,
519 struct ebt_cl_stack *udc)
520{
521 int i;
522
523 /* we're only interested in chain starts */
Al Viro40642f92006-11-30 19:24:12 -0800524 if (e->bitmask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 return 0;
526 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
527 if ((valid_hooks & (1 << i)) == 0)
528 continue;
529 if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
530 break;
531 }
532 /* only care about udc */
533 if (i != NF_BR_NUMHOOKS)
534 return 0;
535
536 udc[*n].cs.chaininfo = (struct ebt_entries *)e;
537 /* these initialisations are depended on later in check_chainloops() */
538 udc[*n].cs.n = 0;
539 udc[*n].hookmask = 0;
540
541 (*n)++;
542 return 0;
543}
544
545static inline int
546ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
547{
548 if (i && (*i)-- == 0)
549 return 1;
550 if (m->u.match->destroy)
551 m->u.match->destroy(m->data, m->match_size);
552 module_put(m->u.match->me);
553
554 return 0;
555}
556
557static inline int
558ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
559{
560 if (i && (*i)-- == 0)
561 return 1;
562 if (w->u.watcher->destroy)
563 w->u.watcher->destroy(w->data, w->watcher_size);
564 module_put(w->u.watcher->me);
565
566 return 0;
567}
568
569static inline int
570ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
571{
572 struct ebt_entry_target *t;
573
Al Viro40642f92006-11-30 19:24:12 -0800574 if (e->bitmask == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 return 0;
576 /* we're done */
577 if (cnt && (*cnt)-- == 0)
578 return 1;
579 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
580 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
581 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
582 if (t->u.target->destroy)
583 t->u.target->destroy(t->data, t->target_size);
584 module_put(t->u.target->me);
585
586 return 0;
587}
588
589static inline int
590ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
591 const char *name, unsigned int *cnt, unsigned int valid_hooks,
592 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
593{
594 struct ebt_entry_target *t;
595 struct ebt_target *target;
596 unsigned int i, j, hook = 0, hookmask = 0;
Al Viro14197d52006-11-30 19:25:21 -0800597 size_t gap = e->next_offset - e->target_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 int ret;
599
600 /* don't mess with the struct ebt_entries */
Al Viro40642f92006-11-30 19:24:12 -0800601 if (e->bitmask == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 return 0;
603
604 if (e->bitmask & ~EBT_F_MASK) {
605 BUGPRINT("Unknown flag for bitmask\n");
606 return -EINVAL;
607 }
608 if (e->invflags & ~EBT_INV_MASK) {
609 BUGPRINT("Unknown flag for inv bitmask\n");
610 return -EINVAL;
611 }
612 if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) {
613 BUGPRINT("NOPROTO & 802_3 not allowed\n");
614 return -EINVAL;
615 }
616 /* what hook do we belong to? */
617 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
618 if ((valid_hooks & (1 << i)) == 0)
619 continue;
620 if ((char *)newinfo->hook_entry[i] < (char *)e)
621 hook = i;
622 else
623 break;
624 }
625 /* (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on
626 a base chain */
627 if (i < NF_BR_NUMHOOKS)
628 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
629 else {
630 for (i = 0; i < udc_cnt; i++)
631 if ((char *)(cl_s[i].cs.chaininfo) > (char *)e)
632 break;
633 if (i == 0)
634 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
635 else
636 hookmask = cl_s[i - 1].hookmask;
637 }
638 i = 0;
639 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
640 if (ret != 0)
641 goto cleanup_matches;
642 j = 0;
643 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
644 if (ret != 0)
645 goto cleanup_watchers;
646 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
647 target = find_target_lock(t->u.name, &ret, &ebt_mutex);
648 if (!target)
649 goto cleanup_watchers;
650 if (!try_module_get(target->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800651 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 ret = -ENOENT;
653 goto cleanup_watchers;
654 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800655 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656
657 t->u.target = target;
658 if (t->u.target == &ebt_standard_target) {
Al Viro14197d52006-11-30 19:25:21 -0800659 if (gap < sizeof(struct ebt_standard_target)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 BUGPRINT("Standard target size too big\n");
661 ret = -EFAULT;
662 goto cleanup_watchers;
663 }
664 if (((struct ebt_standard_target *)t)->verdict <
665 -NUM_STANDARD_TARGETS) {
666 BUGPRINT("Invalid standard target\n");
667 ret = -EFAULT;
668 goto cleanup_watchers;
669 }
Al Viro14197d52006-11-30 19:25:21 -0800670 } else if (t->target_size > gap - sizeof(struct ebt_entry_target) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 (t->u.target->check &&
672 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
673 module_put(t->u.target->me);
674 ret = -EFAULT;
675 goto cleanup_watchers;
676 }
677 (*cnt)++;
678 return 0;
679cleanup_watchers:
680 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j);
681cleanup_matches:
682 EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i);
683 return ret;
684}
685
686/*
687 * checks for loops and sets the hook mask for udc
688 * the hook mask for udc tells us from which base chains the udc can be
689 * accessed. This mask is a parameter to the check() functions of the extensions
690 */
691static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s,
692 unsigned int udc_cnt, unsigned int hooknr, char *base)
693{
694 int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict;
695 struct ebt_entry *e = (struct ebt_entry *)chain->data;
696 struct ebt_entry_target *t;
697
698 while (pos < nentries || chain_nr != -1) {
699 /* end of udc, go back one 'recursion' step */
700 if (pos == nentries) {
701 /* put back values of the time when this chain was called */
702 e = cl_s[chain_nr].cs.e;
703 if (cl_s[chain_nr].from != -1)
704 nentries =
705 cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries;
706 else
707 nentries = chain->nentries;
708 pos = cl_s[chain_nr].cs.n;
709 /* make sure we won't see a loop that isn't one */
710 cl_s[chain_nr].cs.n = 0;
711 chain_nr = cl_s[chain_nr].from;
712 if (pos == nentries)
713 continue;
714 }
715 t = (struct ebt_entry_target *)
716 (((char *)e) + e->target_offset);
717 if (strcmp(t->u.name, EBT_STANDARD_TARGET))
718 goto letscontinue;
719 if (e->target_offset + sizeof(struct ebt_standard_target) >
720 e->next_offset) {
721 BUGPRINT("Standard target size too big\n");
722 return -1;
723 }
724 verdict = ((struct ebt_standard_target *)t)->verdict;
725 if (verdict >= 0) { /* jump to another chain */
726 struct ebt_entries *hlp2 =
727 (struct ebt_entries *)(base + verdict);
728 for (i = 0; i < udc_cnt; i++)
729 if (hlp2 == cl_s[i].cs.chaininfo)
730 break;
731 /* bad destination or loop */
732 if (i == udc_cnt) {
733 BUGPRINT("bad destination\n");
734 return -1;
735 }
736 if (cl_s[i].cs.n) {
737 BUGPRINT("loop\n");
738 return -1;
739 }
Al Viro98a08242006-11-30 19:24:49 -0800740 if (cl_s[i].hookmask & (1 << hooknr))
741 goto letscontinue;
742 /* this can't be 0, so the loop test is correct */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 cl_s[i].cs.n = pos + 1;
744 pos = 0;
745 cl_s[i].cs.e = ((void *)e + e->next_offset);
746 e = (struct ebt_entry *)(hlp2->data);
747 nentries = hlp2->nentries;
748 cl_s[i].from = chain_nr;
749 chain_nr = i;
750 /* this udc is accessible from the base chain for hooknr */
751 cl_s[i].hookmask |= (1 << hooknr);
752 continue;
753 }
754letscontinue:
755 e = (void *)e + e->next_offset;
756 pos++;
757 }
758 return 0;
759}
760
761/* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
762static int translate_table(struct ebt_replace *repl,
763 struct ebt_table_info *newinfo)
764{
765 unsigned int i, j, k, udc_cnt;
766 int ret;
767 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
768
769 i = 0;
770 while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i)))
771 i++;
772 if (i == NF_BR_NUMHOOKS) {
773 BUGPRINT("No valid hooks specified\n");
774 return -EINVAL;
775 }
776 if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) {
777 BUGPRINT("Chains don't start at beginning\n");
778 return -EINVAL;
779 }
780 /* make sure chains are ordered after each other in same order
781 as their corresponding hooks */
782 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
783 if (!(repl->valid_hooks & (1 << j)))
784 continue;
785 if ( repl->hook_entry[j] <= repl->hook_entry[i] ) {
786 BUGPRINT("Hook order must be followed\n");
787 return -EINVAL;
788 }
789 i = j;
790 }
791
792 for (i = 0; i < NF_BR_NUMHOOKS; i++)
793 newinfo->hook_entry[i] = NULL;
794
795 newinfo->entries_size = repl->entries_size;
796 newinfo->nentries = repl->nentries;
797
Al Viro22b440b2006-11-30 19:25:51 -0800798 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
799 __ebt_verify_pointers, newinfo, repl->entries,
800 repl->entries + repl->entries_size, repl->hook_entry, repl->valid_hooks);
801 if (ret != 0)
802 return ret;
803
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 /* do some early checkings and initialize some things */
805 i = 0; /* holds the expected nr. of entries for the chain */
806 j = 0; /* holds the up to now counted entries for the chain */
807 k = 0; /* holds the total nr. of entries, should equal
808 newinfo->nentries afterwards */
809 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
810 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
811 ebt_check_entry_size_and_hooks, newinfo, repl->entries,
Al Viro22b440b2006-11-30 19:25:51 -0800812 repl->hook_entry, &i, &j, &k,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 &udc_cnt, repl->valid_hooks);
814
815 if (ret != 0)
816 return ret;
817
818 if (i != j) {
819 BUGPRINT("nentries does not equal the nr of entries in the "
820 "(last) chain\n");
821 return -EINVAL;
822 }
823 if (k != newinfo->nentries) {
824 BUGPRINT("Total nentries is wrong\n");
825 return -EINVAL;
826 }
827
828 /* check if all valid hooks have a chain */
829 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
830 if (newinfo->hook_entry[i] == NULL &&
831 (repl->valid_hooks & (1 << i))) {
832 BUGPRINT("Valid hook without chain\n");
833 return -EINVAL;
834 }
835 }
836
837 /* get the location of the udc, put them in an array
838 while we're at it, allocate the chainstack */
839 if (udc_cnt) {
840 /* this will get free'd in do_replace()/ebt_register_table()
841 if an error occurs */
Jayachandran C7ad4d2f2006-04-11 17:25:38 -0700842 newinfo->chainstack =
843 vmalloc((highest_possible_processor_id()+1)
844 * sizeof(*(newinfo->chainstack)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 if (!newinfo->chainstack)
846 return -ENOMEM;
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -0700847 for_each_possible_cpu(i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 newinfo->chainstack[i] =
Jayachandran C18bc89a2006-04-20 00:14:49 -0700849 vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0])));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 if (!newinfo->chainstack[i]) {
851 while (i)
852 vfree(newinfo->chainstack[--i]);
853 vfree(newinfo->chainstack);
854 newinfo->chainstack = NULL;
855 return -ENOMEM;
856 }
857 }
858
Jayachandran C18bc89a2006-04-20 00:14:49 -0700859 cl_s = vmalloc(udc_cnt * sizeof(*cl_s));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 if (!cl_s)
861 return -ENOMEM;
862 i = 0; /* the i'th udc */
863 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
864 ebt_get_udc_positions, newinfo, repl->hook_entry, &i,
865 repl->valid_hooks, cl_s);
866 /* sanity check */
867 if (i != udc_cnt) {
868 BUGPRINT("i != udc_cnt\n");
869 vfree(cl_s);
870 return -EFAULT;
871 }
872 }
873
874 /* Check for loops */
875 for (i = 0; i < NF_BR_NUMHOOKS; i++)
876 if (repl->valid_hooks & (1 << i))
877 if (check_chainloops(newinfo->hook_entry[i],
878 cl_s, udc_cnt, i, newinfo->entries)) {
James Lamanna68d31872005-06-22 22:12:57 -0700879 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 return -EINVAL;
881 }
882
883 /* we now know the following (along with E=mc²):
884 - the nr of entries in each chain is right
885 - the size of the allocated space is right
886 - all valid hooks have a corresponding chain
887 - there are no loops
888 - wrong data can still be on the level of a single entry
889 - could be there are jumps to places that are not the
890 beginning of a chain. This can only occur in chains that
891 are not accessible from any base chains, so we don't care. */
892
893 /* used to know what we need to clean up if something goes wrong */
894 i = 0;
895 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
896 ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks,
897 cl_s, udc_cnt);
898 if (ret != 0) {
899 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
900 ebt_cleanup_entry, &i);
901 }
James Lamanna68d31872005-06-22 22:12:57 -0700902 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 return ret;
904}
905
906/* called under write_lock */
907static void get_counters(struct ebt_counter *oldcounters,
908 struct ebt_counter *counters, unsigned int nentries)
909{
910 int i, cpu;
911 struct ebt_counter *counter_base;
912
913 /* counters of cpu 0 */
914 memcpy(counters, oldcounters,
David S. Millerc8923c62005-10-13 14:41:23 -0700915 sizeof(struct ebt_counter) * nentries);
916
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 /* add other counters to those of cpu 0 */
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -0700918 for_each_possible_cpu(cpu) {
David S. Millerc8923c62005-10-13 14:41:23 -0700919 if (cpu == 0)
920 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
922 for (i = 0; i < nentries; i++) {
923 counters[i].pcnt += counter_base[i].pcnt;
924 counters[i].bcnt += counter_base[i].bcnt;
925 }
926 }
927}
928
929/* replace the table */
930static int do_replace(void __user *user, unsigned int len)
931{
932 int ret, i, countersize;
933 struct ebt_table_info *newinfo;
934 struct ebt_replace tmp;
935 struct ebt_table *t;
936 struct ebt_counter *counterstmp = NULL;
937 /* used to be able to unlock earlier */
938 struct ebt_table_info *table;
939
940 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
941 return -EFAULT;
942
943 if (len != sizeof(tmp) + tmp.entries_size) {
944 BUGPRINT("Wrong len argument\n");
945 return -EINVAL;
946 }
947
948 if (tmp.entries_size == 0) {
949 BUGPRINT("Entries_size never zero\n");
950 return -EINVAL;
951 }
Kirill Korotaevee4bb812006-02-04 02:16:56 -0800952 /* overflow check */
953 if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
954 SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
955 return -ENOMEM;
956 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
957 return -ENOMEM;
958
David S. Millerc8923c62005-10-13 14:41:23 -0700959 countersize = COUNTER_OFFSET(tmp.nentries) *
960 (highest_possible_processor_id()+1);
Jayachandran C18bc89a2006-04-20 00:14:49 -0700961 newinfo = vmalloc(sizeof(*newinfo) + countersize);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 if (!newinfo)
963 return -ENOMEM;
964
965 if (countersize)
966 memset(newinfo->counters, 0, countersize);
967
Kris Katterjohn8b3a7002006-01-11 15:56:43 -0800968 newinfo->entries = vmalloc(tmp.entries_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 if (!newinfo->entries) {
970 ret = -ENOMEM;
971 goto free_newinfo;
972 }
973 if (copy_from_user(
974 newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
975 BUGPRINT("Couldn't copy entries from userspace\n");
976 ret = -EFAULT;
977 goto free_entries;
978 }
979
980 /* the user wants counters back
981 the check on the size is done later, when we have the lock */
982 if (tmp.num_counters) {
Jayachandran C18bc89a2006-04-20 00:14:49 -0700983 counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 if (!counterstmp) {
985 ret = -ENOMEM;
986 goto free_entries;
987 }
988 }
989 else
990 counterstmp = NULL;
991
992 /* this can get initialized by translate_table() */
993 newinfo->chainstack = NULL;
994 ret = translate_table(&tmp, newinfo);
995
996 if (ret != 0)
997 goto free_counterstmp;
998
999 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
1000 if (!t) {
1001 ret = -ENOENT;
1002 goto free_iterate;
1003 }
1004
1005 /* the table doesn't like it */
1006 if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
1007 goto free_unlock;
1008
1009 if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
1010 BUGPRINT("Wrong nr. of counters requested\n");
1011 ret = -EINVAL;
1012 goto free_unlock;
1013 }
1014
1015 /* we have the mutex lock, so no danger in reading this pointer */
1016 table = t->private;
1017 /* make sure the table can only be rmmod'ed if it contains no rules */
1018 if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
1019 ret = -ENOENT;
1020 goto free_unlock;
1021 } else if (table->nentries && !newinfo->nentries)
1022 module_put(t->me);
1023 /* we need an atomic snapshot of the counters */
1024 write_lock_bh(&t->lock);
1025 if (tmp.num_counters)
1026 get_counters(t->private->counters, counterstmp,
1027 t->private->nentries);
1028
1029 t->private = newinfo;
1030 write_unlock_bh(&t->lock);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001031 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 /* so, a user can change the chains while having messed up her counter
1033 allocation. Only reason why this is done is because this way the lock
1034 is held only once, while this doesn't bring the kernel into a
1035 dangerous state. */
1036 if (tmp.num_counters &&
1037 copy_to_user(tmp.counters, counterstmp,
1038 tmp.num_counters * sizeof(struct ebt_counter))) {
1039 BUGPRINT("Couldn't copy counters to userspace\n");
1040 ret = -EFAULT;
1041 }
1042 else
1043 ret = 0;
1044
1045 /* decrease module count and free resources */
1046 EBT_ENTRY_ITERATE(table->entries, table->entries_size,
1047 ebt_cleanup_entry, NULL);
1048
1049 vfree(table->entries);
1050 if (table->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001051 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 vfree(table->chainstack[i]);
1053 vfree(table->chainstack);
1054 }
1055 vfree(table);
1056
James Lamanna68d31872005-06-22 22:12:57 -07001057 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 return ret;
1059
1060free_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001061 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062free_iterate:
1063 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1064 ebt_cleanup_entry, NULL);
1065free_counterstmp:
James Lamanna68d31872005-06-22 22:12:57 -07001066 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 /* can be initialized in translate_table() */
1068 if (newinfo->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001069 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 vfree(newinfo->chainstack[i]);
1071 vfree(newinfo->chainstack);
1072 }
1073free_entries:
James Lamanna68d31872005-06-22 22:12:57 -07001074 vfree(newinfo->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075free_newinfo:
James Lamanna68d31872005-06-22 22:12:57 -07001076 vfree(newinfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 return ret;
1078}
1079
1080int ebt_register_target(struct ebt_target *target)
1081{
Patrick McHardydf0933d2006-09-20 11:57:53 -07001082 struct ebt_target *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 int ret;
1084
Ingo Molnar57b47a52006-03-20 22:35:41 -08001085 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 if (ret != 0)
1087 return ret;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001088 list_for_each_entry(t, &ebt_targets, list) {
1089 if (strcmp(t->name, target->name) == 0) {
1090 mutex_unlock(&ebt_mutex);
1091 return -EEXIST;
1092 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001094 list_add(&target->list, &ebt_targets);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001095 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
1097 return 0;
1098}
1099
1100void ebt_unregister_target(struct ebt_target *target)
1101{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001102 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001103 list_del(&target->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001104 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105}
1106
1107int ebt_register_match(struct ebt_match *match)
1108{
Patrick McHardydf0933d2006-09-20 11:57:53 -07001109 struct ebt_match *m;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 int ret;
1111
Ingo Molnar57b47a52006-03-20 22:35:41 -08001112 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 if (ret != 0)
1114 return ret;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001115 list_for_each_entry(m, &ebt_matches, list) {
1116 if (strcmp(m->name, match->name) == 0) {
1117 mutex_unlock(&ebt_mutex);
1118 return -EEXIST;
1119 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001121 list_add(&match->list, &ebt_matches);
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_match(struct ebt_match *match)
1128{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001129 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001130 list_del(&match->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001131 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132}
1133
1134int ebt_register_watcher(struct ebt_watcher *watcher)
1135{
Patrick McHardydf0933d2006-09-20 11:57:53 -07001136 struct ebt_watcher *w;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 int ret;
1138
Ingo Molnar57b47a52006-03-20 22:35:41 -08001139 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 if (ret != 0)
1141 return ret;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001142 list_for_each_entry(w, &ebt_watchers, list) {
1143 if (strcmp(w->name, watcher->name) == 0) {
1144 mutex_unlock(&ebt_mutex);
1145 return -EEXIST;
1146 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001148 list_add(&watcher->list, &ebt_watchers);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001149 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150
1151 return 0;
1152}
1153
1154void ebt_unregister_watcher(struct ebt_watcher *watcher)
1155{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001156 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001157 list_del(&watcher->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001158 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159}
1160
1161int ebt_register_table(struct ebt_table *table)
1162{
1163 struct ebt_table_info *newinfo;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001164 struct ebt_table *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 int ret, i, countersize;
1166
1167 if (!table || !table->table ||!table->table->entries ||
1168 table->table->entries_size == 0 ||
1169 table->table->counters || table->private) {
1170 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1171 return -EINVAL;
1172 }
1173
David S. Millerc8923c62005-10-13 14:41:23 -07001174 countersize = COUNTER_OFFSET(table->table->nentries) *
1175 (highest_possible_processor_id()+1);
Jayachandran C18bc89a2006-04-20 00:14:49 -07001176 newinfo = vmalloc(sizeof(*newinfo) + countersize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 ret = -ENOMEM;
1178 if (!newinfo)
1179 return -ENOMEM;
1180
Kris Katterjohn8b3a7002006-01-11 15:56:43 -08001181 newinfo->entries = vmalloc(table->table->entries_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 if (!(newinfo->entries))
1183 goto free_newinfo;
1184
1185 memcpy(newinfo->entries, table->table->entries,
1186 table->table->entries_size);
1187
1188 if (countersize)
1189 memset(newinfo->counters, 0, countersize);
1190
1191 /* fill in newinfo and parse the entries */
1192 newinfo->chainstack = NULL;
1193 ret = translate_table(table->table, newinfo);
1194 if (ret != 0) {
1195 BUGPRINT("Translate_table failed\n");
1196 goto free_chainstack;
1197 }
1198
1199 if (table->check && table->check(newinfo, table->valid_hooks)) {
1200 BUGPRINT("The table doesn't like its own initial data, lol\n");
1201 return -EINVAL;
1202 }
1203
1204 table->private = newinfo;
1205 rwlock_init(&table->lock);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001206 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 if (ret != 0)
1208 goto free_chainstack;
1209
Patrick McHardydf0933d2006-09-20 11:57:53 -07001210 list_for_each_entry(t, &ebt_tables, list) {
1211 if (strcmp(t->name, table->name) == 0) {
1212 ret = -EEXIST;
1213 BUGPRINT("Table name already exists\n");
1214 goto free_unlock;
1215 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 }
1217
1218 /* Hold a reference count if the chains aren't empty */
1219 if (newinfo->nentries && !try_module_get(table->me)) {
1220 ret = -ENOENT;
1221 goto free_unlock;
1222 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001223 list_add(&table->list, &ebt_tables);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001224 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 return 0;
1226free_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001227 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228free_chainstack:
1229 if (newinfo->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001230 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 vfree(newinfo->chainstack[i]);
1232 vfree(newinfo->chainstack);
1233 }
1234 vfree(newinfo->entries);
1235free_newinfo:
1236 vfree(newinfo);
1237 return ret;
1238}
1239
1240void ebt_unregister_table(struct ebt_table *table)
1241{
1242 int i;
1243
1244 if (!table) {
1245 BUGPRINT("Request to unregister NULL table!!!\n");
1246 return;
1247 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001248 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001249 list_del(&table->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001250 mutex_unlock(&ebt_mutex);
James Lamanna68d31872005-06-22 22:12:57 -07001251 vfree(table->private->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 if (table->private->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001253 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 vfree(table->private->chainstack[i]);
1255 vfree(table->private->chainstack);
1256 }
1257 vfree(table->private);
1258}
1259
1260/* userspace just supplied us with counters */
1261static int update_counters(void __user *user, unsigned int len)
1262{
1263 int i, ret;
1264 struct ebt_counter *tmp;
1265 struct ebt_replace hlp;
1266 struct ebt_table *t;
1267
1268 if (copy_from_user(&hlp, user, sizeof(hlp)))
1269 return -EFAULT;
1270
1271 if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
1272 return -EINVAL;
1273 if (hlp.num_counters == 0)
1274 return -EINVAL;
1275
Jayachandran C18bc89a2006-04-20 00:14:49 -07001276 if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 MEMPRINT("Update_counters && nomemory\n");
1278 return -ENOMEM;
1279 }
1280
1281 t = find_table_lock(hlp.name, &ret, &ebt_mutex);
1282 if (!t)
1283 goto free_tmp;
1284
1285 if (hlp.num_counters != t->private->nentries) {
1286 BUGPRINT("Wrong nr of counters\n");
1287 ret = -EINVAL;
1288 goto unlock_mutex;
1289 }
1290
1291 if ( copy_from_user(tmp, hlp.counters,
1292 hlp.num_counters * sizeof(struct ebt_counter)) ) {
1293 BUGPRINT("Updata_counters && !cfu\n");
1294 ret = -EFAULT;
1295 goto unlock_mutex;
1296 }
1297
1298 /* we want an atomic add of the counters */
1299 write_lock_bh(&t->lock);
1300
1301 /* we add to the counters of the first cpu */
1302 for (i = 0; i < hlp.num_counters; i++) {
1303 t->private->counters[i].pcnt += tmp[i].pcnt;
1304 t->private->counters[i].bcnt += tmp[i].bcnt;
1305 }
1306
1307 write_unlock_bh(&t->lock);
1308 ret = 0;
1309unlock_mutex:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001310 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311free_tmp:
1312 vfree(tmp);
1313 return ret;
1314}
1315
1316static inline int ebt_make_matchname(struct ebt_entry_match *m,
1317 char *base, char *ubase)
1318{
1319 char *hlp = ubase - base + (char *)m;
1320 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
1321 return -EFAULT;
1322 return 0;
1323}
1324
1325static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
1326 char *base, char *ubase)
1327{
1328 char *hlp = ubase - base + (char *)w;
1329 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
1330 return -EFAULT;
1331 return 0;
1332}
1333
1334static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase)
1335{
1336 int ret;
1337 char *hlp;
1338 struct ebt_entry_target *t;
1339
Al Viro40642f92006-11-30 19:24:12 -08001340 if (e->bitmask == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 return 0;
1342
1343 hlp = ubase - base + (char *)e + e->target_offset;
1344 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
1345
1346 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
1347 if (ret != 0)
1348 return ret;
1349 ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
1350 if (ret != 0)
1351 return ret;
1352 if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN))
1353 return -EFAULT;
1354 return 0;
1355}
1356
Ingo Molnar57b47a52006-03-20 22:35:41 -08001357/* called with ebt_mutex locked */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358static int copy_everything_to_user(struct ebt_table *t, void __user *user,
1359 int *len, int cmd)
1360{
1361 struct ebt_replace tmp;
1362 struct ebt_counter *counterstmp, *oldcounters;
1363 unsigned int entries_size, nentries;
1364 char *entries;
1365
1366 if (cmd == EBT_SO_GET_ENTRIES) {
1367 entries_size = t->private->entries_size;
1368 nentries = t->private->nentries;
1369 entries = t->private->entries;
1370 oldcounters = t->private->counters;
1371 } else {
1372 entries_size = t->table->entries_size;
1373 nentries = t->table->nentries;
1374 entries = t->table->entries;
1375 oldcounters = t->table->counters;
1376 }
1377
1378 if (copy_from_user(&tmp, user, sizeof(tmp))) {
1379 BUGPRINT("Cfu didn't work\n");
1380 return -EFAULT;
1381 }
1382
1383 if (*len != sizeof(struct ebt_replace) + entries_size +
1384 (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
1385 BUGPRINT("Wrong size\n");
1386 return -EINVAL;
1387 }
1388
1389 if (tmp.nentries != nentries) {
1390 BUGPRINT("Nentries wrong\n");
1391 return -EINVAL;
1392 }
1393
1394 if (tmp.entries_size != entries_size) {
1395 BUGPRINT("Wrong size\n");
1396 return -EINVAL;
1397 }
1398
1399 /* userspace might not need the counters */
1400 if (tmp.num_counters) {
1401 if (tmp.num_counters != nentries) {
1402 BUGPRINT("Num_counters wrong\n");
1403 return -EINVAL;
1404 }
Jayachandran C18bc89a2006-04-20 00:14:49 -07001405 counterstmp = vmalloc(nentries * sizeof(*counterstmp));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 if (!counterstmp) {
1407 MEMPRINT("Couldn't copy counters, out of memory\n");
1408 return -ENOMEM;
1409 }
1410 write_lock_bh(&t->lock);
1411 get_counters(oldcounters, counterstmp, nentries);
1412 write_unlock_bh(&t->lock);
1413
1414 if (copy_to_user(tmp.counters, counterstmp,
1415 nentries * sizeof(struct ebt_counter))) {
1416 BUGPRINT("Couldn't copy counters to userspace\n");
1417 vfree(counterstmp);
1418 return -EFAULT;
1419 }
1420 vfree(counterstmp);
1421 }
1422
1423 if (copy_to_user(tmp.entries, entries, entries_size)) {
1424 BUGPRINT("Couldn't copy entries to userspace\n");
1425 return -EFAULT;
1426 }
1427 /* set the match/watcher/target names right */
1428 return EBT_ENTRY_ITERATE(entries, entries_size,
1429 ebt_make_names, entries, tmp.entries);
1430}
1431
1432static int do_ebt_set_ctl(struct sock *sk,
1433 int cmd, void __user *user, unsigned int len)
1434{
1435 int ret;
1436
1437 switch(cmd) {
1438 case EBT_SO_SET_ENTRIES:
1439 ret = do_replace(user, len);
1440 break;
1441 case EBT_SO_SET_COUNTERS:
1442 ret = update_counters(user, len);
1443 break;
1444 default:
1445 ret = -EINVAL;
1446 }
1447 return ret;
1448}
1449
1450static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1451{
1452 int ret;
1453 struct ebt_replace tmp;
1454 struct ebt_table *t;
1455
1456 if (copy_from_user(&tmp, user, sizeof(tmp)))
1457 return -EFAULT;
1458
1459 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
1460 if (!t)
1461 return ret;
1462
1463 switch(cmd) {
1464 case EBT_SO_GET_INFO:
1465 case EBT_SO_GET_INIT_INFO:
1466 if (*len != sizeof(struct ebt_replace)){
1467 ret = -EINVAL;
Ingo Molnar57b47a52006-03-20 22:35:41 -08001468 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 break;
1470 }
1471 if (cmd == EBT_SO_GET_INFO) {
1472 tmp.nentries = t->private->nentries;
1473 tmp.entries_size = t->private->entries_size;
1474 tmp.valid_hooks = t->valid_hooks;
1475 } else {
1476 tmp.nentries = t->table->nentries;
1477 tmp.entries_size = t->table->entries_size;
1478 tmp.valid_hooks = t->table->valid_hooks;
1479 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001480 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 if (copy_to_user(user, &tmp, *len) != 0){
1482 BUGPRINT("c2u Didn't work\n");
1483 ret = -EFAULT;
1484 break;
1485 }
1486 ret = 0;
1487 break;
1488
1489 case EBT_SO_GET_ENTRIES:
1490 case EBT_SO_GET_INIT_ENTRIES:
1491 ret = copy_everything_to_user(t, user, len, cmd);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001492 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 break;
1494
1495 default:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001496 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 ret = -EINVAL;
1498 }
1499
1500 return ret;
1501}
1502
1503static struct nf_sockopt_ops ebt_sockopts =
Andrew Morton74ca4e5a2006-03-20 22:55:02 -08001504{
1505 .pf = PF_INET,
1506 .set_optmin = EBT_BASE_CTL,
1507 .set_optmax = EBT_SO_SET_MAX + 1,
1508 .set = do_ebt_set_ctl,
1509 .get_optmin = EBT_BASE_CTL,
1510 .get_optmax = EBT_SO_GET_MAX + 1,
1511 .get = do_ebt_get_ctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512};
1513
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001514static int __init ebtables_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515{
1516 int ret;
1517
Ingo Molnar57b47a52006-03-20 22:35:41 -08001518 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001519 list_add(&ebt_standard_target.list, &ebt_targets);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001520 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
1522 return ret;
1523
1524 printk(KERN_NOTICE "Ebtables v2.0 registered\n");
1525 return 0;
1526}
1527
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001528static void __exit ebtables_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529{
1530 nf_unregister_sockopt(&ebt_sockopts);
1531 printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
1532}
1533
1534EXPORT_SYMBOL(ebt_register_table);
1535EXPORT_SYMBOL(ebt_unregister_table);
1536EXPORT_SYMBOL(ebt_register_match);
1537EXPORT_SYMBOL(ebt_unregister_match);
1538EXPORT_SYMBOL(ebt_register_watcher);
1539EXPORT_SYMBOL(ebt_unregister_watcher);
1540EXPORT_SYMBOL(ebt_register_target);
1541EXPORT_SYMBOL(ebt_unregister_target);
1542EXPORT_SYMBOL(ebt_do_table);
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001543module_init(ebtables_init);
1544module_exit(ebtables_fini);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545MODULE_LICENSE("GPL");