Root/target/linux/generic-2.4/patches/628-netfilter_raw.patch

1--- a/Documentation/Configure.help
2+++ b/Documentation/Configure.help
3@@ -3057,6 +3057,34 @@ CONFIG_IP_NF_FILTER
4   If you want to compile it as a module, say M here and read
5   <file:Documentation/modules.txt>. If unsure, say `N'.
6 
7+raw table support (required for NOTRACK/TRACE)
8+CONFIG_IP_NF_RAW
9+ This option adds a `raw' table to iptables. This table is the very
10+ first in the netfilter framework and hooks in at the PREROUTING
11+ and OUTPUT chains.
12+
13+ If you want to compile it as a module, say M here and read
14+ <file:Documentation/modules.txt>. If unsure, say `N'.
15+
16+NOTRACK target support
17+CONFIG_IP_NF_TARGET_NOTRACK
18+ The NOTRACK target allows a select rule to specify
19+ which packets *not* to enter the conntrack/NAT
20+ subsystem with all the consequences (no ICMP error tracking,
21+ no protocol helpers for the selected packets).
22+
23+ If you want to compile it as a module, say M here and read
24+ <file:Documentation/modules.txt>. If unsure, say `N'.
25+
26+raw table support (required for TRACE)
27+CONFIG_IP6_NF_RAW
28+ This option adds a `raw' table to ip6tables. This table is the very
29+ first in the netfilter framework and hooks in at the PREROUTING
30+ and OUTPUT chains.
31+
32+ If you want to compile it as a module, say M here and read
33+ <file:Documentation/modules.txt>. If unsure, say `N'.
34+
35 REJECT target support
36 CONFIG_IP_NF_TARGET_REJECT
37   The REJECT target allows a filtering rule to specify that an ICMP
38--- a/include/linux/netfilter_ipv4/ip_conntrack.h
39+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
40@@ -286,6 +286,9 @@ extern void ip_ct_refresh_acct(struct ip
41 /* Call me when a conntrack is destroyed. */
42 extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
43 
44+/* Fake conntrack entry for untracked connections */
45+extern struct ip_conntrack ip_conntrack_untracked;
46+
47 /* Returns new sk_buff, or NULL */
48 struct sk_buff *
49 ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user);
50--- a/include/linux/netfilter_ipv4/ipt_conntrack.h
51+++ b/include/linux/netfilter_ipv4/ipt_conntrack.h
52@@ -10,6 +10,7 @@
53 
54 #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
55 #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
56+#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
57 
58 /* flags, invflags: */
59 #define IPT_CONNTRACK_STATE 0x01
60--- a/include/linux/netfilter_ipv4/ipt_state.h
61+++ b/include/linux/netfilter_ipv4/ipt_state.h
62@@ -4,6 +4,8 @@
63 #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
64 #define IPT_STATE_INVALID (1 << 0)
65 
66+#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
67+
68 struct ipt_state_info
69 {
70     unsigned int statemask;
71--- a/include/linux/netfilter_ipv4.h
72+++ b/include/linux/netfilter_ipv4.h
73@@ -51,6 +51,8 @@
74 
75 enum nf_ip_hook_priorities {
76     NF_IP_PRI_FIRST = INT_MIN,
77+ NF_IP_PRI_CONNTRACK_DEFRAG = -400,
78+ NF_IP_PRI_RAW = -300,
79     NF_IP_PRI_CONNTRACK = -200,
80     NF_IP_PRI_MANGLE = -150,
81     NF_IP_PRI_NAT_DST = -100,
82--- a/net/ipv4/netfilter/Config.in
83+++ b/net/ipv4/netfilter/Config.in
84@@ -153,6 +153,15 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ];
85   dep_tristate ' TTL target support' CONFIG_IP_NF_TARGET_TTL $CONFIG_IP_NF_IPTABLES
86   dep_tristate ' ULOG target support' CONFIG_IP_NF_TARGET_ULOG $CONFIG_IP_NF_IPTABLES
87   dep_tristate ' TCPMSS target support' CONFIG_IP_NF_TARGET_TCPMSS $CONFIG_IP_NF_IPTABLES
88+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
89+ tristate ' raw table support (required for NOTRACK/TRACE)' CONFIG_IP_NF_RAW $CONFIG_IP_NF_IPTABLES
90+ fi
91+ if [ "$CONFIG_IP_NF_RAW" != "n" ]; then
92+ if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
93+ dep_tristate ' NOTRACK target support' CONFIG_IP_NF_TARGET_NOTRACK $CONFIG_IP_NF_RAW
94+ fi
95+ # Marker for TRACE target
96+ fi
97 fi
98 
99 tristate 'ARP tables support' CONFIG_IP_NF_ARPTABLES
100--- a/net/ipv4/netfilter/ip_conntrack_core.c
101+++ b/net/ipv4/netfilter/ip_conntrack_core.c
102@@ -64,6 +64,7 @@ int ip_conntrack_max = 0;
103 static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
104 struct list_head *ip_conntrack_hash;
105 static kmem_cache_t *ip_conntrack_cachep;
106+struct ip_conntrack ip_conntrack_untracked;
107 static LIST_HEAD(unconfirmed);
108 
109 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
110@@ -834,6 +835,15 @@ unsigned int ip_conntrack_in(unsigned in
111     int set_reply;
112     int ret;
113 
114+ /* Never happen */
115+ if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
116+ if (net_ratelimit()) {
117+ printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",
118+ (*pskb)->nh.iph->protocol, hooknum);
119+ }
120+ return NF_DROP;
121+ }
122+
123     /* FIXME: Do this right please. --RR */
124     (*pskb)->nfcache |= NFC_UNKNOWN;
125 
126@@ -1489,6 +1499,18 @@ int __init ip_conntrack_init(void)
127 
128     /* For use by ipt_REJECT */
129     ip_ct_attach = ip_conntrack_attach;
130+
131+ /* Set up fake conntrack:
132+ - to never be deleted, not in any hashes */
133+ atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
134+ /* - and look it like as a confirmed connection */
135+ set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
136+ /* - and prepare the ctinfo field for REJECT/NAT. */
137+ ip_conntrack_untracked.infos[IP_CT_NEW].master =
138+ ip_conntrack_untracked.infos[IP_CT_RELATED].master =
139+ ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
140+ &ip_conntrack_untracked.ct_general;
141+
142     return ret;
143 
144 err_free_hash:
145--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
146+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
147@@ -218,6 +218,29 @@ static unsigned int ip_confirm(unsigned
148     return ip_conntrack_confirm(*pskb);
149 }
150 
151+static unsigned int ip_conntrack_defrag(unsigned int hooknum,
152+ struct sk_buff **pskb,
153+ const struct net_device *in,
154+ const struct net_device *out,
155+ int (*okfn)(struct sk_buff *))
156+{
157+ /* Previously seen (loopback)? Ignore. Do this before
158+ fragment check. */
159+ if ((*pskb)->nfct)
160+ return NF_ACCEPT;
161+
162+ /* Gather fragments. */
163+ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
164+ *pskb = ip_ct_gather_frags(*pskb,
165+ hooknum == NF_IP_PRE_ROUTING ?
166+ IP_DEFRAG_CONNTRACK_IN :
167+ IP_DEFRAG_CONNTRACK_OUT);
168+ if (!*pskb)
169+ return NF_STOLEN;
170+ }
171+ return NF_ACCEPT;
172+}
173+
174 static unsigned int ip_refrag(unsigned int hooknum,
175                   struct sk_buff **pskb,
176                   const struct net_device *in,
177@@ -259,9 +282,15 @@ static unsigned int ip_conntrack_local(u
178 
179 /* Connection tracking may drop packets, but never alters them, so
180    make it the first hook. */
181+static struct nf_hook_ops ip_conntrack_defrag_ops
182+= { { NULL, NULL }, ip_conntrack_defrag, PF_INET, NF_IP_PRE_ROUTING,
183+ NF_IP_PRI_CONNTRACK_DEFRAG };
184 static struct nf_hook_ops ip_conntrack_in_ops
185 = { { NULL, NULL }, ip_conntrack_in, PF_INET, NF_IP_PRE_ROUTING,
186     NF_IP_PRI_CONNTRACK };
187+static struct nf_hook_ops ip_conntrack_defrag_local_out_ops
188+= { { NULL, NULL }, ip_conntrack_defrag, PF_INET, NF_IP_LOCAL_OUT,
189+ NF_IP_PRI_CONNTRACK_DEFRAG };
190 static struct nf_hook_ops ip_conntrack_local_out_ops
191 = { { NULL, NULL }, ip_conntrack_local, PF_INET, NF_IP_LOCAL_OUT,
192     NF_IP_PRI_CONNTRACK };
193@@ -382,10 +411,20 @@ static int init_or_cleanup(int init)
194     if (!proc) goto cleanup_init;
195     proc->owner = THIS_MODULE;
196 
197+ ret = nf_register_hook(&ip_conntrack_defrag_ops);
198+ if (ret < 0) {
199+ printk("ip_conntrack: can't register pre-routing defrag hook.\n");
200+ goto cleanup_proc;
201+ }
202+ ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
203+ if (ret < 0) {
204+ printk("ip_conntrack: can't register local_out defrag hook.\n");
205+ goto cleanup_defragops;
206+ }
207     ret = nf_register_hook(&ip_conntrack_in_ops);
208     if (ret < 0) {
209         printk("ip_conntrack: can't register pre-routing hook.\n");
210- goto cleanup_proc;
211+ goto cleanup_defraglocalops;
212     }
213     ret = nf_register_hook(&ip_conntrack_local_out_ops);
214     if (ret < 0) {
215@@ -423,6 +462,10 @@ static int init_or_cleanup(int init)
216     nf_unregister_hook(&ip_conntrack_local_out_ops);
217  cleanup_inops:
218     nf_unregister_hook(&ip_conntrack_in_ops);
219+ cleanup_defraglocalops:
220+ nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
221+ cleanup_defragops:
222+ nf_unregister_hook(&ip_conntrack_defrag_ops);
223  cleanup_proc:
224     proc_net_remove("ip_conntrack");
225  cleanup_init:
226@@ -512,5 +555,6 @@ EXPORT_SYMBOL(ip_conntrack_htable_size);
227 EXPORT_SYMBOL(ip_conntrack_expect_list);
228 EXPORT_SYMBOL(ip_conntrack_lock);
229 EXPORT_SYMBOL(ip_conntrack_hash);
230+EXPORT_SYMBOL(ip_conntrack_untracked);
231 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
232 EXPORT_SYMBOL_GPL(ip_conntrack_put);
233--- a/net/ipv4/netfilter/ip_nat_core.c
234+++ b/net/ipv4/netfilter/ip_nat_core.c
235@@ -1023,6 +1023,10 @@ int __init ip_nat_init(void)
236     /* FIXME: Man, this is a hack. <SIGH> */
237     IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
238     ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
239+
240+ /* Initialize fake conntrack so that NAT will skip it */
241+ ip_conntrack_untracked.nat.info.initialized |=
242+ (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
243 
244     return 0;
245 }
246--- /dev/null
247+++ b/net/ipv4/netfilter/iptable_raw.c
248@@ -0,0 +1,149 @@
249+/*
250+ * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
251+ *
252+ * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
253+ */
254+#include <linux/module.h>
255+#include <linux/netfilter_ipv4/ip_tables.h>
256+
257+#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
258+
259+/* Standard entry. */
260+struct ipt_standard
261+{
262+ struct ipt_entry entry;
263+ struct ipt_standard_target target;
264+};
265+
266+struct ipt_error_target
267+{
268+ struct ipt_entry_target target;
269+ char errorname[IPT_FUNCTION_MAXNAMELEN];
270+};
271+
272+struct ipt_error
273+{
274+ struct ipt_entry entry;
275+ struct ipt_error_target target;
276+};
277+
278+static struct
279+{
280+ struct ipt_replace repl;
281+ struct ipt_standard entries[2];
282+ struct ipt_error term;
283+} initial_table __initdata
284+= { { "raw", RAW_VALID_HOOKS, 3,
285+ sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
286+ { [NF_IP_PRE_ROUTING] 0,
287+ [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
288+ { [NF_IP_PRE_ROUTING] 0,
289+ [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
290+ 0, NULL, { } },
291+ {
292+ /* PRE_ROUTING */
293+ { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
294+ 0,
295+ sizeof(struct ipt_entry),
296+ sizeof(struct ipt_standard),
297+ 0, { 0, 0 }, { } },
298+ { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
299+ -NF_ACCEPT - 1 } },
300+ /* LOCAL_OUT */
301+ { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
302+ 0,
303+ sizeof(struct ipt_entry),
304+ sizeof(struct ipt_standard),
305+ 0, { 0, 0 }, { } },
306+ { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
307+ -NF_ACCEPT - 1 } }
308+ },
309+ /* ERROR */
310+ { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
311+ 0,
312+ sizeof(struct ipt_entry),
313+ sizeof(struct ipt_error),
314+ 0, { 0, 0 }, { } },
315+ { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
316+ { } },
317+ "ERROR"
318+ }
319+ }
320+};
321+
322+static struct ipt_table packet_raw = {
323+ .name = "raw",
324+ .table = &initial_table.repl,
325+ .valid_hooks = RAW_VALID_HOOKS,
326+ .lock = RW_LOCK_UNLOCKED,
327+ .me = THIS_MODULE
328+};
329+
330+/* The work comes in here from netfilter.c. */
331+static unsigned int
332+ipt_hook(unsigned int hook,
333+ struct sk_buff **pskb,
334+ const struct net_device *in,
335+ const struct net_device *out,
336+ int (*okfn)(struct sk_buff *))
337+{
338+ return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
339+}
340+
341+/* 'raw' is the very first table. */
342+static struct nf_hook_ops ipt_ops[] = {
343+ {
344+ .hook = ipt_hook,
345+ .pf = PF_INET,
346+ .hooknum = NF_IP_PRE_ROUTING,
347+ .priority = NF_IP_PRI_RAW
348+ },
349+ {
350+ .hook = ipt_hook,
351+ .pf = PF_INET,
352+ .hooknum = NF_IP_LOCAL_OUT,
353+ .priority = NF_IP_PRI_RAW
354+ },
355+};
356+
357+static int __init init(void)
358+{
359+ int ret;
360+
361+ /* Register table */
362+ ret = ipt_register_table(&packet_raw);
363+ if (ret < 0)
364+ return ret;
365+
366+ /* Register hooks */
367+ ret = nf_register_hook(&ipt_ops[0]);
368+ if (ret < 0)
369+ goto cleanup_table;
370+
371+ ret = nf_register_hook(&ipt_ops[1]);
372+ if (ret < 0)
373+ goto cleanup_hook0;
374+
375+ return ret;
376+
377+ cleanup_hook0:
378+ nf_unregister_hook(&ipt_ops[0]);
379+ cleanup_table:
380+ ipt_unregister_table(&packet_raw);
381+
382+ return ret;
383+}
384+
385+static void __exit fini(void)
386+{
387+ unsigned int i;
388+
389+ for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
390+ nf_unregister_hook(&ipt_ops[i]);
391+
392+ ipt_unregister_table(&packet_raw);
393+}
394+
395+module_init(init);
396+module_exit(fini);
397+MODULE_LICENSE("GPL");
398--- a/net/ipv4/netfilter/ipt_conntrack.c
399+++ b/net/ipv4/netfilter/ipt_conntrack.c
400@@ -27,11 +27,13 @@ match(const struct sk_buff *skb,
401 
402 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
403 
404- if (ct)
405- statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
406- else
407- statebit = IPT_CONNTRACK_STATE_INVALID;
408-
409+ if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
410+ statebit = IPT_CONNTRACK_STATE_UNTRACKED;
411+ else if (ct)
412+ statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
413+ else
414+ statebit = IPT_CONNTRACK_STATE_INVALID;
415+
416     if(sinfo->flags & IPT_CONNTRACK_STATE) {
417         if (ct) {
418             if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip !=
419--- /dev/null
420+++ b/net/ipv4/netfilter/ipt_NOTRACK.c
421@@ -0,0 +1,75 @@
422+/* This is a module which is used for setting up fake conntracks
423+ * on packets so that they are not seen by the conntrack/NAT code.
424+ */
425+#include <linux/module.h>
426+#include <linux/skbuff.h>
427+
428+#include <linux/netfilter_ipv4/ip_tables.h>
429+#include <linux/netfilter_ipv4/ip_conntrack.h>
430+
431+static unsigned int
432+target(struct sk_buff **pskb,
433+ unsigned int hooknum,
434+ const struct net_device *in,
435+ const struct net_device *out,
436+ const void *targinfo,
437+ void *userinfo)
438+{
439+ /* Previously seen (loopback)? Ignore. */
440+ if ((*pskb)->nfct != NULL)
441+ return IPT_CONTINUE;
442+
443+ /* Attach fake conntrack entry.
444+ If there is a real ct entry correspondig to this packet,
445+ it'll hang aroun till timing out. We don't deal with it
446+ for performance reasons. JK */
447+ (*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW];
448+ nf_conntrack_get((*pskb)->nfct);
449+
450+ return IPT_CONTINUE;
451+}
452+
453+static int
454+checkentry(const char *tablename,
455+ const struct ipt_entry *e,
456+ void *targinfo,
457+ unsigned int targinfosize,
458+ unsigned int hook_mask)
459+{
460+ if (targinfosize != 0) {
461+ printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n",
462+ targinfosize);
463+ return 0;
464+ }
465+
466+ if (strcmp(tablename, "raw") != 0) {
467+ printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename);
468+ return 0;
469+ }
470+
471+ return 1;
472+}
473+
474+static struct ipt_target ipt_notrack_reg = {
475+ .name = "NOTRACK",
476+ .target = target,
477+ .checkentry = checkentry,
478+ .me = THIS_MODULE
479+};
480+
481+static int __init init(void)
482+{
483+ if (ipt_register_target(&ipt_notrack_reg))
484+ return -EINVAL;
485+
486+ return 0;
487+}
488+
489+static void __exit fini(void)
490+{
491+ ipt_unregister_target(&ipt_notrack_reg);
492+}
493+
494+module_init(init);
495+module_exit(fini);
496+MODULE_LICENSE("GPL");
497--- a/net/ipv4/netfilter/ipt_state.c
498+++ b/net/ipv4/netfilter/ipt_state.c
499@@ -21,7 +21,9 @@ match(const struct sk_buff *skb,
500     enum ip_conntrack_info ctinfo;
501     unsigned int statebit;
502 
503- if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
504+ if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
505+ statebit = IPT_STATE_UNTRACKED;
506+ else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
507         statebit = IPT_STATE_INVALID;
508     else
509         statebit = IPT_STATE_BIT(ctinfo);
510--- a/net/ipv4/netfilter/Makefile
511+++ b/net/ipv4/netfilter/Makefile
512@@ -77,6 +77,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_table
513 obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
514 obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
515 obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
516+obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
517 
518 # matches
519 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
520@@ -131,6 +132,7 @@ obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += i
521 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
522 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
523 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
524+obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
525 
526 # generic ARP tables
527 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
528--- a/net/ipv6/netfilter/Config.in
529+++ b/net/ipv6/netfilter/Config.in
530@@ -79,6 +79,10 @@ if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ];
531     dep_tristate ' IMQ target support' CONFIG_IP6_NF_TARGET_IMQ $CONFIG_IP6_NF_MANGLE
532   fi
533   #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
534+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
535+ tristate ' raw table support (required for TRACE)' CONFIG_IP6_NF_RAW $CONFIG_IP6_NF_IPTABLES
536+ fi
537+ # Marker for TRACE target
538 fi
539 
540 endmenu
541--- /dev/null
542+++ b/net/ipv6/netfilter/ip6table_raw.c
543@@ -0,0 +1,154 @@
544+/*
545+ * IPv6 raw table, a port of the IPv4 raw table to IPv6
546+ *
547+ * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
548+ */
549+#include <linux/module.h>
550+#include <linux/netfilter_ipv6/ip6_tables.h>
551+
552+#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
553+
554+#if 0
555+#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
556+#else
557+#define DEBUGP(x, args...)
558+#endif
559+
560+/* Standard entry. */
561+struct ip6t_standard
562+{
563+ struct ip6t_entry entry;
564+ struct ip6t_standard_target target;
565+};
566+
567+struct ip6t_error_target
568+{
569+ struct ip6t_entry_target target;
570+ char errorname[IP6T_FUNCTION_MAXNAMELEN];
571+};
572+
573+struct ip6t_error
574+{
575+ struct ip6t_entry entry;
576+ struct ip6t_error_target target;
577+};
578+
579+static struct
580+{
581+ struct ip6t_replace repl;
582+ struct ip6t_standard entries[2];
583+ struct ip6t_error term;
584+} initial_table __initdata
585+= { { "raw", RAW_VALID_HOOKS, 3,
586+ sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
587+ { [NF_IP6_PRE_ROUTING] 0,
588+ [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
589+ { [NF_IP6_PRE_ROUTING] 0,
590+ [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
591+ 0, NULL, { } },
592+ {
593+ /* PRE_ROUTING */
594+ { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
595+ 0,
596+ sizeof(struct ip6t_entry),
597+ sizeof(struct ip6t_standard),
598+ 0, { 0, 0 }, { } },
599+ { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
600+ -NF_ACCEPT - 1 } },
601+ /* LOCAL_OUT */
602+ { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
603+ 0,
604+ sizeof(struct ip6t_entry),
605+ sizeof(struct ip6t_standard),
606+ 0, { 0, 0 }, { } },
607+ { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
608+ -NF_ACCEPT - 1 } },
609+ },
610+ /* ERROR */
611+ { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
612+ 0,
613+ sizeof(struct ip6t_entry),
614+ sizeof(struct ip6t_error),
615+ 0, { 0, 0 }, { } },
616+ { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
617+ { } },
618+ "ERROR"
619+ }
620+ }
621+};
622+
623+static struct ip6t_table packet_raw = {
624+ .name = "raw",
625+ .table = &initial_table.repl,
626+ .valid_hooks = RAW_VALID_HOOKS,
627+ .lock = RW_LOCK_UNLOCKED,
628+ .me = THIS_MODULE
629+};
630+
631+/* The work comes in here from netfilter.c. */
632+static unsigned int
633+ip6t_hook(unsigned int hook,
634+ struct sk_buff **pskb,
635+ const struct net_device *in,
636+ const struct net_device *out,
637+ int (*okfn)(struct sk_buff *))
638+{
639+ return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL);
640+}
641+
642+static struct nf_hook_ops ip6t_ops[] = {
643+ {
644+ .hook = ip6t_hook,
645+ .pf = PF_INET6,
646+ .hooknum = NF_IP6_PRE_ROUTING,
647+ .priority = NF_IP6_PRI_FIRST
648+ },
649+ {
650+ .hook = ip6t_hook,
651+ .pf = PF_INET6,
652+ .hooknum = NF_IP6_LOCAL_OUT,
653+ .priority = NF_IP6_PRI_FIRST
654+ },
655+};
656+
657+static int __init init(void)
658+{
659+ int ret;
660+
661+ /* Register table */
662+ ret = ip6t_register_table(&packet_raw);
663+ if (ret < 0)
664+ return ret;
665+
666+ /* Register hooks */
667+ ret = nf_register_hook(&ip6t_ops[0]);
668+ if (ret < 0)
669+ goto cleanup_table;
670+
671+ ret = nf_register_hook(&ip6t_ops[1]);
672+ if (ret < 0)
673+ goto cleanup_hook0;
674+
675+ return ret;
676+
677+ cleanup_hook0:
678+ nf_unregister_hook(&ip6t_ops[0]);
679+ cleanup_table:
680+ ip6t_unregister_table(&packet_raw);
681+
682+ return ret;
683+}
684+
685+static void __exit fini(void)
686+{
687+ unsigned int i;
688+
689+ for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
690+ nf_unregister_hook(&ip6t_ops[i]);
691+
692+ ip6t_unregister_table(&packet_raw);
693+}
694+
695+module_init(init);
696+module_exit(fini);
697+MODULE_LICENSE("GPL");
698--- a/net/ipv6/netfilter/Makefile
699+++ b/net/ipv6/netfilter/Makefile
700@@ -32,6 +32,7 @@ obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t
701 obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o
702 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
703 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
704+obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
705 obj-$(CONFIG_IP6_NF_MATCH_RANDOM) += ip6t_random.o
706 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
707 obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
708

Archive Download this file



interactive