Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
netfilter
xt_NFQUEUE.c
Go to the documentation of this file.
1
/* iptables module for using new netfilter netlink queue
2
*
3
* (C) 2005 by Harald Welte <
[email protected]
>
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 <
[email protected]
>"
);
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_action_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
45
/* packets in either direction go into same queue */
46
if
((
__force
u32
)iph->
saddr
< (
__force
u32)iph->
daddr
)
47
return
jhash_3words((
__force
u32)iph->
saddr
,
48
(
__force
u32)iph->
daddr
, iph->
protocol
, jhash_initval);
49
50
return
jhash_3words((
__force
u32)iph->
daddr
,
51
(
__force
u32)iph->
saddr
, iph->
protocol
, jhash_initval);
52
}
53
54
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
55
static
u32 hash_v6(
const
struct
sk_buff
*skb)
56
{
57
const
struct
ipv6hdr
*ip6h = ipv6_hdr(skb);
58
u32
a
,
b
,
c
;
59
60
if
((
__force
u32)ip6h->
saddr
.s6_addr32[3] <
61
(
__force
u32)ip6h->
daddr
.s6_addr32[3]) {
62
a = (
__force
u32
) ip6h->
saddr
.s6_addr32[3];
63
b = (
__force
u32) ip6h->
daddr
.s6_addr32[3];
64
}
else
{
65
b = (
__force
u32
) ip6h->
saddr
.s6_addr32[3];
66
a = (
__force
u32) ip6h->
daddr
.s6_addr32[3];
67
}
68
69
if
((
__force
u32)ip6h->
saddr
.s6_addr32[1] <
70
(
__force
u32
)ip6h->
daddr
.s6_addr32[1])
71
c = (
__force
u32
) ip6h->
saddr
.s6_addr32[1];
72
else
73
c = (
__force
u32) ip6h->
daddr
.s6_addr32[1];
74
75
return
jhash_3words(a, b, c, jhash_initval);
76
}
77
#endif
78
79
static
unsigned
int
80
nfqueue_tg_v1(
struct
sk_buff
*skb,
const
struct
xt_action_param
*par)
81
{
82
const
struct
xt_NFQ_info_v1
*
info
= par->
targinfo
;
83
u32
queue
= info->
queuenum
;
84
85
if
(info->
queues_total
> 1) {
86
if
(par->
family
==
NFPROTO_IPV4
)
87
queue = (((
u64
) hash_v4(skb) * info->
queues_total
) >>
88
32) + queue;
89
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
90
else
if
(par->
family
==
NFPROTO_IPV6
)
91
queue = (((
u64
) hash_v6(skb) * info->
queues_total
) >>
92
32) + queue;
93
#endif
94
}
95
return
NF_QUEUE_NR
(queue);
96
}
97
98
static
unsigned
int
99
nfqueue_tg_v2(
struct
sk_buff
*skb,
const
struct
xt_action_param
*par)
100
{
101
const
struct
xt_NFQ_info_v2
*info = par->
targinfo
;
102
unsigned
int
ret
= nfqueue_tg_v1(skb, par);
103
104
if
(info->
bypass
)
105
ret |=
NF_VERDICT_FLAG_QUEUE_BYPASS
;
106
return
ret
;
107
}
108
109
static
int
nfqueue_tg_check(
const
struct
xt_tgchk_param
*par)
110
{
111
const
struct
xt_NFQ_info_v2
*info = par->
targinfo
;
112
u32 maxid;
113
114
if
(
unlikely
(!rnd_inited)) {
115
get_random_bytes
(&jhash_initval,
sizeof
(jhash_initval));
116
rnd_inited =
true
;
117
}
118
if
(info->
queues_total
== 0) {
119
pr_err
(
"NFQUEUE: number of total queues is 0\n"
);
120
return
-
EINVAL
;
121
}
122
maxid = info->
queues_total
- 1 + info->
queuenum
;
123
if
(maxid > 0xffff) {
124
pr_err
(
"NFQUEUE: number of queues (%u) out of range (got %u)\n"
,
125
info->
queues_total
, maxid);
126
return
-
ERANGE
;
127
}
128
if
(par->
target
->revision == 2 && info->
bypass
> 1)
129
return
-
EINVAL
;
130
return
0;
131
}
132
133
static
struct
xt_target
nfqueue_tg_reg[]
__read_mostly
= {
134
{
135
.name =
"NFQUEUE"
,
136
.family =
NFPROTO_UNSPEC
,
137
.target = nfqueue_tg,
138
.targetsize =
sizeof
(
struct
xt_NFQ_info
),
139
.me =
THIS_MODULE
,
140
},
141
{
142
.name =
"NFQUEUE"
,
143
.revision = 1,
144
.family =
NFPROTO_UNSPEC
,
145
.checkentry = nfqueue_tg_check,
146
.target = nfqueue_tg_v1,
147
.targetsize =
sizeof
(
struct
xt_NFQ_info_v1
),
148
.me =
THIS_MODULE
,
149
},
150
{
151
.name =
"NFQUEUE"
,
152
.revision = 2,
153
.family =
NFPROTO_UNSPEC
,
154
.checkentry = nfqueue_tg_check,
155
.target = nfqueue_tg_v2,
156
.targetsize =
sizeof
(
struct
xt_NFQ_info_v2
),
157
.me =
THIS_MODULE
,
158
},
159
};
160
161
static
int
__init
nfqueue_tg_init(
void
)
162
{
163
return
xt_register_targets
(nfqueue_tg_reg,
ARRAY_SIZE
(nfqueue_tg_reg));
164
}
165
166
static
void
__exit
nfqueue_tg_exit(
void
)
167
{
168
xt_unregister_targets
(nfqueue_tg_reg,
ARRAY_SIZE
(nfqueue_tg_reg));
169
}
170
171
module_init
(nfqueue_tg_init);
172
module_exit
(nfqueue_tg_exit);
Generated on Thu Jan 10 2013 15:00:57 for Linux Kernel by
1.8.2