21 #include <linux/module.h>
22 #include <linux/slab.h>
23 #include <linux/types.h>
24 #include <linux/kernel.h>
25 #include <linux/string.h>
26 #include <linux/errno.h>
32 #define HTSIZE (PAGE_SIZE/sizeof(struct fw_filter *))
43 #ifdef CONFIG_NET_CLS_IND
57 return ((handle >> 24) & 0xFFF) ^
58 ((handle >> 12) & 0xFFF) ^
61 return ((handle >> 22) & 0x7FF) ^
62 ((handle >> 11) & 0x7FF) ^
65 return ((handle >> 20) & 0x3FF) ^
66 ((handle >> 10) & 0x3FF) ^
69 return (handle >> 27) ^
70 ((handle >> 18) & 0x1FF) ^
71 ((handle >> 9) & 0x1FF) ^
74 u8 *
t = (
u8 *) &handle;
75 return t[0] ^ t[1] ^ t[2] ^ t[3];
77 return handle & (
HTSIZE - 1);
90 for (
f = head->
ht[fw_hash(
id)];
f;
f =
f->next) {
93 #ifdef CONFIG_NET_CLS_IND
94 if (!tcf_match_indev(skb,
f->indev))
97 r = tcf_exts_exec(skb, &
f->exts, res);
117 static unsigned long fw_get(
struct tcf_proto *tp,
u32 handle)
125 for (
f = head->
ht[fw_hash(handle)];
f;
f =
f->next) {
127 return (
unsigned long)
f;
132 static void fw_put(
struct tcf_proto *tp,
unsigned long f)
143 tcf_unbind_filter(tp, &f->
res);
148 static void fw_destroy(
struct tcf_proto *tp)
157 for (h = 0; h <
HTSIZE; h++) {
158 while ((f = head->
ht[h]) !=
NULL) {
160 fw_delete_filter(tp, f);
166 static int fw_delete(
struct tcf_proto *tp,
unsigned long arg)
175 for (fp = &head->
ht[fw_hash(f->
id)]; *
fp; fp = &(*fp)->
next) {
180 fw_delete_filter(tp, f);
209 f->
res.classid = nla_get_u32(tb[TCA_FW_CLASSID]);
210 tcf_bind_filter(tp, &f->
res, base);
213 #ifdef CONFIG_NET_CLS_IND
215 err = tcf_change_indev(tp, f->indev, tb[TCA_FW_INDEV]);
222 mask = nla_get_u32(tb[TCA_FW_MASK]);
225 }
else if (head->
mask != 0xFFFFFFFF)
236 static int fw_change(
struct sk_buff *in_skb,
237 struct tcf_proto *tp,
unsigned long base,
249 return handle ? -
EINVAL : 0;
251 err = nla_parse_nested(tb,
TCA_FW_MAX, opt, fw_policy);
256 if (f->
id != handle && handle)
258 return fw_change_attrs(tp, f, tb, tca, base);
267 mask = nla_get_u32(tb[TCA_FW_MASK]);
285 err = fw_change_attrs(tp, f, tb, tca, base);
289 f->
next = head->
ht[fw_hash(handle)];
291 head->
ht[fw_hash(handle)] =
f;
294 *arg = (
unsigned long)f;
313 for (h = 0; h <
HTSIZE; h++) {
316 for (f = head->
ht[h]; f; f = f->
next) {
321 if (arg->
fn(tp, (
unsigned long)f, arg) < 0) {
330 static int fw_dump(
struct tcf_proto *tp,
unsigned long fh,
335 unsigned char *
b = skb_tail_pointer(skb);
343 if (!f->
res.classid && !tcf_exts_is_available(&f->
exts))
348 goto nla_put_failure;
350 if (f->
res.classid &&
351 nla_put_u32(skb, TCA_FW_CLASSID, f->
res.classid))
352 goto nla_put_failure;
353 #ifdef CONFIG_NET_CLS_IND
355 nla_put_string(skb, TCA_FW_INDEV, f->indev))
356 goto nla_put_failure;
358 if (head->
mask != 0xFFFFFFFF &&
359 nla_put_u32(skb, TCA_FW_MASK, head->
mask))
360 goto nla_put_failure;
363 goto nla_put_failure;
365 nla_nest_end(skb, nest);
368 goto nla_put_failure;
379 .classify = fw_classify,
381 .destroy = fw_destroy,
391 static int __init init_fw(
void)
396 static void __exit exit_fw(
void)