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