Root/
1 | /* iptables module for using new netfilter netlink queue |
2 | * |
3 | * (C) 2005 by Harald Welte <laforge@netfilter.org> |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | */ |
10 | |
11 | #include <linux/module.h> |
12 | #include <linux/skbuff.h> |
13 | |
14 | #include <linux/ip.h> |
15 | #include <linux/ipv6.h> |
16 | #include <linux/jhash.h> |
17 | |
18 | #include <linux/netfilter.h> |
19 | #include <linux/netfilter_arp.h> |
20 | #include <linux/netfilter/x_tables.h> |
21 | #include <linux/netfilter/xt_NFQUEUE.h> |
22 | |
23 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); |
24 | MODULE_DESCRIPTION("Xtables: packet forwarding to netlink"); |
25 | MODULE_LICENSE("GPL"); |
26 | MODULE_ALIAS("ipt_NFQUEUE"); |
27 | MODULE_ALIAS("ip6t_NFQUEUE"); |
28 | MODULE_ALIAS("arpt_NFQUEUE"); |
29 | |
30 | static u32 jhash_initval __read_mostly; |
31 | static bool rnd_inited __read_mostly; |
32 | |
33 | static unsigned int |
34 | nfqueue_tg(struct sk_buff *skb, const struct xt_target_param *par) |
35 | { |
36 | const struct xt_NFQ_info *tinfo = par->targinfo; |
37 | |
38 | return NF_QUEUE_NR(tinfo->queuenum); |
39 | } |
40 | |
41 | static u32 hash_v4(const struct sk_buff *skb) |
42 | { |
43 | const struct iphdr *iph = ip_hdr(skb); |
44 | __be32 ipaddr; |
45 | |
46 | /* packets in either direction go into same queue */ |
47 | ipaddr = iph->saddr ^ iph->daddr; |
48 | |
49 | return jhash_2words((__force u32)ipaddr, iph->protocol, jhash_initval); |
50 | } |
51 | |
52 | static unsigned int |
53 | nfqueue_tg4_v1(struct sk_buff *skb, const struct xt_target_param *par) |
54 | { |
55 | const struct xt_NFQ_info_v1 *info = par->targinfo; |
56 | u32 queue = info->queuenum; |
57 | |
58 | if (info->queues_total > 1) |
59 | queue = hash_v4(skb) % info->queues_total + queue; |
60 | return NF_QUEUE_NR(queue); |
61 | } |
62 | |
63 | #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) |
64 | static u32 hash_v6(const struct sk_buff *skb) |
65 | { |
66 | const struct ipv6hdr *ip6h = ipv6_hdr(skb); |
67 | __be32 addr[4]; |
68 | |
69 | addr[0] = ip6h->saddr.s6_addr32[0] ^ ip6h->daddr.s6_addr32[0]; |
70 | addr[1] = ip6h->saddr.s6_addr32[1] ^ ip6h->daddr.s6_addr32[1]; |
71 | addr[2] = ip6h->saddr.s6_addr32[2] ^ ip6h->daddr.s6_addr32[2]; |
72 | addr[3] = ip6h->saddr.s6_addr32[3] ^ ip6h->daddr.s6_addr32[3]; |
73 | |
74 | return jhash2((__force u32 *)addr, ARRAY_SIZE(addr), jhash_initval); |
75 | } |
76 | |
77 | static unsigned int |
78 | nfqueue_tg6_v1(struct sk_buff *skb, const struct xt_target_param *par) |
79 | { |
80 | const struct xt_NFQ_info_v1 *info = par->targinfo; |
81 | u32 queue = info->queuenum; |
82 | |
83 | if (info->queues_total > 1) |
84 | queue = hash_v6(skb) % info->queues_total + queue; |
85 | return NF_QUEUE_NR(queue); |
86 | } |
87 | #endif |
88 | |
89 | static bool nfqueue_tg_v1_check(const struct xt_tgchk_param *par) |
90 | { |
91 | const struct xt_NFQ_info_v1 *info = par->targinfo; |
92 | u32 maxid; |
93 | |
94 | if (unlikely(!rnd_inited)) { |
95 | get_random_bytes(&jhash_initval, sizeof(jhash_initval)); |
96 | rnd_inited = true; |
97 | } |
98 | if (info->queues_total == 0) { |
99 | pr_err("NFQUEUE: number of total queues is 0\n"); |
100 | return false; |
101 | } |
102 | maxid = info->queues_total - 1 + info->queuenum; |
103 | if (maxid > 0xffff) { |
104 | pr_err("NFQUEUE: number of queues (%u) out of range (got %u)\n", |
105 | info->queues_total, maxid); |
106 | return false; |
107 | } |
108 | return true; |
109 | } |
110 | |
111 | static struct xt_target nfqueue_tg_reg[] __read_mostly = { |
112 | { |
113 | .name = "NFQUEUE", |
114 | .family = NFPROTO_UNSPEC, |
115 | .target = nfqueue_tg, |
116 | .targetsize = sizeof(struct xt_NFQ_info), |
117 | .me = THIS_MODULE, |
118 | }, |
119 | { |
120 | .name = "NFQUEUE", |
121 | .revision = 1, |
122 | .family = NFPROTO_IPV4, |
123 | .checkentry = nfqueue_tg_v1_check, |
124 | .target = nfqueue_tg4_v1, |
125 | .targetsize = sizeof(struct xt_NFQ_info_v1), |
126 | .me = THIS_MODULE, |
127 | }, |
128 | #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) |
129 | { |
130 | .name = "NFQUEUE", |
131 | .revision = 1, |
132 | .family = NFPROTO_IPV6, |
133 | .checkentry = nfqueue_tg_v1_check, |
134 | .target = nfqueue_tg6_v1, |
135 | .targetsize = sizeof(struct xt_NFQ_info_v1), |
136 | .me = THIS_MODULE, |
137 | }, |
138 | #endif |
139 | }; |
140 | |
141 | static int __init nfqueue_tg_init(void) |
142 | { |
143 | return xt_register_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg)); |
144 | } |
145 | |
146 | static void __exit nfqueue_tg_exit(void) |
147 | { |
148 | xt_unregister_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg)); |
149 | } |
150 | |
151 | module_init(nfqueue_tg_init); |
152 | module_exit(nfqueue_tg_exit); |
153 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9