blob: 4d1cf1492ca480869f503afa46bc4cf8b3c480c8 [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
Al Viro70fe9af2006-11-30 19:26:14 -0800396static int ebt_verify_pointers(struct ebt_replace *repl,
397 struct ebt_table_info *newinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398{
Al Viro70fe9af2006-11-30 19:26:14 -0800399 unsigned int limit = repl->entries_size;
400 unsigned int valid_hooks = repl->valid_hooks;
401 unsigned int offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 int i;
403
Al Viroe4fd77d2006-11-30 19:26:35 -0800404 for (i = 0; i < NF_BR_NUMHOOKS; i++)
405 newinfo->hook_entry[i] = NULL;
406
407 newinfo->entries_size = repl->entries_size;
408 newinfo->nentries = repl->nentries;
409
Al Viro70fe9af2006-11-30 19:26:14 -0800410 while (offset < limit) {
411 size_t left = limit - offset;
412 struct ebt_entry *e = (void *)newinfo->entries + offset;
Al Virobb2ef252006-11-30 19:22:42 -0800413
Al Viro70fe9af2006-11-30 19:26:14 -0800414 if (left < sizeof(unsigned int))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 break;
Al Viro22b440b2006-11-30 19:25:51 -0800416
Al Viro70fe9af2006-11-30 19:26:14 -0800417 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
418 if ((valid_hooks & (1 << i)) == 0)
419 continue;
420 if ((char *)repl->hook_entry[i] == repl->entries + offset)
421 break;
422 }
423
424 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
425 if (e->bitmask != 0) {
426 /* we make userspace set this right,
427 so there is no misunderstanding */
428 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
429 "in distinguisher\n");
430 return -EINVAL;
431 }
432 if (i != NF_BR_NUMHOOKS)
433 newinfo->hook_entry[i] = (struct ebt_entries *)e;
434 if (left < sizeof(struct ebt_entries))
435 break;
436 offset += sizeof(struct ebt_entries);
437 } else {
438 if (left < sizeof(struct ebt_entry))
439 break;
440 if (left < e->next_offset)
441 break;
442 offset += e->next_offset;
443 }
444 }
445 if (offset != limit) {
446 BUGPRINT("entries_size too small\n");
447 return -EINVAL;
448 }
Al Viroe4fd77d2006-11-30 19:26:35 -0800449
450 /* check if all valid hooks have a chain */
451 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
452 if (!newinfo->hook_entry[i] &&
453 (valid_hooks & (1 << i))) {
454 BUGPRINT("Valid hook without chain\n");
455 return -EINVAL;
456 }
457 }
Al Viro70fe9af2006-11-30 19:26:14 -0800458 return 0;
Al Viro22b440b2006-11-30 19:25:51 -0800459}
460
461/*
462 * this one is very careful, as it is the first function
463 * to parse the userspace data
464 */
465static inline int
466ebt_check_entry_size_and_hooks(struct ebt_entry *e,
Al Viro0e795532006-11-30 19:27:13 -0800467 struct ebt_table_info *newinfo,
468 unsigned int *n, unsigned int *cnt,
469 unsigned int *totalcnt, unsigned int *udc_cnt)
Al Viro22b440b2006-11-30 19:25:51 -0800470{
Al Viro22b440b2006-11-30 19:25:51 -0800471 int i;
472
473 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
Al Viro0e795532006-11-30 19:27:13 -0800474 if ((void *)e == (void *)newinfo->hook_entry[i])
Al Viro22b440b2006-11-30 19:25:51 -0800475 break;
476 }
477 /* beginning of a new chain
478 if i == NF_BR_NUMHOOKS it must be a user defined chain */
479 if (i != NF_BR_NUMHOOKS || !e->bitmask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 /* this checks if the previous chain has as many entries
481 as it said it has */
482 if (*n != *cnt) {
483 BUGPRINT("nentries does not equal the nr of entries "
484 "in the chain\n");
485 return -EINVAL;
486 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 if (((struct ebt_entries *)e)->policy != EBT_DROP &&
488 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
489 /* only RETURN from udc */
490 if (i != NF_BR_NUMHOOKS ||
491 ((struct ebt_entries *)e)->policy != EBT_RETURN) {
492 BUGPRINT("bad policy\n");
493 return -EINVAL;
494 }
495 }
496 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
497 (*udc_cnt)++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
499 BUGPRINT("counter_offset != totalcnt");
500 return -EINVAL;
501 }
502 *n = ((struct ebt_entries *)e)->nentries;
503 *cnt = 0;
504 return 0;
505 }
506 /* a plain old entry, heh */
507 if (sizeof(struct ebt_entry) > e->watchers_offset ||
508 e->watchers_offset > e->target_offset ||
509 e->target_offset >= e->next_offset) {
510 BUGPRINT("entry offsets not in right order\n");
511 return -EINVAL;
512 }
513 /* this is not checked anywhere else */
514 if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) {
515 BUGPRINT("target size too small\n");
516 return -EINVAL;
517 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 (*cnt)++;
519 (*totalcnt)++;
520 return 0;
521}
522
523struct ebt_cl_stack
524{
525 struct ebt_chainstack cs;
526 int from;
527 unsigned int hookmask;
528};
529
530/*
531 * we need these positions to check that the jumps to a different part of the
532 * entries is a jump to the beginning of a new chain.
533 */
534static inline int
535ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
Al Viro177abc32006-11-30 19:27:32 -0800536 unsigned int *n, struct ebt_cl_stack *udc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537{
538 int i;
539
540 /* we're only interested in chain starts */
Al Viro40642f92006-11-30 19:24:12 -0800541 if (e->bitmask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 return 0;
543 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
545 break;
546 }
547 /* only care about udc */
548 if (i != NF_BR_NUMHOOKS)
549 return 0;
550
551 udc[*n].cs.chaininfo = (struct ebt_entries *)e;
552 /* these initialisations are depended on later in check_chainloops() */
553 udc[*n].cs.n = 0;
554 udc[*n].hookmask = 0;
555
556 (*n)++;
557 return 0;
558}
559
560static inline int
561ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
562{
563 if (i && (*i)-- == 0)
564 return 1;
565 if (m->u.match->destroy)
566 m->u.match->destroy(m->data, m->match_size);
567 module_put(m->u.match->me);
568
569 return 0;
570}
571
572static inline int
573ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
574{
575 if (i && (*i)-- == 0)
576 return 1;
577 if (w->u.watcher->destroy)
578 w->u.watcher->destroy(w->data, w->watcher_size);
579 module_put(w->u.watcher->me);
580
581 return 0;
582}
583
584static inline int
585ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
586{
587 struct ebt_entry_target *t;
588
Al Viro40642f92006-11-30 19:24:12 -0800589 if (e->bitmask == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 return 0;
591 /* we're done */
592 if (cnt && (*cnt)-- == 0)
593 return 1;
594 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
595 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
596 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
597 if (t->u.target->destroy)
598 t->u.target->destroy(t->data, t->target_size);
599 module_put(t->u.target->me);
600
601 return 0;
602}
603
604static inline int
605ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
606 const char *name, unsigned int *cnt, unsigned int valid_hooks,
607 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
608{
609 struct ebt_entry_target *t;
610 struct ebt_target *target;
611 unsigned int i, j, hook = 0, hookmask = 0;
Al Viro14197d52006-11-30 19:25:21 -0800612 size_t gap = e->next_offset - e->target_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 int ret;
614
615 /* don't mess with the struct ebt_entries */
Al Viro40642f92006-11-30 19:24:12 -0800616 if (e->bitmask == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 return 0;
618
619 if (e->bitmask & ~EBT_F_MASK) {
620 BUGPRINT("Unknown flag for bitmask\n");
621 return -EINVAL;
622 }
623 if (e->invflags & ~EBT_INV_MASK) {
624 BUGPRINT("Unknown flag for inv bitmask\n");
625 return -EINVAL;
626 }
627 if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) {
628 BUGPRINT("NOPROTO & 802_3 not allowed\n");
629 return -EINVAL;
630 }
631 /* what hook do we belong to? */
632 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
633 if ((valid_hooks & (1 << i)) == 0)
634 continue;
635 if ((char *)newinfo->hook_entry[i] < (char *)e)
636 hook = i;
637 else
638 break;
639 }
640 /* (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on
641 a base chain */
642 if (i < NF_BR_NUMHOOKS)
643 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
644 else {
645 for (i = 0; i < udc_cnt; i++)
646 if ((char *)(cl_s[i].cs.chaininfo) > (char *)e)
647 break;
648 if (i == 0)
649 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
650 else
651 hookmask = cl_s[i - 1].hookmask;
652 }
653 i = 0;
654 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
655 if (ret != 0)
656 goto cleanup_matches;
657 j = 0;
658 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
659 if (ret != 0)
660 goto cleanup_watchers;
661 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
662 target = find_target_lock(t->u.name, &ret, &ebt_mutex);
663 if (!target)
664 goto cleanup_watchers;
665 if (!try_module_get(target->me)) {
Ingo Molnar57b47a52006-03-20 22:35:41 -0800666 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 ret = -ENOENT;
668 goto cleanup_watchers;
669 }
Ingo Molnar57b47a52006-03-20 22:35:41 -0800670 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671
672 t->u.target = target;
673 if (t->u.target == &ebt_standard_target) {
Al Viro14197d52006-11-30 19:25:21 -0800674 if (gap < sizeof(struct ebt_standard_target)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 BUGPRINT("Standard target size too big\n");
676 ret = -EFAULT;
677 goto cleanup_watchers;
678 }
679 if (((struct ebt_standard_target *)t)->verdict <
680 -NUM_STANDARD_TARGETS) {
681 BUGPRINT("Invalid standard target\n");
682 ret = -EFAULT;
683 goto cleanup_watchers;
684 }
Al Viro14197d52006-11-30 19:25:21 -0800685 } else if (t->target_size > gap - sizeof(struct ebt_entry_target) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 (t->u.target->check &&
687 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
688 module_put(t->u.target->me);
689 ret = -EFAULT;
690 goto cleanup_watchers;
691 }
692 (*cnt)++;
693 return 0;
694cleanup_watchers:
695 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j);
696cleanup_matches:
697 EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i);
698 return ret;
699}
700
701/*
702 * checks for loops and sets the hook mask for udc
703 * the hook mask for udc tells us from which base chains the udc can be
704 * accessed. This mask is a parameter to the check() functions of the extensions
705 */
706static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s,
707 unsigned int udc_cnt, unsigned int hooknr, char *base)
708{
709 int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict;
710 struct ebt_entry *e = (struct ebt_entry *)chain->data;
711 struct ebt_entry_target *t;
712
713 while (pos < nentries || chain_nr != -1) {
714 /* end of udc, go back one 'recursion' step */
715 if (pos == nentries) {
716 /* put back values of the time when this chain was called */
717 e = cl_s[chain_nr].cs.e;
718 if (cl_s[chain_nr].from != -1)
719 nentries =
720 cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries;
721 else
722 nentries = chain->nentries;
723 pos = cl_s[chain_nr].cs.n;
724 /* make sure we won't see a loop that isn't one */
725 cl_s[chain_nr].cs.n = 0;
726 chain_nr = cl_s[chain_nr].from;
727 if (pos == nentries)
728 continue;
729 }
730 t = (struct ebt_entry_target *)
731 (((char *)e) + e->target_offset);
732 if (strcmp(t->u.name, EBT_STANDARD_TARGET))
733 goto letscontinue;
734 if (e->target_offset + sizeof(struct ebt_standard_target) >
735 e->next_offset) {
736 BUGPRINT("Standard target size too big\n");
737 return -1;
738 }
739 verdict = ((struct ebt_standard_target *)t)->verdict;
740 if (verdict >= 0) { /* jump to another chain */
741 struct ebt_entries *hlp2 =
742 (struct ebt_entries *)(base + verdict);
743 for (i = 0; i < udc_cnt; i++)
744 if (hlp2 == cl_s[i].cs.chaininfo)
745 break;
746 /* bad destination or loop */
747 if (i == udc_cnt) {
748 BUGPRINT("bad destination\n");
749 return -1;
750 }
751 if (cl_s[i].cs.n) {
752 BUGPRINT("loop\n");
753 return -1;
754 }
Al Viro98a08242006-11-30 19:24:49 -0800755 if (cl_s[i].hookmask & (1 << hooknr))
756 goto letscontinue;
757 /* this can't be 0, so the loop test is correct */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 cl_s[i].cs.n = pos + 1;
759 pos = 0;
760 cl_s[i].cs.e = ((void *)e + e->next_offset);
761 e = (struct ebt_entry *)(hlp2->data);
762 nentries = hlp2->nentries;
763 cl_s[i].from = chain_nr;
764 chain_nr = i;
765 /* this udc is accessible from the base chain for hooknr */
766 cl_s[i].hookmask |= (1 << hooknr);
767 continue;
768 }
769letscontinue:
770 e = (void *)e + e->next_offset;
771 pos++;
772 }
773 return 0;
774}
775
776/* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
777static int translate_table(struct ebt_replace *repl,
778 struct ebt_table_info *newinfo)
779{
780 unsigned int i, j, k, udc_cnt;
781 int ret;
782 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
783
Al Viroe4fd77d2006-11-30 19:26:35 -0800784 ret = ebt_verify_pointers(repl, newinfo);
785 if (ret != 0)
786 return ret;
787
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 i = 0;
Al Viro1f072c92006-11-30 19:26:53 -0800789 while (i < NF_BR_NUMHOOKS && !newinfo->hook_entry[i])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 i++;
791 if (i == NF_BR_NUMHOOKS) {
792 BUGPRINT("No valid hooks specified\n");
793 return -EINVAL;
794 }
Al Viro1f072c92006-11-30 19:26:53 -0800795 if (newinfo->hook_entry[i] != (struct ebt_entries *)newinfo->entries) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 BUGPRINT("Chains don't start at beginning\n");
797 return -EINVAL;
798 }
799 /* make sure chains are ordered after each other in same order
800 as their corresponding hooks */
801 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
Al Viro1f072c92006-11-30 19:26:53 -0800802 if (!newinfo->hook_entry[j])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 continue;
Al Viro1f072c92006-11-30 19:26:53 -0800804 if (newinfo->hook_entry[j] <= newinfo->hook_entry[i]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 BUGPRINT("Hook order must be followed\n");
806 return -EINVAL;
807 }
808 i = j;
809 }
810
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 /* do some early checkings and initialize some things */
812 i = 0; /* holds the expected nr. of entries for the chain */
813 j = 0; /* holds the up to now counted entries for the chain */
814 k = 0; /* holds the total nr. of entries, should equal
815 newinfo->nentries afterwards */
816 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
817 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
Al Viro0e795532006-11-30 19:27:13 -0800818 ebt_check_entry_size_and_hooks, newinfo,
819 &i, &j, &k, &udc_cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820
821 if (ret != 0)
822 return ret;
823
824 if (i != j) {
825 BUGPRINT("nentries does not equal the nr of entries in the "
826 "(last) chain\n");
827 return -EINVAL;
828 }
829 if (k != newinfo->nentries) {
830 BUGPRINT("Total nentries is wrong\n");
831 return -EINVAL;
832 }
833
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 /* get the location of the udc, put them in an array
835 while we're at it, allocate the chainstack */
836 if (udc_cnt) {
837 /* this will get free'd in do_replace()/ebt_register_table()
838 if an error occurs */
Jayachandran C7ad4d2f2006-04-11 17:25:38 -0700839 newinfo->chainstack =
840 vmalloc((highest_possible_processor_id()+1)
841 * sizeof(*(newinfo->chainstack)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 if (!newinfo->chainstack)
843 return -ENOMEM;
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -0700844 for_each_possible_cpu(i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 newinfo->chainstack[i] =
Jayachandran C18bc89a2006-04-20 00:14:49 -0700846 vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0])));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 if (!newinfo->chainstack[i]) {
848 while (i)
849 vfree(newinfo->chainstack[--i]);
850 vfree(newinfo->chainstack);
851 newinfo->chainstack = NULL;
852 return -ENOMEM;
853 }
854 }
855
Jayachandran C18bc89a2006-04-20 00:14:49 -0700856 cl_s = vmalloc(udc_cnt * sizeof(*cl_s));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 if (!cl_s)
858 return -ENOMEM;
859 i = 0; /* the i'th udc */
860 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
Al Viro177abc32006-11-30 19:27:32 -0800861 ebt_get_udc_positions, newinfo, &i, cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 /* sanity check */
863 if (i != udc_cnt) {
864 BUGPRINT("i != udc_cnt\n");
865 vfree(cl_s);
866 return -EFAULT;
867 }
868 }
869
870 /* Check for loops */
871 for (i = 0; i < NF_BR_NUMHOOKS; i++)
Al Viro1f072c92006-11-30 19:26:53 -0800872 if (newinfo->hook_entry[i])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 if (check_chainloops(newinfo->hook_entry[i],
874 cl_s, udc_cnt, i, newinfo->entries)) {
James Lamanna68d31872005-06-22 22:12:57 -0700875 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 return -EINVAL;
877 }
878
879 /* we now know the following (along with E=mc²):
880 - the nr of entries in each chain is right
881 - the size of the allocated space is right
882 - all valid hooks have a corresponding chain
883 - there are no loops
884 - wrong data can still be on the level of a single entry
885 - could be there are jumps to places that are not the
886 beginning of a chain. This can only occur in chains that
887 are not accessible from any base chains, so we don't care. */
888
889 /* used to know what we need to clean up if something goes wrong */
890 i = 0;
891 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
892 ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks,
893 cl_s, udc_cnt);
894 if (ret != 0) {
895 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
896 ebt_cleanup_entry, &i);
897 }
James Lamanna68d31872005-06-22 22:12:57 -0700898 vfree(cl_s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 return ret;
900}
901
902/* called under write_lock */
903static void get_counters(struct ebt_counter *oldcounters,
904 struct ebt_counter *counters, unsigned int nentries)
905{
906 int i, cpu;
907 struct ebt_counter *counter_base;
908
909 /* counters of cpu 0 */
910 memcpy(counters, oldcounters,
David S. Millerc8923c62005-10-13 14:41:23 -0700911 sizeof(struct ebt_counter) * nentries);
912
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 /* add other counters to those of cpu 0 */
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -0700914 for_each_possible_cpu(cpu) {
David S. Millerc8923c62005-10-13 14:41:23 -0700915 if (cpu == 0)
916 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
918 for (i = 0; i < nentries; i++) {
919 counters[i].pcnt += counter_base[i].pcnt;
920 counters[i].bcnt += counter_base[i].bcnt;
921 }
922 }
923}
924
925/* replace the table */
926static int do_replace(void __user *user, unsigned int len)
927{
928 int ret, i, countersize;
929 struct ebt_table_info *newinfo;
930 struct ebt_replace tmp;
931 struct ebt_table *t;
932 struct ebt_counter *counterstmp = NULL;
933 /* used to be able to unlock earlier */
934 struct ebt_table_info *table;
935
936 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
937 return -EFAULT;
938
939 if (len != sizeof(tmp) + tmp.entries_size) {
940 BUGPRINT("Wrong len argument\n");
941 return -EINVAL;
942 }
943
944 if (tmp.entries_size == 0) {
945 BUGPRINT("Entries_size never zero\n");
946 return -EINVAL;
947 }
Kirill Korotaevee4bb812006-02-04 02:16:56 -0800948 /* overflow check */
949 if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
950 SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
951 return -ENOMEM;
952 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
953 return -ENOMEM;
954
David S. Millerc8923c62005-10-13 14:41:23 -0700955 countersize = COUNTER_OFFSET(tmp.nentries) *
956 (highest_possible_processor_id()+1);
Jayachandran C18bc89a2006-04-20 00:14:49 -0700957 newinfo = vmalloc(sizeof(*newinfo) + countersize);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 if (!newinfo)
959 return -ENOMEM;
960
961 if (countersize)
962 memset(newinfo->counters, 0, countersize);
963
Kris Katterjohn8b3a7002006-01-11 15:56:43 -0800964 newinfo->entries = vmalloc(tmp.entries_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 if (!newinfo->entries) {
966 ret = -ENOMEM;
967 goto free_newinfo;
968 }
969 if (copy_from_user(
970 newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
971 BUGPRINT("Couldn't copy entries from userspace\n");
972 ret = -EFAULT;
973 goto free_entries;
974 }
975
976 /* the user wants counters back
977 the check on the size is done later, when we have the lock */
978 if (tmp.num_counters) {
Jayachandran C18bc89a2006-04-20 00:14:49 -0700979 counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980 if (!counterstmp) {
981 ret = -ENOMEM;
982 goto free_entries;
983 }
984 }
985 else
986 counterstmp = NULL;
987
988 /* this can get initialized by translate_table() */
989 newinfo->chainstack = NULL;
990 ret = translate_table(&tmp, newinfo);
991
992 if (ret != 0)
993 goto free_counterstmp;
994
995 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
996 if (!t) {
997 ret = -ENOENT;
998 goto free_iterate;
999 }
1000
1001 /* the table doesn't like it */
1002 if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
1003 goto free_unlock;
1004
1005 if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
1006 BUGPRINT("Wrong nr. of counters requested\n");
1007 ret = -EINVAL;
1008 goto free_unlock;
1009 }
1010
1011 /* we have the mutex lock, so no danger in reading this pointer */
1012 table = t->private;
1013 /* make sure the table can only be rmmod'ed if it contains no rules */
1014 if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
1015 ret = -ENOENT;
1016 goto free_unlock;
1017 } else if (table->nentries && !newinfo->nentries)
1018 module_put(t->me);
1019 /* we need an atomic snapshot of the counters */
1020 write_lock_bh(&t->lock);
1021 if (tmp.num_counters)
1022 get_counters(t->private->counters, counterstmp,
1023 t->private->nentries);
1024
1025 t->private = newinfo;
1026 write_unlock_bh(&t->lock);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001027 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 /* so, a user can change the chains while having messed up her counter
1029 allocation. Only reason why this is done is because this way the lock
1030 is held only once, while this doesn't bring the kernel into a
1031 dangerous state. */
1032 if (tmp.num_counters &&
1033 copy_to_user(tmp.counters, counterstmp,
1034 tmp.num_counters * sizeof(struct ebt_counter))) {
1035 BUGPRINT("Couldn't copy counters to userspace\n");
1036 ret = -EFAULT;
1037 }
1038 else
1039 ret = 0;
1040
1041 /* decrease module count and free resources */
1042 EBT_ENTRY_ITERATE(table->entries, table->entries_size,
1043 ebt_cleanup_entry, NULL);
1044
1045 vfree(table->entries);
1046 if (table->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001047 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 vfree(table->chainstack[i]);
1049 vfree(table->chainstack);
1050 }
1051 vfree(table);
1052
James Lamanna68d31872005-06-22 22:12:57 -07001053 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 return ret;
1055
1056free_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001057 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058free_iterate:
1059 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1060 ebt_cleanup_entry, NULL);
1061free_counterstmp:
James Lamanna68d31872005-06-22 22:12:57 -07001062 vfree(counterstmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 /* can be initialized in translate_table() */
1064 if (newinfo->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001065 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 vfree(newinfo->chainstack[i]);
1067 vfree(newinfo->chainstack);
1068 }
1069free_entries:
James Lamanna68d31872005-06-22 22:12:57 -07001070 vfree(newinfo->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071free_newinfo:
James Lamanna68d31872005-06-22 22:12:57 -07001072 vfree(newinfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 return ret;
1074}
1075
1076int ebt_register_target(struct ebt_target *target)
1077{
Patrick McHardydf0933d2006-09-20 11:57:53 -07001078 struct ebt_target *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 int ret;
1080
Ingo Molnar57b47a52006-03-20 22:35:41 -08001081 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 if (ret != 0)
1083 return ret;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001084 list_for_each_entry(t, &ebt_targets, list) {
1085 if (strcmp(t->name, target->name) == 0) {
1086 mutex_unlock(&ebt_mutex);
1087 return -EEXIST;
1088 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001090 list_add(&target->list, &ebt_targets);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001091 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092
1093 return 0;
1094}
1095
1096void ebt_unregister_target(struct ebt_target *target)
1097{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001098 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001099 list_del(&target->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001100 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101}
1102
1103int ebt_register_match(struct ebt_match *match)
1104{
Patrick McHardydf0933d2006-09-20 11:57:53 -07001105 struct ebt_match *m;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 int ret;
1107
Ingo Molnar57b47a52006-03-20 22:35:41 -08001108 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 if (ret != 0)
1110 return ret;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001111 list_for_each_entry(m, &ebt_matches, list) {
1112 if (strcmp(m->name, match->name) == 0) {
1113 mutex_unlock(&ebt_mutex);
1114 return -EEXIST;
1115 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001117 list_add(&match->list, &ebt_matches);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001118 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
1120 return 0;
1121}
1122
1123void ebt_unregister_match(struct ebt_match *match)
1124{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001125 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001126 list_del(&match->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001127 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128}
1129
1130int ebt_register_watcher(struct ebt_watcher *watcher)
1131{
Patrick McHardydf0933d2006-09-20 11:57:53 -07001132 struct ebt_watcher *w;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 int ret;
1134
Ingo Molnar57b47a52006-03-20 22:35:41 -08001135 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 if (ret != 0)
1137 return ret;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001138 list_for_each_entry(w, &ebt_watchers, list) {
1139 if (strcmp(w->name, watcher->name) == 0) {
1140 mutex_unlock(&ebt_mutex);
1141 return -EEXIST;
1142 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001144 list_add(&watcher->list, &ebt_watchers);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001145 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146
1147 return 0;
1148}
1149
1150void ebt_unregister_watcher(struct ebt_watcher *watcher)
1151{
Ingo Molnar57b47a52006-03-20 22:35:41 -08001152 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001153 list_del(&watcher->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001154 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155}
1156
1157int ebt_register_table(struct ebt_table *table)
1158{
1159 struct ebt_table_info *newinfo;
Patrick McHardydf0933d2006-09-20 11:57:53 -07001160 struct ebt_table *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 int ret, i, countersize;
1162
1163 if (!table || !table->table ||!table->table->entries ||
1164 table->table->entries_size == 0 ||
1165 table->table->counters || table->private) {
1166 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1167 return -EINVAL;
1168 }
1169
David S. Millerc8923c62005-10-13 14:41:23 -07001170 countersize = COUNTER_OFFSET(table->table->nentries) *
1171 (highest_possible_processor_id()+1);
Jayachandran C18bc89a2006-04-20 00:14:49 -07001172 newinfo = vmalloc(sizeof(*newinfo) + countersize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 ret = -ENOMEM;
1174 if (!newinfo)
1175 return -ENOMEM;
1176
Kris Katterjohn8b3a7002006-01-11 15:56:43 -08001177 newinfo->entries = vmalloc(table->table->entries_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 if (!(newinfo->entries))
1179 goto free_newinfo;
1180
1181 memcpy(newinfo->entries, table->table->entries,
1182 table->table->entries_size);
1183
1184 if (countersize)
1185 memset(newinfo->counters, 0, countersize);
1186
1187 /* fill in newinfo and parse the entries */
1188 newinfo->chainstack = NULL;
1189 ret = translate_table(table->table, newinfo);
1190 if (ret != 0) {
1191 BUGPRINT("Translate_table failed\n");
1192 goto free_chainstack;
1193 }
1194
1195 if (table->check && table->check(newinfo, table->valid_hooks)) {
1196 BUGPRINT("The table doesn't like its own initial data, lol\n");
1197 return -EINVAL;
1198 }
1199
1200 table->private = newinfo;
1201 rwlock_init(&table->lock);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001202 ret = mutex_lock_interruptible(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 if (ret != 0)
1204 goto free_chainstack;
1205
Patrick McHardydf0933d2006-09-20 11:57:53 -07001206 list_for_each_entry(t, &ebt_tables, list) {
1207 if (strcmp(t->name, table->name) == 0) {
1208 ret = -EEXIST;
1209 BUGPRINT("Table name already exists\n");
1210 goto free_unlock;
1211 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 }
1213
1214 /* Hold a reference count if the chains aren't empty */
1215 if (newinfo->nentries && !try_module_get(table->me)) {
1216 ret = -ENOENT;
1217 goto free_unlock;
1218 }
Patrick McHardydf0933d2006-09-20 11:57:53 -07001219 list_add(&table->list, &ebt_tables);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001220 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 return 0;
1222free_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001223 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224free_chainstack:
1225 if (newinfo->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001226 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227 vfree(newinfo->chainstack[i]);
1228 vfree(newinfo->chainstack);
1229 }
1230 vfree(newinfo->entries);
1231free_newinfo:
1232 vfree(newinfo);
1233 return ret;
1234}
1235
1236void ebt_unregister_table(struct ebt_table *table)
1237{
1238 int i;
1239
1240 if (!table) {
1241 BUGPRINT("Request to unregister NULL table!!!\n");
1242 return;
1243 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001244 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001245 list_del(&table->list);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001246 mutex_unlock(&ebt_mutex);
James Lamanna68d31872005-06-22 22:12:57 -07001247 vfree(table->private->entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 if (table->private->chainstack) {
KAMEZAWA Hiroyuki6f912042006-04-10 22:52:50 -07001249 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250 vfree(table->private->chainstack[i]);
1251 vfree(table->private->chainstack);
1252 }
1253 vfree(table->private);
1254}
1255
1256/* userspace just supplied us with counters */
1257static int update_counters(void __user *user, unsigned int len)
1258{
1259 int i, ret;
1260 struct ebt_counter *tmp;
1261 struct ebt_replace hlp;
1262 struct ebt_table *t;
1263
1264 if (copy_from_user(&hlp, user, sizeof(hlp)))
1265 return -EFAULT;
1266
1267 if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
1268 return -EINVAL;
1269 if (hlp.num_counters == 0)
1270 return -EINVAL;
1271
Jayachandran C18bc89a2006-04-20 00:14:49 -07001272 if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 MEMPRINT("Update_counters && nomemory\n");
1274 return -ENOMEM;
1275 }
1276
1277 t = find_table_lock(hlp.name, &ret, &ebt_mutex);
1278 if (!t)
1279 goto free_tmp;
1280
1281 if (hlp.num_counters != t->private->nentries) {
1282 BUGPRINT("Wrong nr of counters\n");
1283 ret = -EINVAL;
1284 goto unlock_mutex;
1285 }
1286
1287 if ( copy_from_user(tmp, hlp.counters,
1288 hlp.num_counters * sizeof(struct ebt_counter)) ) {
1289 BUGPRINT("Updata_counters && !cfu\n");
1290 ret = -EFAULT;
1291 goto unlock_mutex;
1292 }
1293
1294 /* we want an atomic add of the counters */
1295 write_lock_bh(&t->lock);
1296
1297 /* we add to the counters of the first cpu */
1298 for (i = 0; i < hlp.num_counters; i++) {
1299 t->private->counters[i].pcnt += tmp[i].pcnt;
1300 t->private->counters[i].bcnt += tmp[i].bcnt;
1301 }
1302
1303 write_unlock_bh(&t->lock);
1304 ret = 0;
1305unlock_mutex:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001306 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307free_tmp:
1308 vfree(tmp);
1309 return ret;
1310}
1311
1312static inline int ebt_make_matchname(struct ebt_entry_match *m,
1313 char *base, char *ubase)
1314{
1315 char *hlp = ubase - base + (char *)m;
1316 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
1317 return -EFAULT;
1318 return 0;
1319}
1320
1321static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
1322 char *base, char *ubase)
1323{
1324 char *hlp = ubase - base + (char *)w;
1325 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
1326 return -EFAULT;
1327 return 0;
1328}
1329
1330static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase)
1331{
1332 int ret;
1333 char *hlp;
1334 struct ebt_entry_target *t;
1335
Al Viro40642f92006-11-30 19:24:12 -08001336 if (e->bitmask == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 return 0;
1338
1339 hlp = ubase - base + (char *)e + e->target_offset;
1340 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
1341
1342 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
1343 if (ret != 0)
1344 return ret;
1345 ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
1346 if (ret != 0)
1347 return ret;
1348 if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN))
1349 return -EFAULT;
1350 return 0;
1351}
1352
Ingo Molnar57b47a52006-03-20 22:35:41 -08001353/* called with ebt_mutex locked */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354static int copy_everything_to_user(struct ebt_table *t, void __user *user,
1355 int *len, int cmd)
1356{
1357 struct ebt_replace tmp;
1358 struct ebt_counter *counterstmp, *oldcounters;
1359 unsigned int entries_size, nentries;
1360 char *entries;
1361
1362 if (cmd == EBT_SO_GET_ENTRIES) {
1363 entries_size = t->private->entries_size;
1364 nentries = t->private->nentries;
1365 entries = t->private->entries;
1366 oldcounters = t->private->counters;
1367 } else {
1368 entries_size = t->table->entries_size;
1369 nentries = t->table->nentries;
1370 entries = t->table->entries;
1371 oldcounters = t->table->counters;
1372 }
1373
1374 if (copy_from_user(&tmp, user, sizeof(tmp))) {
1375 BUGPRINT("Cfu didn't work\n");
1376 return -EFAULT;
1377 }
1378
1379 if (*len != sizeof(struct ebt_replace) + entries_size +
1380 (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
1381 BUGPRINT("Wrong size\n");
1382 return -EINVAL;
1383 }
1384
1385 if (tmp.nentries != nentries) {
1386 BUGPRINT("Nentries wrong\n");
1387 return -EINVAL;
1388 }
1389
1390 if (tmp.entries_size != entries_size) {
1391 BUGPRINT("Wrong size\n");
1392 return -EINVAL;
1393 }
1394
1395 /* userspace might not need the counters */
1396 if (tmp.num_counters) {
1397 if (tmp.num_counters != nentries) {
1398 BUGPRINT("Num_counters wrong\n");
1399 return -EINVAL;
1400 }
Jayachandran C18bc89a2006-04-20 00:14:49 -07001401 counterstmp = vmalloc(nentries * sizeof(*counterstmp));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 if (!counterstmp) {
1403 MEMPRINT("Couldn't copy counters, out of memory\n");
1404 return -ENOMEM;
1405 }
1406 write_lock_bh(&t->lock);
1407 get_counters(oldcounters, counterstmp, nentries);
1408 write_unlock_bh(&t->lock);
1409
1410 if (copy_to_user(tmp.counters, counterstmp,
1411 nentries * sizeof(struct ebt_counter))) {
1412 BUGPRINT("Couldn't copy counters to userspace\n");
1413 vfree(counterstmp);
1414 return -EFAULT;
1415 }
1416 vfree(counterstmp);
1417 }
1418
1419 if (copy_to_user(tmp.entries, entries, entries_size)) {
1420 BUGPRINT("Couldn't copy entries to userspace\n");
1421 return -EFAULT;
1422 }
1423 /* set the match/watcher/target names right */
1424 return EBT_ENTRY_ITERATE(entries, entries_size,
1425 ebt_make_names, entries, tmp.entries);
1426}
1427
1428static int do_ebt_set_ctl(struct sock *sk,
1429 int cmd, void __user *user, unsigned int len)
1430{
1431 int ret;
1432
1433 switch(cmd) {
1434 case EBT_SO_SET_ENTRIES:
1435 ret = do_replace(user, len);
1436 break;
1437 case EBT_SO_SET_COUNTERS:
1438 ret = update_counters(user, len);
1439 break;
1440 default:
1441 ret = -EINVAL;
1442 }
1443 return ret;
1444}
1445
1446static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1447{
1448 int ret;
1449 struct ebt_replace tmp;
1450 struct ebt_table *t;
1451
1452 if (copy_from_user(&tmp, user, sizeof(tmp)))
1453 return -EFAULT;
1454
1455 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
1456 if (!t)
1457 return ret;
1458
1459 switch(cmd) {
1460 case EBT_SO_GET_INFO:
1461 case EBT_SO_GET_INIT_INFO:
1462 if (*len != sizeof(struct ebt_replace)){
1463 ret = -EINVAL;
Ingo Molnar57b47a52006-03-20 22:35:41 -08001464 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 break;
1466 }
1467 if (cmd == EBT_SO_GET_INFO) {
1468 tmp.nentries = t->private->nentries;
1469 tmp.entries_size = t->private->entries_size;
1470 tmp.valid_hooks = t->valid_hooks;
1471 } else {
1472 tmp.nentries = t->table->nentries;
1473 tmp.entries_size = t->table->entries_size;
1474 tmp.valid_hooks = t->table->valid_hooks;
1475 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001476 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 if (copy_to_user(user, &tmp, *len) != 0){
1478 BUGPRINT("c2u Didn't work\n");
1479 ret = -EFAULT;
1480 break;
1481 }
1482 ret = 0;
1483 break;
1484
1485 case EBT_SO_GET_ENTRIES:
1486 case EBT_SO_GET_INIT_ENTRIES:
1487 ret = copy_everything_to_user(t, user, len, cmd);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001488 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 break;
1490
1491 default:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001492 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 ret = -EINVAL;
1494 }
1495
1496 return ret;
1497}
1498
1499static struct nf_sockopt_ops ebt_sockopts =
Andrew Morton74ca4e5a2006-03-20 22:55:02 -08001500{
1501 .pf = PF_INET,
1502 .set_optmin = EBT_BASE_CTL,
1503 .set_optmax = EBT_SO_SET_MAX + 1,
1504 .set = do_ebt_set_ctl,
1505 .get_optmin = EBT_BASE_CTL,
1506 .get_optmax = EBT_SO_GET_MAX + 1,
1507 .get = do_ebt_get_ctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508};
1509
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001510static int __init ebtables_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511{
1512 int ret;
1513
Ingo Molnar57b47a52006-03-20 22:35:41 -08001514 mutex_lock(&ebt_mutex);
Patrick McHardydf0933d2006-09-20 11:57:53 -07001515 list_add(&ebt_standard_target.list, &ebt_targets);
Ingo Molnar57b47a52006-03-20 22:35:41 -08001516 mutex_unlock(&ebt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
1518 return ret;
1519
1520 printk(KERN_NOTICE "Ebtables v2.0 registered\n");
1521 return 0;
1522}
1523
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001524static void __exit ebtables_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525{
1526 nf_unregister_sockopt(&ebt_sockopts);
1527 printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
1528}
1529
1530EXPORT_SYMBOL(ebt_register_table);
1531EXPORT_SYMBOL(ebt_unregister_table);
1532EXPORT_SYMBOL(ebt_register_match);
1533EXPORT_SYMBOL(ebt_unregister_match);
1534EXPORT_SYMBOL(ebt_register_watcher);
1535EXPORT_SYMBOL(ebt_unregister_watcher);
1536EXPORT_SYMBOL(ebt_register_target);
1537EXPORT_SYMBOL(ebt_unregister_target);
1538EXPORT_SYMBOL(ebt_do_table);
Andrew Morton65b4b4e2006-03-28 16:37:06 -08001539module_init(ebtables_init);
1540module_exit(ebtables_fini);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541MODULE_LICENSE("GPL");