~vcs-imports/ipfire/ipfire-2.x

« back to all changes in this revision

Viewing changes to src/patches/patch-o-matic-ng-raw_2.4.31.patch

  • Committer: ipfire
  • Date: 2006-02-15 21:15:54 UTC
  • Revision ID: git-v1:cd1a2927226c734d96478e12bb768256fb64a06a


git-svn-id: http://svn.ipfire.org/svn/ipfire/IPFire/source@16 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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);