RT-AC66 3.0.0.4.374.130 core
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / net / ipv4 / netfilter / ipt_set.c
blob3c661be40a613a0b90312a3f7c05a5810f600701
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>
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 */
11 /* Kernel module to match an IP set. */
13 #include <linux/module.h>
14 #include <linux/ip.h>
15 #include <linux/skbuff.h>
16 #include <linux/version.h>
18 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
19 #include <linux/netfilter_ipv4/ip_tables.h>
20 #define xt_register_match ipt_register_match
21 #define xt_unregister_match ipt_unregister_match
22 #define xt_match ipt_match
23 #else
24 #include <linux/netfilter/x_tables.h>
25 #endif
26 #include <linux/netfilter_ipv4/ip_set.h>
27 #include <linux/netfilter_ipv4/ipt_set.h>
29 static inline int
30 match_set(const struct ipt_set_info *info,
31 const struct sk_buff *skb,
32 int inv)
34 if (ip_set_testip_kernel(info->index, skb, info->flags))
35 inv = !inv;
36 return inv;
39 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
40 static int
41 match(const struct sk_buff *skb,
42 const struct net_device *in,
43 const struct net_device *out,
44 const void *matchinfo,
45 int offset,
46 const void *hdr,
47 u_int16_t datalen,
48 int *hotdrop)
49 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
50 static int
51 match(const struct sk_buff *skb,
52 const struct net_device *in,
53 const struct net_device *out,
54 const void *matchinfo,
55 int offset,
56 int *hotdrop)
57 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
58 static int
59 match(const struct sk_buff *skb,
60 const struct net_device *in,
61 const struct net_device *out,
62 const void *matchinfo,
63 int offset,
64 unsigned int protoff,
65 int *hotdrop)
66 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
67 static int
68 match(const struct sk_buff *skb,
69 const struct net_device *in,
70 const struct net_device *out,
71 const struct xt_match *match,
72 const void *matchinfo,
73 int offset,
74 unsigned int protoff,
75 int *hotdrop)
76 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
77 static bool
78 match(const struct sk_buff *skb,
79 const struct net_device *in,
80 const struct net_device *out,
81 const struct xt_match *match,
82 const void *matchinfo,
83 int offset,
84 unsigned int protoff,
85 bool *hotdrop)
86 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
87 static bool
88 match(const struct sk_buff *skb,
89 const struct xt_match_param *par)
90 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
91 static bool
92 match(const struct sk_buff *skb,
93 struct xt_action_param *par)
94 #endif
96 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
97 const struct ipt_set_info_match *info = matchinfo;
98 #else
99 const struct ipt_set_info_match *info = par->matchinfo;
100 #endif
102 return match_set(&info->match_set,
103 skb,
104 info->match_set.flags[0] & IPSET_MATCH_INV);
107 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
108 #define CHECK_OK 1
109 #define CHECK_FAIL 0
110 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
111 #define CHECK_OK 0
112 #define CHECK_FAIL -EINVAL
113 #endif
115 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
116 static int
117 checkentry(const char *tablename,
118 const struct ipt_ip *ip,
119 void *matchinfo,
120 unsigned int matchsize,
121 unsigned int hook_mask)
122 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
123 static int
124 checkentry(const char *tablename,
125 const void *inf,
126 void *matchinfo,
127 unsigned int matchsize,
128 unsigned int hook_mask)
129 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
130 static int
131 checkentry(const char *tablename,
132 const void *inf,
133 const struct xt_match *match,
134 void *matchinfo,
135 unsigned int matchsize,
136 unsigned int hook_mask)
137 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
138 static int
139 checkentry(const char *tablename,
140 const void *inf,
141 const struct xt_match *match,
142 void *matchinfo,
143 unsigned int hook_mask)
144 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
145 static bool
146 checkentry(const char *tablename,
147 const void *inf,
148 const struct xt_match *match,
149 void *matchinfo,
150 unsigned int hook_mask)
151 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
152 static bool
153 checkentry(const struct xt_mtchk_param *par)
154 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
155 static int
156 checkentry(const struct xt_mtchk_param *par)
157 #endif
159 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
160 struct ipt_set_info_match *info = matchinfo;
161 #else
162 struct ipt_set_info_match *info = par->matchinfo;
163 #endif
164 ip_set_id_t index;
166 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
167 if (matchsize != IPT_ALIGN(sizeof(struct ipt_set_info_match))) {
168 ip_set_printk("invalid matchsize %d", matchsize);
169 return CHECK_FAIL;
171 #endif
173 index = ip_set_get_byindex(info->match_set.index);
175 if (index == IP_SET_INVALID_ID) {
176 ip_set_printk("Cannot find set indentified by id %u to match",
177 info->match_set.index);
178 return CHECK_FAIL; /* error */
180 if (info->match_set.flags[IP_SET_MAX_BINDINGS] != 0) {
181 ip_set_printk("That's nasty!");
182 return CHECK_FAIL; /* error */
185 return CHECK_OK;
188 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
189 static void destroy(void *matchinfo,
190 unsigned int matchsize)
191 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
192 static void destroy(const struct xt_match *match,
193 void *matchinfo,
194 unsigned int matchsize)
195 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
196 static void destroy(const struct xt_match *match,
197 void *matchinfo)
198 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) */
199 static void destroy(const struct xt_mtdtor_param *par)
200 #endif
202 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
203 struct ipt_set_info_match *info = matchinfo;
204 #else
205 struct ipt_set_info_match *info = par->matchinfo;
206 #endif
209 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
210 if (matchsize != IPT_ALIGN(sizeof(struct ipt_set_info_match))) {
211 ip_set_printk("invalid matchsize %d", matchsize);
212 return;
214 #endif
215 ip_set_put_byindex(info->match_set.index);
218 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
219 static struct xt_match set_match = {
220 .name = "set",
221 .match = &match,
222 .checkentry = &checkentry,
223 .destroy = &destroy,
224 .me = THIS_MODULE
226 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) */
227 static struct xt_match set_match = {
228 .name = "set",
229 .family = AF_INET,
230 .match = &match,
231 .matchsize = sizeof(struct ipt_set_info_match),
232 .checkentry = &checkentry,
233 .destroy = &destroy,
234 .me = THIS_MODULE
236 #endif
238 MODULE_LICENSE("GPL");
239 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
240 MODULE_DESCRIPTION("iptables IP set match module");
242 static int __init ipt_ipset_init(void)
244 return xt_register_match(&set_match);
247 static void __exit ipt_ipset_fini(void)
249 xt_unregister_match(&set_match);
252 module_init(ipt_ipset_init);
253 module_exit(ipt_ipset_fini);