]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/patch-o-matic-ng-raw_2.4.31.patch
Wir kehren zurueck zu Kudzu, da hwinfo noch mehr Aerger macht.
[people/teissler/ipfire-2.x.git] / src / patches / patch-o-matic-ng-raw_2.4.31.patch
1 Patch found at http://patchwork.netfilter.org/netfilter-devel/patch.pl?id=2663
2 Thank to Roberto Nibali for his work
3
4 diff -Nur linux-2.4.31-orig/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.31-pab2/include/linux/netfilter_ipv4/ip_conntrack.h
5 --- linux-2.4.31-orig/include/linux/netfilter_ipv4/ip_conntrack.h 2005-04-04 03:42:20 +0200
6 +++ linux-2.4.31-pab2/include/linux/netfilter_ipv4/ip_conntrack.h 2005-06-29 12:23:37 +0200
7 @@ -249,6 +249,9 @@
8 /* Call me when a conntrack is destroyed. */
9 extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
10
11 +/* Fake conntrack entry for untracked connections */
12 +extern struct ip_conntrack ip_conntrack_untracked;
13 +
14 /* Returns new sk_buff, or NULL */
15 struct sk_buff *
16 ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user);
17 diff -Nur linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_conntrack.h linux-2.4.31-pab2/include/linux/netfilter_ipv4/ipt_conntrack.h
18 --- linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_conntrack.h 2002-11-29 00:53:15 +0100
19 +++ linux-2.4.31-pab2/include/linux/netfilter_ipv4/ipt_conntrack.h 2005-06-29 12:23:37 +0200
20 @@ -10,6 +10,7 @@
21
22 #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
23 #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
24 +#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
25
26 /* flags, invflags: */
27 #define IPT_CONNTRACK_STATE 0x01
28 diff -Nur linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_state.h linux-2.4.31-pab2/include/linux/netfilter_ipv4/ipt_state.h
29 --- linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_state.h 2000-04-14 18:37:20 +0200
30 +++ linux-2.4.31-pab2/include/linux/netfilter_ipv4/ipt_state.h 2005-06-29 12:23:37 +0200
31 @@ -3,6 +3,7 @@
32
33 #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
34 #define IPT_STATE_INVALID (1 << 0)
35 +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
36
37 struct ipt_state_info
38 {
39 diff -Nur linux-2.4.31-orig/include/linux/netfilter_ipv4.h linux-2.4.31-pab2/include/linux/netfilter_ipv4.h
40 --- linux-2.4.31-orig/include/linux/netfilter_ipv4.h 2002-02-25 20:38:13 +0100
41 +++ linux-2.4.31-pab2/include/linux/netfilter_ipv4.h 2005-06-29 12:23:37 +0200
42 @@ -51,6 +51,8 @@
43
44 enum nf_ip_hook_priorities {
45 NF_IP_PRI_FIRST = INT_MIN,
46 + NF_IP_PRI_CONNTRACK_DEFRAG = -400,
47 + NF_IP_PRI_RAW = -300,
48 NF_IP_PRI_CONNTRACK = -200,
49 NF_IP_PRI_MANGLE = -150,
50 NF_IP_PRI_NAT_DST = -100,
51 diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.31-pab2/net/ipv4/netfilter/ip_conntrack_core.c
52 --- linux-2.4.31-orig/net/ipv4/netfilter/ip_conntrack_core.c 2005-04-04 03:42:20 +0200
53 +++ linux-2.4.31-pab2/net/ipv4/netfilter/ip_conntrack_core.c 2005-06-29 12:42:09 +0200
54 @@ -65,6 +65,7 @@
55 struct list_head *ip_conntrack_hash;
56 static kmem_cache_t *ip_conntrack_cachep;
57 static LIST_HEAD(unconfirmed);
58 +struct ip_conntrack ip_conntrack_untracked;
59
60 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
61
62 @@ -823,6 +824,19 @@
63 int set_reply;
64 int ret;
65
66 + /* Previously seen (loopback or untracked)? Ignore. */
67 + if ((*pskb)->nfct)
68 + return NF_ACCEPT;
69 +
70 + /* Never happen */
71 + if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
72 + if (net_ratelimit()) {
73 + printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",
74 + (*pskb)->nh.iph->protocol, hooknum);
75 + }
76 + return NF_DROP;
77 + }
78 +
79 /* FIXME: Do this right please. --RR */
80 (*pskb)->nfcache |= NFC_UNKNOWN;
81
82 @@ -841,21 +855,6 @@
83 }
84 #endif
85
86 - /* Previously seen (loopback)? Ignore. Do this before
87 - fragment check. */
88 - if ((*pskb)->nfct)
89 - return NF_ACCEPT;
90 -
91 - /* Gather fragments. */
92 - if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
93 - *pskb = ip_ct_gather_frags(*pskb,
94 - hooknum == NF_IP_PRE_ROUTING ?
95 - IP_DEFRAG_CONNTRACK_IN :
96 - IP_DEFRAG_CONNTRACK_OUT);
97 - if (!*pskb)
98 - return NF_STOLEN;
99 - }
100 -
101 proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
102
103 /* It may be an icmp error... */
104 @@ -1392,6 +1391,8 @@
105 schedule();
106 goto i_see_dead_people;
107 }
108 + while (atomic_read(&ip_conntrack_untracked.ct_general.use) > 1)
109 + schedule();
110
111 kmem_cache_destroy(ip_conntrack_cachep);
112 vfree(ip_conntrack_hash);
113 @@ -1459,6 +1460,18 @@
114
115 /* For use by ipt_REJECT */
116 ip_ct_attach = ip_conntrack_attach;
117 +
118 + /* Set up fake conntrack:
119 + - never to be deleted, not in any hashes */
120 + atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
121 + /* - and let it look as if it's a confirmed connection */
122 + set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
123 + /* - and prepare the ctinfo field for REJECT/NAT. */
124 + ip_conntrack_untracked.infos[IP_CT_NEW].master =
125 + ip_conntrack_untracked.infos[IP_CT_RELATED].master =
126 + ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
127 + &ip_conntrack_untracked.ct_general;
128 +
129 return ret;
130
131 err_free_hash:
132 diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.31-pab2/net/ipv4/netfilter/ip_conntrack_standalone.c
133 --- linux-2.4.31-orig/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-04-04 03:42:20 +0200
134 +++ linux-2.4.31-pab2/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-06-29 12:23:37 +0200
135 @@ -189,6 +189,29 @@
136 return ip_conntrack_confirm(*pskb);
137 }
138
139 +static unsigned int ip_conntrack_defrag(unsigned int hooknum,
140 + struct sk_buff **pskb,
141 + const struct net_device *in,
142 + const struct net_device *out,
143 + int (*okfn)(struct sk_buff *))
144 +{
145 + /* Previously seen (loopback)? Ignore. Do this before
146 + * fragment check. */
147 + if ((*pskb)->nfct)
148 + return NF_ACCEPT;
149 +
150 + /* Gather fragments. */
151 + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
152 + *pskb = ip_ct_gather_frags(*pskb,
153 + hooknum == NF_IP_PRE_ROUTING ?
154 + IP_DEFRAG_CONNTRACK_IN :
155 + IP_DEFRAG_CONNTRACK_OUT);
156 + if (!*pskb)
157 + return NF_STOLEN;
158 + }
159 + return NF_ACCEPT;
160 +}
161 +
162 static unsigned int ip_refrag(unsigned int hooknum,
163 struct sk_buff **pskb,
164 const struct net_device *in,
165 @@ -230,9 +253,15 @@
166
167 /* Connection tracking may drop packets, but never alters them, so
168 make it the first hook. */
169 +static struct nf_hook_ops ip_conntrack_defrag_ops
170 += { { NULL, NULL }, ip_conntrack_defrag, PF_INET, NF_IP_PRE_ROUTING,
171 + NF_IP_PRI_CONNTRACK_DEFRAG };
172 static struct nf_hook_ops ip_conntrack_in_ops
173 = { { NULL, NULL }, ip_conntrack_in, PF_INET, NF_IP_PRE_ROUTING,
174 NF_IP_PRI_CONNTRACK };
175 +static struct nf_hook_ops ip_conntrack_defrag_local_out_ops
176 += { { NULL, NULL }, ip_conntrack_defrag, PF_INET, NF_IP_LOCAL_OUT,
177 + NF_IP_PRI_CONNTRACK_DEFRAG };
178 static struct nf_hook_ops ip_conntrack_local_out_ops
179 = { { NULL, NULL }, ip_conntrack_local, PF_INET, NF_IP_LOCAL_OUT,
180 NF_IP_PRI_CONNTRACK };
181 @@ -353,10 +382,21 @@
182 if (!proc) goto cleanup_init;
183 proc->owner = THIS_MODULE;
184
185 + ret = nf_register_hook(&ip_conntrack_defrag_ops);
186 + if (ret < 0) {
187 + printk("ip_conntrack: can't register pre-routing defrag hook.\n");
188 + goto cleanup_proc;
189 + }
190 + ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
191 + if (ret < 0) {
192 + printk("ip_conntrack: can't register local_out defrag hook.\n");
193 + goto cleanup_defragops;
194 + }
195 +
196 ret = nf_register_hook(&ip_conntrack_in_ops);
197 if (ret < 0) {
198 printk("ip_conntrack: can't register pre-routing hook.\n");
199 - goto cleanup_proc;
200 + goto cleanup_defraglocalops;
201 }
202 ret = nf_register_hook(&ip_conntrack_local_out_ops);
203 if (ret < 0) {
204 @@ -394,6 +434,10 @@
205 nf_unregister_hook(&ip_conntrack_local_out_ops);
206 cleanup_inops:
207 nf_unregister_hook(&ip_conntrack_in_ops);
208 + cleanup_defraglocalops:
209 + nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
210 + cleanup_defragops:
211 + nf_unregister_hook(&ip_conntrack_defrag_ops);
212 cleanup_proc:
213 proc_net_remove("ip_conntrack");
214 cleanup_init:
215 @@ -483,5 +527,6 @@
216 EXPORT_SYMBOL(ip_conntrack_expect_list);
217 EXPORT_SYMBOL(ip_conntrack_lock);
218 EXPORT_SYMBOL(ip_conntrack_hash);
219 +EXPORT_SYMBOL(ip_conntrack_untracked);
220 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
221 EXPORT_SYMBOL_GPL(ip_conntrack_put);
222 diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ip_nat_core.c linux-2.4.31-pab2/net/ipv4/netfilter/ip_nat_core.c
223 --- linux-2.4.31-orig/net/ipv4/netfilter/ip_nat_core.c 2005-04-04 03:42:20 +0200
224 +++ linux-2.4.31-pab2/net/ipv4/netfilter/ip_nat_core.c 2005-06-29 12:23:37 +0200
225 @@ -1024,6 +1024,10 @@
226 IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
227 ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
228
229 + /* Initialize fake conntrack so that NAT will skip it */
230 + ip_conntrack_untracked.nat.info.initialized |=
231 + (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
232 +
233 return 0;
234 }
235
236 diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ipt_conntrack.c linux-2.4.31-pab2/net/ipv4/netfilter/ipt_conntrack.c
237 --- linux-2.4.31-orig/net/ipv4/netfilter/ipt_conntrack.c 2004-02-18 14:36:32 +0100
238 +++ linux-2.4.31-pab2/net/ipv4/netfilter/ipt_conntrack.c 2005-06-29 12:23:37 +0200
239 @@ -27,7 +27,9 @@
240
241 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
242
243 - if (ct)
244 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
245 + statebit = IPT_CONNTRACK_STATE_UNTRACKED;
246 + else if (ct)
247 statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
248 else
249 statebit = IPT_CONNTRACK_STATE_INVALID;
250 diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ipt_state.c linux-2.4.31-pab2/net/ipv4/netfilter/ipt_state.c
251 --- linux-2.4.31-orig/net/ipv4/netfilter/ipt_state.c 2004-02-18 14:36:32 +0100
252 +++ linux-2.4.31-pab2/net/ipv4/netfilter/ipt_state.c 2005-06-29 12:23:37 +0200
253 @@ -21,7 +21,9 @@
254 enum ip_conntrack_info ctinfo;
255 unsigned int statebit;
256
257 - if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
258 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
259 + statebit = IPT_STATE_UNTRACKED;
260 + else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
261 statebit = IPT_STATE_INVALID;
262 else
263 statebit = IPT_STATE_BIT(ctinfo);