aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netfilter/ipv4/nf_defrag_ipv4.h6
-rw-r--r--net/ipv4/netfilter/Kconfig5
-rw-r--r--net/ipv4/netfilter/Makefile3
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c56
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c96
5 files changed, 113 insertions, 53 deletions
diff --git a/include/net/netfilter/ipv4/nf_defrag_ipv4.h b/include/net/netfilter/ipv4/nf_defrag_ipv4.h
new file mode 100644
index 000000000000..6b00ea38546b
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_defrag_ipv4.h
@@ -0,0 +1,6 @@
1#ifndef _NF_DEFRAG_IPV4_H
2#define _NF_DEFRAG_IPV4_H
3
4extern void nf_defrag_ipv4_enable(void);
5
6#endif /* _NF_DEFRAG_IPV4_H */
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 4e842d566428..07757ac8d5d8 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -5,10 +5,15 @@
5menu "IP: Netfilter Configuration" 5menu "IP: Netfilter Configuration"
6 depends on INET && NETFILTER 6 depends on INET && NETFILTER
7 7
8config NF_DEFRAG_IPV4
9 tristate
10 default n
11
8config NF_CONNTRACK_IPV4 12config NF_CONNTRACK_IPV4
9 tristate "IPv4 connection tracking support (required for NAT)" 13 tristate "IPv4 connection tracking support (required for NAT)"
10 depends on NF_CONNTRACK 14 depends on NF_CONNTRACK
11 default m if NETFILTER_ADVANCED=n 15 default m if NETFILTER_ADVANCED=n
16 select NF_DEFRAG_IPV4
12 ---help--- 17 ---help---
13 Connection tracking keeps a record of what packets have passed 18 Connection tracking keeps a record of what packets have passed
14 through your machine, in order to figure out how they are related 19 through your machine, in order to figure out how they are related
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 1107edbe478f..5f9b650d90fc 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
18 18
19obj-$(CONFIG_NF_NAT) += nf_nat.o 19obj-$(CONFIG_NF_NAT) += nf_nat.o
20 20
21# defrag
22obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
23
21# NAT helpers (nf_conntrack) 24# NAT helpers (nf_conntrack)
22obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o 25obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
23obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o 26obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index af69acc1d0f8..4a7c35275396 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -1,3 +1,4 @@
1
1/* (C) 1999-2001 Paul `Rusty' Russell 2/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 3 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 * 4 *
@@ -24,6 +25,7 @@
24#include <net/netfilter/nf_conntrack_core.h> 25#include <net/netfilter/nf_conntrack_core.h>
25#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 26#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
26#include <net/netfilter/nf_nat_helper.h> 27#include <net/netfilter/nf_nat_helper.h>
28#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
27 29
28int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, 30int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
29 struct nf_conn *ct, 31 struct nf_conn *ct,
@@ -63,23 +65,6 @@ static int ipv4_print_tuple(struct seq_file *s,
63 NIPQUAD(tuple->dst.u3.ip)); 65 NIPQUAD(tuple->dst.u3.ip));
64} 66}
65 67
66/* Returns new sk_buff, or NULL */
67static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
68{
69 int err;
70
71 skb_orphan(skb);
72
73 local_bh_disable();
74 err = ip_defrag(skb, user);
75 local_bh_enable();
76
77 if (!err)
78 ip_send_check(ip_hdr(skb));
79
80 return err;
81}
82
83static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, 68static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
84 unsigned int *dataoff, u_int8_t *protonum) 69 unsigned int *dataoff, u_int8_t *protonum)
85{ 70{
@@ -144,28 +129,6 @@ out:
144 return nf_conntrack_confirm(skb); 129 return nf_conntrack_confirm(skb);
145} 130}
146 131
147static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
148 struct sk_buff *skb,
149 const struct net_device *in,
150 const struct net_device *out,
151 int (*okfn)(struct sk_buff *))
152{
153 /* Previously seen (loopback)? Ignore. Do this before
154 fragment check. */
155 if (skb->nfct)
156 return NF_ACCEPT;
157
158 /* Gather fragments. */
159 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
160 if (nf_ct_ipv4_gather_frags(skb,
161 hooknum == NF_INET_PRE_ROUTING ?
162 IP_DEFRAG_CONNTRACK_IN :
163 IP_DEFRAG_CONNTRACK_OUT))
164 return NF_STOLEN;
165 }
166 return NF_ACCEPT;
167}
168
169static unsigned int ipv4_conntrack_in(unsigned int hooknum, 132static unsigned int ipv4_conntrack_in(unsigned int hooknum,
170 struct sk_buff *skb, 133 struct sk_buff *skb,
171 const struct net_device *in, 134 const struct net_device *in,
@@ -195,13 +158,6 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
195 make it the first hook. */ 158 make it the first hook. */
196static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { 159static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
197 { 160 {
198 .hook = ipv4_conntrack_defrag,
199 .owner = THIS_MODULE,
200 .pf = PF_INET,
201 .hooknum = NF_INET_PRE_ROUTING,
202 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
203 },
204 {
205 .hook = ipv4_conntrack_in, 161 .hook = ipv4_conntrack_in,
206 .owner = THIS_MODULE, 162 .owner = THIS_MODULE,
207 .pf = PF_INET, 163 .pf = PF_INET,
@@ -209,13 +165,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
209 .priority = NF_IP_PRI_CONNTRACK, 165 .priority = NF_IP_PRI_CONNTRACK,
210 }, 166 },
211 { 167 {
212 .hook = ipv4_conntrack_defrag,
213 .owner = THIS_MODULE,
214 .pf = PF_INET,
215 .hooknum = NF_INET_LOCAL_OUT,
216 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
217 },
218 {
219 .hook = ipv4_conntrack_local, 168 .hook = ipv4_conntrack_local,
220 .owner = THIS_MODULE, 169 .owner = THIS_MODULE,
221 .pf = PF_INET, 170 .pf = PF_INET,
@@ -422,6 +371,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
422 int ret = 0; 371 int ret = 0;
423 372
424 need_conntrack(); 373 need_conntrack();
374 nf_defrag_ipv4_enable();
425 375
426 ret = nf_register_sockopt(&so_getorigdst); 376 ret = nf_register_sockopt(&so_getorigdst);
427 if (ret < 0) { 377 if (ret < 0) {
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
new file mode 100644
index 000000000000..aa2c50a180f7
--- /dev/null
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -0,0 +1,96 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/types.h>
10#include <linux/ip.h>
11#include <linux/netfilter.h>
12#include <linux/module.h>
13#include <linux/skbuff.h>
14#include <net/route.h>
15#include <net/ip.h>
16
17#include <linux/netfilter_ipv4.h>
18#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
19
20/* Returns new sk_buff, or NULL */
21static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
22{
23 int err;
24
25 skb_orphan(skb);
26
27 local_bh_disable();
28 err = ip_defrag(skb, user);
29 local_bh_enable();
30
31 if (!err)
32 ip_send_check(ip_hdr(skb));
33
34 return err;
35}
36
37static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
38 struct sk_buff *skb,
39 const struct net_device *in,
40 const struct net_device *out,
41 int (*okfn)(struct sk_buff *))
42{
43#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
44 /* Previously seen (loopback)? Ignore. Do this before
45 fragment check. */
46 if (skb->nfct)
47 return NF_ACCEPT;
48#endif
49
50 /* Gather fragments. */
51 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
52 if (nf_ct_ipv4_gather_frags(skb,
53 hooknum == NF_INET_PRE_ROUTING ?
54 IP_DEFRAG_CONNTRACK_IN :
55 IP_DEFRAG_CONNTRACK_OUT))
56 return NF_STOLEN;
57 }
58 return NF_ACCEPT;
59}
60
61static struct nf_hook_ops ipv4_defrag_ops[] = {
62 {
63 .hook = ipv4_conntrack_defrag,
64 .owner = THIS_MODULE,
65 .pf = PF_INET,
66 .hooknum = NF_INET_PRE_ROUTING,
67 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
68 },
69 {
70 .hook = ipv4_conntrack_defrag,
71 .owner = THIS_MODULE,
72 .pf = PF_INET,
73 .hooknum = NF_INET_LOCAL_OUT,
74 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
75 },
76};
77
78static int __init nf_defrag_init(void)
79{
80 return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
81}
82
83static void __exit nf_defrag_fini(void)
84{
85 nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
86}
87
88void nf_defrag_ipv4_enable(void)
89{
90}
91EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
92
93module_init(nf_defrag_init);
94module_exit(nf_defrag_fini);
95
96MODULE_LICENSE("GPL");