This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / net / ipv4 / netfilter / ipt_SET.c
1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2  *                         Patrick Schaaf <bof@bof.de>
3  *                         Martin Josefsson <gandalf@wlug.westbo.se>
4  * Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.  
9  */
10
11 /* ipt_SET.c - netfilter target to manipulate IP sets */
12
13 #include <linux/types.h>
14 #include <linux/ip.h>
15 #include <linux/timer.h>
16 #include <linux/module.h>
17 #include <linux/netfilter.h>
18 #include <linux/netdevice.h>
19 #include <linux/if.h>
20 #include <linux/inetdevice.h>
21 #include <net/protocol.h>
22 #include <net/checksum.h>
23 #include <linux/netfilter_ipv4.h>
24 #include <linux/netfilter_ipv4/ip_nat_rule.h>
25 #include <linux/netfilter_ipv4/ipt_set.h>
26
27 static unsigned int
28 target(struct sk_buff **pskb,
29        const struct net_device *in,
30        const struct net_device *out,
31        unsigned int hooknum,
32        const void *targinfo,
33        void *userinfo)
34 {
35         const struct ipt_set_info_target *info = targinfo;
36         
37         if (info->add_set.index != IP_SET_INVALID_ID)
38                 ip_set_addip_kernel(info->add_set.index,
39                                     *pskb,
40                                     info->add_set.flags);
41         if (info->del_set.index != IP_SET_INVALID_ID)
42                 ip_set_delip_kernel(info->del_set.index,
43                                     *pskb,
44                                     info->del_set.flags);
45
46         return IPT_CONTINUE;
47 }
48
49 static int
50 checkentry(const char *tablename,
51            const struct ipt_entry *e,
52            void *targinfo,
53            unsigned int targinfosize, unsigned int hook_mask)
54 {
55         struct ipt_set_info_target *info = 
56                 (struct ipt_set_info_target *) targinfo;
57         ip_set_id_t index;
58
59         if (targinfosize != IPT_ALIGN(sizeof(*info))) {
60                 DP("bad target info size %u", targinfosize);
61                 return 0;
62         }
63
64         if (info->add_set.index != IP_SET_INVALID_ID) {
65                 index = ip_set_get_byindex(info->add_set.index);
66                 if (index == IP_SET_INVALID_ID) {
67                         ip_set_printk("cannot find add_set index %u as target",
68                                       info->add_set.index);
69                         return 0;       /* error */
70                 }
71         }
72
73         if (info->del_set.index != IP_SET_INVALID_ID) {
74                 index = ip_set_get_byindex(info->del_set.index);
75                 if (index == IP_SET_INVALID_ID) {
76                         ip_set_printk("cannot find del_set index %u as target",
77                                       info->del_set.index);
78                         return 0;       /* error */
79                 }
80         }
81         if (info->add_set.flags[IP_SET_MAX_BINDINGS] != 0
82             || info->del_set.flags[IP_SET_MAX_BINDINGS] != 0) {
83                 ip_set_printk("That's nasty!");
84                 return 0;       /* error */
85         }
86
87         return 1;
88 }
89
90 static void destroy(void *targetinfo, unsigned int targetsize)
91 {
92         struct ipt_set_info_target *info = targetinfo;
93
94         if (targetsize != IPT_ALIGN(sizeof(struct ipt_set_info_target))) {
95                 ip_set_printk("invalid targetsize %d", targetsize);
96                 return;
97         }
98
99         if (info->add_set.index != IP_SET_INVALID_ID)
100                 ip_set_put(info->add_set.index);
101         if (info->del_set.index != IP_SET_INVALID_ID)
102                 ip_set_put(info->del_set.index);
103 }
104
105 static struct ipt_target SET_target = {
106         .name           = "SET",
107         .target         = target,
108         .checkentry     = checkentry,
109         .destroy        = destroy,
110         .me             = THIS_MODULE
111 };
112
113 MODULE_LICENSE("GPL");
114 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
115 MODULE_DESCRIPTION("iptables IP set target module");
116
117 static int __init init(void)
118 {
119         return ipt_register_target(&SET_target);
120 }
121
122 static void __exit fini(void)
123 {
124         ipt_unregister_target(&SET_target);
125 }
126
127 module_init(init);
128 module_exit(fini);