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>
24 #include <linux/mutex.h>
26 #include <linux/netfilter/x_tables.h>
27 #include <linux/netfilter_arp.h>
30 MODULE_LICENSE("GPL");
31 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
32 MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module");
34 #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
38 struct list_head match
;
39 struct list_head target
;
40 struct list_head tables
;
43 static struct xt_af
*xt
;
45 #ifdef DEBUG_IP_FIREWALL_USER
46 #define duprintf(format, args...) printk(format , ## args)
48 #define duprintf(format, args...)
57 static const char *xt_prefix
[NPROTO
] = {
63 /* Registration hooks for targets. */
65 xt_register_target(struct xt_target
*target
)
67 int ret
, af
= target
->family
;
69 ret
= mutex_lock_interruptible(&xt
[af
].mutex
);
72 list_add(&target
->list
, &xt
[af
].target
);
73 mutex_unlock(&xt
[af
].mutex
);
76 EXPORT_SYMBOL(xt_register_target
);
79 xt_unregister_target(struct xt_target
*target
)
81 int af
= target
->family
;
83 mutex_lock(&xt
[af
].mutex
);
84 LIST_DELETE(&xt
[af
].target
, target
);
85 mutex_unlock(&xt
[af
].mutex
);
87 EXPORT_SYMBOL(xt_unregister_target
);
90 xt_register_match(struct xt_match
*match
)
92 int ret
, af
= match
->family
;
94 ret
= mutex_lock_interruptible(&xt
[af
].mutex
);
98 list_add(&match
->list
, &xt
[af
].match
);
99 mutex_unlock(&xt
[af
].mutex
);
103 EXPORT_SYMBOL(xt_register_match
);
106 xt_unregister_match(struct xt_match
*match
)
108 int af
= match
->family
;
110 mutex_lock(&xt
[af
].mutex
);
111 LIST_DELETE(&xt
[af
].match
, match
);
112 mutex_unlock(&xt
[af
].mutex
);
114 EXPORT_SYMBOL(xt_unregister_match
);
118 * These are weird, but module loading must not be done with mutex
119 * held (since they will register), and we have to have a single
120 * function to use try_then_request_module().
123 /* Find match, grabs ref. Returns ERR_PTR() on error. */
124 struct xt_match
*xt_find_match(int af
, const char *name
, u8 revision
)
129 if (mutex_lock_interruptible(&xt
[af
].mutex
) != 0)
130 return ERR_PTR(-EINTR
);
132 list_for_each_entry(m
, &xt
[af
].match
, list
) {
133 if (strcmp(m
->name
, name
) == 0) {
134 if (m
->revision
== revision
) {
135 if (try_module_get(m
->me
)) {
136 mutex_unlock(&xt
[af
].mutex
);
140 err
= -EPROTOTYPE
; /* Found something. */
143 mutex_unlock(&xt
[af
].mutex
);
146 EXPORT_SYMBOL(xt_find_match
);
148 /* Find target, grabs ref. Returns ERR_PTR() on error. */
149 struct xt_target
*xt_find_target(int af
, const char *name
, u8 revision
)
154 if (mutex_lock_interruptible(&xt
[af
].mutex
) != 0)
155 return ERR_PTR(-EINTR
);
157 list_for_each_entry(t
, &xt
[af
].target
, list
) {
158 if (strcmp(t
->name
, name
) == 0) {
159 if (t
->revision
== revision
) {
160 if (try_module_get(t
->me
)) {
161 mutex_unlock(&xt
[af
].mutex
);
165 err
= -EPROTOTYPE
; /* Found something. */
168 mutex_unlock(&xt
[af
].mutex
);
171 EXPORT_SYMBOL(xt_find_target
);
173 struct xt_target
*xt_request_find_target(int af
, const char *name
, u8 revision
)
175 struct xt_target
*target
;
177 target
= try_then_request_module(xt_find_target(af
, name
, revision
),
178 "%st_%s", xt_prefix
[af
], name
);
179 if (IS_ERR(target
) || !target
)
183 EXPORT_SYMBOL_GPL(xt_request_find_target
);
185 static int match_revfn(int af
, const char *name
, u8 revision
, int *bestp
)
190 list_for_each_entry(m
, &xt
[af
].match
, list
) {
191 if (strcmp(m
->name
, name
) == 0) {
192 if (m
->revision
> *bestp
)
193 *bestp
= m
->revision
;
194 if (m
->revision
== revision
)
201 static int target_revfn(int af
, const char *name
, u8 revision
, int *bestp
)
206 list_for_each_entry(t
, &xt
[af
].target
, list
) {
207 if (strcmp(t
->name
, name
) == 0) {
208 if (t
->revision
> *bestp
)
209 *bestp
= t
->revision
;
210 if (t
->revision
== revision
)
217 /* Returns true or false (if no such extension at all) */
218 int xt_find_revision(int af
, const char *name
, u8 revision
, int target
,
221 int have_rev
, best
= -1;
223 if (mutex_lock_interruptible(&xt
[af
].mutex
) != 0) {
228 have_rev
= target_revfn(af
, name
, revision
, &best
);
230 have_rev
= match_revfn(af
, name
, revision
, &best
);
231 mutex_unlock(&xt
[af
].mutex
);
233 /* Nothing at all? Return 0 to try loading module. */
241 *err
= -EPROTONOSUPPORT
;
244 EXPORT_SYMBOL_GPL(xt_find_revision
);
246 int xt_check_match(const struct xt_match
*match
, unsigned short family
,
247 unsigned int size
, const char *table
, unsigned int hook_mask
,
248 unsigned short proto
, int inv_proto
)
250 if (XT_ALIGN(match
->matchsize
) != size
) {
251 printk("%s_tables: %s match: invalid size %Zu != %u\n",
252 xt_prefix
[family
], match
->name
,
253 XT_ALIGN(match
->matchsize
), size
);
256 if (match
->table
&& strcmp(match
->table
, table
)) {
257 printk("%s_tables: %s match: only valid in %s table, not %s\n",
258 xt_prefix
[family
], match
->name
, match
->table
, table
);
261 if (match
->hooks
&& (hook_mask
& ~match
->hooks
) != 0) {
262 printk("%s_tables: %s match: bad hook_mask %u\n",
263 xt_prefix
[family
], match
->name
, hook_mask
);
266 if (match
->proto
&& (match
->proto
!= proto
|| inv_proto
)) {
267 printk("%s_tables: %s match: only valid for protocol %u\n",
268 xt_prefix
[family
], match
->name
, match
->proto
);
273 EXPORT_SYMBOL_GPL(xt_check_match
);
275 int xt_check_target(const struct xt_target
*target
, unsigned short family
,
276 unsigned int size
, const char *table
, unsigned int hook_mask
,
277 unsigned short proto
, int inv_proto
)
279 if (XT_ALIGN(target
->targetsize
) != size
) {
280 printk("%s_tables: %s target: invalid size %Zu != %u\n",
281 xt_prefix
[family
], target
->name
,
282 XT_ALIGN(target
->targetsize
), size
);
285 if (target
->table
&& strcmp(target
->table
, table
)) {
286 printk("%s_tables: %s target: only valid in %s table, not %s\n",
287 xt_prefix
[family
], target
->name
, target
->table
, table
);
290 if (target
->hooks
&& (hook_mask
& ~target
->hooks
) != 0) {
291 printk("%s_tables: %s target: bad hook_mask %u\n",
292 xt_prefix
[family
], target
->name
, hook_mask
);
295 if (target
->proto
&& (target
->proto
!= proto
|| inv_proto
)) {
296 printk("%s_tables: %s target: only valid for protocol %u\n",
297 xt_prefix
[family
], target
->name
, target
->proto
);
302 EXPORT_SYMBOL_GPL(xt_check_target
);
304 struct xt_table_info
*xt_alloc_table_info(unsigned int size
)
306 struct xt_table_info
*newinfo
;
309 /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
310 if ((SMP_ALIGN(size
) >> PAGE_SHIFT
) + 2 > num_physpages
)
313 newinfo
= kzalloc(sizeof(struct xt_table_info
), GFP_KERNEL
);
317 newinfo
->size
= size
;
320 if (size
<= PAGE_SIZE
)
321 newinfo
->entries
[cpu
] = kmalloc_node(size
,
325 newinfo
->entries
[cpu
] = vmalloc_node(size
,
328 if (newinfo
->entries
[cpu
] == NULL
) {
329 xt_free_table_info(newinfo
);
336 EXPORT_SYMBOL(xt_alloc_table_info
);
338 void xt_free_table_info(struct xt_table_info
*info
)
343 if (info
->size
<= PAGE_SIZE
)
344 kfree(info
->entries
[cpu
]);
346 vfree(info
->entries
[cpu
]);
350 EXPORT_SYMBOL(xt_free_table_info
);
352 /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
353 struct xt_table
*xt_find_table_lock(int af
, const char *name
)
357 if (mutex_lock_interruptible(&xt
[af
].mutex
) != 0)
358 return ERR_PTR(-EINTR
);
360 list_for_each_entry(t
, &xt
[af
].tables
, list
)
361 if (strcmp(t
->name
, name
) == 0 && try_module_get(t
->me
))
363 mutex_unlock(&xt
[af
].mutex
);
366 EXPORT_SYMBOL_GPL(xt_find_table_lock
);
368 void xt_table_unlock(struct xt_table
*table
)
370 mutex_unlock(&xt
[table
->af
].mutex
);
372 EXPORT_SYMBOL_GPL(xt_table_unlock
);
375 struct xt_table_info
*
376 xt_replace_table(struct xt_table
*table
,
377 unsigned int num_counters
,
378 struct xt_table_info
*newinfo
,
381 struct xt_table_info
*oldinfo
, *private;
383 /* Do the substitution. */
384 write_lock_bh(&table
->lock
);
385 private = table
->private;
386 /* Check inside lock: is the old number correct? */
387 if (num_counters
!= private->number
) {
388 duprintf("num_counters != table->private->number (%u/%u)\n",
389 num_counters
, private->number
);
390 write_unlock_bh(&table
->lock
);
395 table
->private = newinfo
;
396 newinfo
->initial_entries
= oldinfo
->initial_entries
;
397 write_unlock_bh(&table
->lock
);
401 EXPORT_SYMBOL_GPL(xt_replace_table
);
403 int xt_register_table(struct xt_table
*table
,
404 struct xt_table_info
*bootstrap
,
405 struct xt_table_info
*newinfo
)
408 struct xt_table_info
*private;
410 ret
= mutex_lock_interruptible(&xt
[table
->af
].mutex
);
414 /* Don't autoload: we'd eat our tail... */
415 if (list_named_find(&xt
[table
->af
].tables
, table
->name
)) {
420 /* Simplifies replace_table code. */
421 table
->private = bootstrap
;
422 if (!xt_replace_table(table
, 0, newinfo
, &ret
))
425 private = table
->private;
426 duprintf("table->private->number = %u\n", private->number
);
428 /* save number of initial entries */
429 private->initial_entries
= private->number
;
431 rwlock_init(&table
->lock
);
432 list_prepend(&xt
[table
->af
].tables
, table
);
436 mutex_unlock(&xt
[table
->af
].mutex
);
439 EXPORT_SYMBOL_GPL(xt_register_table
);
441 void *xt_unregister_table(struct xt_table
*table
)
443 struct xt_table_info
*private;
445 mutex_lock(&xt
[table
->af
].mutex
);
446 private = table
->private;
447 LIST_DELETE(&xt
[table
->af
].tables
, table
);
448 mutex_unlock(&xt
[table
->af
].mutex
);
452 EXPORT_SYMBOL_GPL(xt_unregister_table
);
454 #ifdef CONFIG_PROC_FS
455 static char *xt_proto_prefix
[NPROTO
] = {
461 static struct list_head
*xt_get_idx(struct list_head
*list
, struct seq_file
*seq
, loff_t pos
)
463 struct list_head
*head
= list
->next
;
465 if (!head
|| list_empty(list
))
468 while (pos
&& (head
= head
->next
)) {
473 return pos
? NULL
: head
;
476 static struct list_head
*type2list(u_int16_t af
, u_int16_t type
)
478 struct list_head
*list
;
482 list
= &xt
[af
].target
;
485 list
= &xt
[af
].match
;
488 list
= &xt
[af
].tables
;
498 static void *xt_tgt_seq_start(struct seq_file
*seq
, loff_t
*pos
)
500 struct proc_dir_entry
*pde
= (struct proc_dir_entry
*) seq
->private;
501 u_int16_t af
= (unsigned long)pde
->data
& 0xffff;
502 u_int16_t type
= (unsigned long)pde
->data
>> 16;
503 struct list_head
*list
;
508 list
= type2list(af
, type
);
512 if (mutex_lock_interruptible(&xt
[af
].mutex
) != 0)
515 return xt_get_idx(list
, seq
, *pos
);
518 static void *xt_tgt_seq_next(struct seq_file
*seq
, void *v
, loff_t
*pos
)
520 struct proc_dir_entry
*pde
= seq
->private;
521 u_int16_t af
= (unsigned long)pde
->data
& 0xffff;
522 u_int16_t type
= (unsigned long)pde
->data
>> 16;
523 struct list_head
*list
;
528 list
= type2list(af
, type
);
533 return xt_get_idx(list
, seq
, *pos
);
536 static void xt_tgt_seq_stop(struct seq_file
*seq
, void *v
)
538 struct proc_dir_entry
*pde
= seq
->private;
539 u_int16_t af
= (unsigned long)pde
->data
& 0xffff;
541 mutex_unlock(&xt
[af
].mutex
);
544 static int xt_name_seq_show(struct seq_file
*seq
, void *v
)
546 char *name
= (char *)v
+ sizeof(struct list_head
);
549 return seq_printf(seq
, "%s\n", name
);
554 static struct seq_operations xt_tgt_seq_ops
= {
555 .start
= xt_tgt_seq_start
,
556 .next
= xt_tgt_seq_next
,
557 .stop
= xt_tgt_seq_stop
,
558 .show
= xt_name_seq_show
,
561 static int xt_tgt_open(struct inode
*inode
, struct file
*file
)
565 ret
= seq_open(file
, &xt_tgt_seq_ops
);
567 struct seq_file
*seq
= file
->private_data
;
568 struct proc_dir_entry
*pde
= PDE(inode
);
576 static struct file_operations xt_file_ops
= {
577 .owner
= THIS_MODULE
,
581 .release
= seq_release
,
584 #define FORMAT_TABLES "_tables_names"
585 #define FORMAT_MATCHES "_tables_matches"
586 #define FORMAT_TARGETS "_tables_targets"
588 #endif /* CONFIG_PROC_FS */
590 int xt_proto_init(int af
)
592 #ifdef CONFIG_PROC_FS
593 char buf
[XT_FUNCTION_MAXNAMELEN
];
594 struct proc_dir_entry
*proc
;
601 #ifdef CONFIG_PROC_FS
602 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
603 strlcat(buf
, FORMAT_TABLES
, sizeof(buf
));
604 proc
= proc_net_fops_create(buf
, 0440, &xt_file_ops
);
607 proc
->data
= (void *) ((unsigned long) af
| (TABLE
<< 16));
610 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
611 strlcat(buf
, FORMAT_MATCHES
, sizeof(buf
));
612 proc
= proc_net_fops_create(buf
, 0440, &xt_file_ops
);
614 goto out_remove_tables
;
615 proc
->data
= (void *) ((unsigned long) af
| (MATCH
<< 16));
617 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
618 strlcat(buf
, FORMAT_TARGETS
, sizeof(buf
));
619 proc
= proc_net_fops_create(buf
, 0440, &xt_file_ops
);
621 goto out_remove_matches
;
622 proc
->data
= (void *) ((unsigned long) af
| (TARGET
<< 16));
627 #ifdef CONFIG_PROC_FS
629 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
630 strlcat(buf
, FORMAT_MATCHES
, sizeof(buf
));
631 proc_net_remove(buf
);
634 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
635 strlcat(buf
, FORMAT_TABLES
, sizeof(buf
));
636 proc_net_remove(buf
);
641 EXPORT_SYMBOL_GPL(xt_proto_init
);
643 void xt_proto_fini(int af
)
645 #ifdef CONFIG_PROC_FS
646 char buf
[XT_FUNCTION_MAXNAMELEN
];
648 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
649 strlcat(buf
, FORMAT_TABLES
, sizeof(buf
));
650 proc_net_remove(buf
);
652 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
653 strlcat(buf
, FORMAT_TARGETS
, sizeof(buf
));
654 proc_net_remove(buf
);
656 strlcpy(buf
, xt_proto_prefix
[af
], sizeof(buf
));
657 strlcat(buf
, FORMAT_MATCHES
, sizeof(buf
));
658 proc_net_remove(buf
);
659 #endif /*CONFIG_PROC_FS*/
661 EXPORT_SYMBOL_GPL(xt_proto_fini
);
664 static int __init
xt_init(void)
668 xt
= kmalloc(sizeof(struct xt_af
) * NPROTO
, GFP_KERNEL
);
672 for (i
= 0; i
< NPROTO
; i
++) {
673 mutex_init(&xt
[i
].mutex
);
674 INIT_LIST_HEAD(&xt
[i
].target
);
675 INIT_LIST_HEAD(&xt
[i
].match
);
676 INIT_LIST_HEAD(&xt
[i
].tables
);
681 static void __exit
xt_fini(void)
686 module_init(xt_init
);
687 module_exit(xt_fini
);