2 * x_tables core - Backend for {ip,ip6,arp}_tables
4 * Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org>
6 * Based on existing ip_tables code which is
7 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
8 * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
16 #include <linux/config.h>
17 #include <linux/kernel.h>
18 #include <linux/socket.h>
19 #include <linux/net.h>
20 #include <linux/proc_fs.h>
21 #include <linux/seq_file.h>
22 #include <linux/string.h>
23 #include <linux/vmalloc.h>
25 #include <linux/netfilter/x_tables.h>
26 #include <linux/netfilter_arp.h>
28 MODULE_LICENSE("GPL");
29 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
30 MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module");
32 #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
35 struct semaphore mutex
;
36 struct list_head match
;
37 struct list_head target
;
38 struct list_head tables
;
41 static struct xt_af
*xt
;
43 #ifdef DEBUG_IP_FIREWALL_USER
44 #define duprintf(format, args...) printk(format , ## args)
46 #define duprintf(format, args...)
55 static const char *xt_prefix
[NPROTO
] = {
61 /* Registration hooks for targets. */
63 xt_register_target(struct xt_target
*target
)
65 int ret
, af
= target
->family
;
67 ret
= down_interruptible(&xt
[af
].mutex
);
70 list_add(&target
->list
, &xt
[af
].target
);
74 EXPORT_SYMBOL(xt_register_target
);
77 xt_unregister_target(struct xt_target
*target
)
79 int af
= target
->family
;
82 LIST_DELETE(&xt
[af
].target
, target
);
85 EXPORT_SYMBOL(xt_unregister_target
);
88 xt_register_match(struct xt_match
*match
)
90 int ret
, af
= match
->family
;
92 ret
= down_interruptible(&xt
[af
].mutex
);
96 list_add(&match
->list
, &xt
[af
].match
);
101 EXPORT_SYMBOL(xt_register_match
);
104 xt_unregister_match(struct xt_match
*match
)
106 int af
= match
->family
;
109 LIST_DELETE(&xt
[af
].match
, match
);
112 EXPORT_SYMBOL(xt_unregister_match
);
116 * These are weird, but module loading must not be done with mutex
117 * held (since they will register), and we have to have a single
118 * function to use try_then_request_module().
121 /* Find match, grabs ref. Returns ERR_PTR() on error. */
122 struct xt_match
*xt_find_match(int af
, const char *name
, u8 revision
)
127 if (down_interruptible(&xt
[af
].mutex
) != 0)
128 return ERR_PTR(-EINTR
);
130 list_for_each_entry(m
, &xt
[af
].match
, list
) {
131 if (strcmp(m
->name
, name
) == 0) {
132 if (m
->revision
== revision
) {
133 if (try_module_get(m
->me
)) {
138 err
= -EPROTOTYPE
; /* Found something. */
144 EXPORT_SYMBOL(xt_find_match
);
146 /* Find target, grabs ref. Returns ERR_PTR() on error. */
147 struct xt_target
*xt_find_target(int af
, const char *name
, u8 revision
)
152 if (down_interruptible(&xt
[af
].mutex
) != 0)
153 return ERR_PTR(-EINTR
);
155 list_for_each_entry(t
, &xt
[af
].target
, list
) {
156 if (strcmp(t
->name
, name
) == 0) {
157 if (t
->revision
== revision
) {
158 if (try_module_get(t
->me
)) {
163 err
= -EPROTOTYPE
; /* Found something. */
169 EXPORT_SYMBOL(xt_find_target
);
171 struct xt_target
*xt_request_find_target(int af
, const char *name
, u8 revision
)
173 struct xt_target
*target
;
175 target
= try_then_request_module(xt_find_target(af
, name
, revision
),
176 "%st_%s", xt_prefix
[af
], name
);
177 if (IS_ERR(target
) || !target
)
181 EXPORT_SYMBOL_GPL(xt_request_find_target
);
183 static int match_revfn(int af
, const char *name
, u8 revision
, int *bestp
)
188 list_for_each_entry(m
, &xt
[af
].match
, list
) {
189 if (strcmp(m
->name
, name
) == 0) {
190 if (m
->revision
> *bestp
)
191 *bestp
= m
->revision
;
192 if (m
->revision
== revision
)
199 static int target_revfn(int af
, const char *name
, u8 revision
, int *bestp
)
204 list_for_each_entry(t
, &xt
[af
].target
, list
) {
205 if (strcmp(t
->name
, name
) == 0) {
206 if (t
->revision
> *bestp
)
207 *bestp
= t
->revision
;
208 if (t
->revision
== revision
)
215 /* Returns true or false (if no such extension at all) */
216 int xt_find_revision(int af
, const char *name
, u8 revision
, int target
,
219 int have_rev
, best
= -1;
221 if (down_interruptible(&xt
[af
].mutex
) != 0) {
226 have_rev
= target_revfn(af
, name
, revision
, &best
);
228 have_rev
= match_revfn(af
, name
, revision
, &best
);
231 /* Nothing at all? Return 0 to try loading module. */
239 *err
= -EPROTONOSUPPORT
;
242 EXPORT_SYMBOL_GPL(xt_find_revision
);
244 int xt_check_match(const struct xt_match
*match
, unsigned short family
,
245 unsigned int size
, const char *table
, unsigned int hook_mask
,
246 unsigned short proto
, int inv_proto
)
248 if (XT_ALIGN(match
->matchsize
) != size
) {
249 printk("%s_tables: %s match: invalid size %Zu != %u\n",
250 xt_prefix
[family
], match
->name
,
251 XT_ALIGN(match
->matchsize
), size
);
254 if (match
->table
&& strcmp(match
->table
, table
)) {
255 printk("%s_tables: %s match: only valid in %s table, not %s\n",
256 xt_prefix
[family
], match
->name
, match
->table
, table
);
259 if (match
->hooks
&& (hook_mask
& ~match
->hooks
) != 0) {
260 printk("%s_tables: %s match: bad hook_mask %u\n",
261 xt_prefix
[family
], match
->name
, hook_mask
);
264 if (match
->proto
&& (match
->proto
!= proto
|| inv_proto
)) {
265 printk("%s_tables: %s match: only valid for protocol %u\n",
266 xt_prefix
[family
], match
->name
, match
->proto
);
271 EXPORT_SYMBOL_GPL(xt_check_match
);
273 int xt_check_target(const struct xt_target
*target
, unsigned short family
,
274 unsigned int size
, const char *table
, unsigned int hook_mask
,
275 unsigned short proto
, int inv_proto
)
277 if (XT_ALIGN(target
->targetsize
) != size
) {
278 printk("%s_tables: %s target: invalid size %Zu != %u\n",
279 xt_prefix
[family
], target
->name
,
280 XT_ALIGN(target
->targetsize
), size
);
283 if (target
->table
&& strcmp(target
->table
, table
)) {
284 printk("%s_tables: %s target: only valid in %s table, not %s\n",
285 xt_prefix
[family
], target
->name
, target
->table
, table
);
288 if (target
->hooks
&& (hook_mask
& ~target
->hooks
) != 0) {
289 printk("%s_tables: %s target: bad hook_mask %u\n",
290 xt_prefix
[family
], target
->name
, hook_mask
);
293 if (target
->proto
&& (target
->proto
!= proto
|| inv_proto
)) {
294 printk("%s_tables: %s target: only valid for protocol %u\n",
295 xt_prefix
[family
], target
->name
, target
->proto
);
300 EXPORT_SYMBOL_GPL(xt_check_target
);
302 struct xt_table_info
*xt_alloc_table_info(unsigned int size
)
304 struct xt_table_info
*newinfo
;
307 /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
308 if ((SMP_ALIGN(size
) >> PAGE_SHIFT
) + 2 > num_physpages
)
311 newinfo
= kzalloc(sizeof(struct xt_table_info
), GFP_KERNEL
);
315 newinfo
->size
= size
;
318 if (size
<= PAGE_SIZE
)
319 newinfo
->entries
[cpu
] = kmalloc_node(size
,
323 newinfo
->entries
[cpu
] = vmalloc_node(size
,
326 if (newinfo
->entries
[cpu
] == NULL
) {
327 xt_free_table_info(newinfo
);
334 EXPORT_SYMBOL(xt_alloc_table_info
);
336 void xt_free_table_info(struct xt_table_info
*info
)
341 if (info
->size
<= PAGE_SIZE
)
342 kfree(info
->entries
[cpu
]);
344 vfree(info
->entries
[cpu
]);
348 EXPORT_SYMBOL(xt_free_table_info
);
350 /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
351 struct xt_table
*xt_find_table_lock(int af
, const char *name
)
355 if (down_interruptible(&xt
[af
].mutex
) != 0)
356 return ERR_PTR(-EINTR
);
358 list_for_each_entry(t
, &xt
[af
].tables
, list
)
359 if (strcmp(t
->name
, name
) == 0 && try_module_get(t
->me
))
364 EXPORT_SYMBOL_GPL(xt_find_table_lock
);
366 void xt_table_unlock(struct xt_table
*table
)
368 up(&xt
[table
->af
].mutex
);
370 EXPORT_SYMBOL_GPL(xt_table_unlock
);
373 struct xt_table_info
*
374 xt_replace_table(struct xt_table
*table
,
375 unsigned int num_counters
,
376 struct xt_table_info
*newinfo
,
379 struct xt_table_info
*oldinfo
, *private;
381 /* Do the substitution. */
382 write_lock_bh(&table
->lock
);
383 private = table
->private;
384 /* Check inside lock: is the old number correct? */
385 if (num_counters
!= private->number
) {
386 duprintf("num_counters != table->private->number (%u/%u)\n",
387 num_counters
, private->number
);
388 write_unlock_bh(&table
->lock
);
393 table
->private = newinfo
;
394 newinfo
->initial_entries
= oldinfo
->initial_entries
;
395 write_unlock_bh(&table
->lock
);
399 EXPORT_SYMBOL_GPL(xt_replace_table
);
401 int xt_register_table(struct xt_table
*table
,
402 struct xt_table_info
*bootstrap
,
403 struct xt_table_info
*newinfo
)
406 struct xt_table_info
*private;
408 ret
= down_interruptible(&xt
[table
->af
].mutex
);
412 /* Don't autoload: we'd eat our tail... */
413 if (list_named_find(&xt
[table
->af
].tables
, table
->name
)) {
418 /* Simplifies replace_table code. */
419 table
->private = bootstrap
;
420 if (!xt_replace_table(table
, 0, newinfo
, &ret
))
423 private = table
->private;
424 duprintf("table->private->number = %u\n", private->number
);
426 /* save number of initial entries */
427 private->initial_entries
= private->number
;
429 rwlock_init(&table
->lock
);
430 list_prepend(&xt
[table
->af
].tables
, table
);
434 up(&xt
[table
->af
].mutex
);
437 EXPORT_SYMBOL_GPL(xt_register_table
);
439 void *xt_unregister_table(struct xt_table
*table
)
441 struct xt_table_info
*private;
443 down(&xt
[table
->af
].mutex
);
444 private = table
->private;
445 LIST_DELETE(&xt
[table
->af
].tables
, table
);
446 up(&xt
[table
->af
].mutex
);
450 EXPORT_SYMBOL_GPL(xt_unregister_table
);
452 #ifdef CONFIG_PROC_FS
453 static char *xt_proto_prefix
[NPROTO
] = {
459 static struct list_head
*xt_get_idx(struct list_head
*list
, struct seq_file
*seq
, loff_t pos
)
461 struct list_head
*head
= list
->next
;
463 if (!head
|| list_empty(list
))
466 while (pos
&& (head
= head
->next
)) {
471 return pos
? NULL
: head
;
474 static struct list_head
*type2list(u_int16_t af
, u_int16_t type
)
476 struct list_head
*list
;
480 list
= &xt
[af
].target
;
483 list
= &xt
[af
].match
;
486 list
= &xt
[af
].tables
;
496 static void *xt_tgt_seq_start(struct seq_file
*seq
, loff_t
*pos
)
498 struct proc_dir_entry
*pde
= (struct proc_dir_entry
*) seq
->private;
499 u_int16_t af
= (unsigned long)pde
->data
& 0xffff;
500 u_int16_t type
= (unsigned long)pde
->data
>> 16;
501 struct list_head
*list
;
506 list
= type2list(af
, type
);
510 if (down_interruptible(&xt
[af
].mutex
) != 0)
513 return xt_get_idx(list
, seq
, *pos
);
516 static void *xt_tgt_seq_next(struct seq_file
*seq
, void *v
, loff_t
*pos
)
518 struct proc_dir_entry
*pde
= seq
->private;
519 u_int16_t af
= (unsigned long)pde
->data
& 0xffff;
520 u_int16_t type
= (unsigned long)pde
->data
>> 16;
521 struct list_head
*list
;
526 list
= type2list(af
, type
);
531 return xt_get_idx(list
, seq
, *pos
);
534 static void xt_tgt_seq_stop(struct seq_file
*seq
, void *v
)
536 struct proc_dir_entry
*pde
= seq
->private;
537 u_int16_t af
= (unsigned long)pde
->data
& 0xffff;
542 static int xt_name_seq_show(struct seq_file
*seq
, void *v
)
544 char *name
= (char *)v
+ sizeof(struct list_head
);
547 return seq_printf(seq
, "%s\n", name
);
552 static struct seq_operations xt_tgt_seq_ops
= {
553 .start
= xt_tgt_seq_start
,
554 .next
= xt_tgt_seq_next
,
555 .stop
= xt_tgt_seq_stop
,
556 .show
= xt_name_seq_show
,
559 static int xt_tgt_open(struct inode
*inode
, struct file
*file
)
563 ret
= seq_open(file
, &xt_tgt_seq_ops
);
565 struct seq_file
*seq
= file
->private_data
;
566 struct proc_dir_entry
*pde
= PDE(inode
);
574 static struct file_operations xt_file_ops
= {
575 .owner
= THIS_MODULE
,
579 .release
= seq_release
,
582 #define FORMAT_TABLES "_tables_names"
583 #define FORMAT_MATCHES "_tables_matches"
584 #define FORMAT_TARGETS "_tables_targets"
586 #endif /* CONFIG_PROC_FS */
588 int xt_proto_init(int af
)
590 #ifdef CONFIG_PROC_FS
591 char buf
[XT_FUNCTION_MAXNAMELEN
];
592 struct proc_dir_entry
*proc
;
599 #ifdef CONFIG_PROC_FS
600 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
601 strlcat(buf
, FORMAT_TABLES
, sizeof(buf
));
602 proc
= proc_net_fops_create(buf
, 0440, &xt_file_ops
);
605 proc
->data
= (void *) ((unsigned long) af
| (TABLE
<< 16));
608 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
609 strlcat(buf
, FORMAT_MATCHES
, sizeof(buf
));
610 proc
= proc_net_fops_create(buf
, 0440, &xt_file_ops
);
612 goto out_remove_tables
;
613 proc
->data
= (void *) ((unsigned long) af
| (MATCH
<< 16));
615 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
616 strlcat(buf
, FORMAT_TARGETS
, sizeof(buf
));
617 proc
= proc_net_fops_create(buf
, 0440, &xt_file_ops
);
619 goto out_remove_matches
;
620 proc
->data
= (void *) ((unsigned long) af
| (TARGET
<< 16));
625 #ifdef CONFIG_PROC_FS
627 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
628 strlcat(buf
, FORMAT_MATCHES
, sizeof(buf
));
629 proc_net_remove(buf
);
632 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
633 strlcat(buf
, FORMAT_TABLES
, sizeof(buf
));
634 proc_net_remove(buf
);
639 EXPORT_SYMBOL_GPL(xt_proto_init
);
641 void xt_proto_fini(int af
)
643 #ifdef CONFIG_PROC_FS
644 char buf
[XT_FUNCTION_MAXNAMELEN
];
646 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
647 strlcat(buf
, FORMAT_TABLES
, sizeof(buf
));
648 proc_net_remove(buf
);
650 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
651 strlcat(buf
, FORMAT_TARGETS
, sizeof(buf
));
652 proc_net_remove(buf
);
654 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
655 strlcat(buf
, FORMAT_MATCHES
, sizeof(buf
));
656 proc_net_remove(buf
);
657 #endif /*CONFIG_PROC_FS*/
659 EXPORT_SYMBOL_GPL(xt_proto_fini
);
662 static int __init
xt_init(void)
666 xt
= kmalloc(sizeof(struct xt_af
) * NPROTO
, GFP_KERNEL
);
670 for (i
= 0; i
< NPROTO
; i
++) {
671 init_MUTEX(&xt
[i
].mutex
);
672 INIT_LIST_HEAD(&xt
[i
].target
);
673 INIT_LIST_HEAD(&xt
[i
].match
);
674 INIT_LIST_HEAD(&xt
[i
].tables
);
679 static void __exit
xt_fini(void)
684 module_init(xt_init
);
685 module_exit(xt_fini
);