Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
[deliverable/linux.git] / net / ipv6 / netfilter / ip6table_filter.c
1 /*
2 * This is the 1999 rewrite of IP Firewalling, aiming for kernel 2.3.x.
3 *
4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
5 * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12 #include <linux/module.h>
13 #include <linux/moduleparam.h>
14 #include <linux/netfilter_ipv6/ip6_tables.h>
15
16 MODULE_LICENSE("GPL");
17 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
18 MODULE_DESCRIPTION("ip6tables filter table");
19
20 #define FILTER_VALID_HOOKS ((1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) | (1 << NF_IP6_LOCAL_OUT))
21
22 static struct
23 {
24 struct ip6t_replace repl;
25 struct ip6t_standard entries[3];
26 struct ip6t_error term;
27 } initial_table __initdata
28 = { { "filter", FILTER_VALID_HOOKS, 4,
29 sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
30 { [NF_IP6_LOCAL_IN] = 0,
31 [NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
32 [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 },
33 { [NF_IP6_LOCAL_IN] = 0,
34 [NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
35 [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 },
36 0, NULL, { } },
37 {
38 /* LOCAL_IN */
39 { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
40 0,
41 sizeof(struct ip6t_entry),
42 sizeof(struct ip6t_standard),
43 0, { 0, 0 }, { } },
44 { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
45 -NF_ACCEPT - 1 } },
46 /* FORWARD */
47 { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
48 0,
49 sizeof(struct ip6t_entry),
50 sizeof(struct ip6t_standard),
51 0, { 0, 0 }, { } },
52 { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
53 -NF_ACCEPT - 1 } },
54 /* LOCAL_OUT */
55 { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
56 0,
57 sizeof(struct ip6t_entry),
58 sizeof(struct ip6t_standard),
59 0, { 0, 0 }, { } },
60 { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
61 -NF_ACCEPT - 1 } }
62 },
63 /* ERROR */
64 { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
65 0,
66 sizeof(struct ip6t_entry),
67 sizeof(struct ip6t_error),
68 0, { 0, 0 }, { } },
69 { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
70 { } },
71 "ERROR"
72 }
73 }
74 };
75
76 static struct xt_table packet_filter = {
77 .name = "filter",
78 .valid_hooks = FILTER_VALID_HOOKS,
79 .lock = RW_LOCK_UNLOCKED,
80 .me = THIS_MODULE,
81 .af = AF_INET6,
82 };
83
84 /* The work comes in here from netfilter.c. */
85 static unsigned int
86 ip6t_hook(unsigned int hook,
87 struct sk_buff **pskb,
88 const struct net_device *in,
89 const struct net_device *out,
90 int (*okfn)(struct sk_buff *))
91 {
92 return ip6t_do_table(pskb, hook, in, out, &packet_filter);
93 }
94
95 static unsigned int
96 ip6t_local_out_hook(unsigned int hook,
97 struct sk_buff **pskb,
98 const struct net_device *in,
99 const struct net_device *out,
100 int (*okfn)(struct sk_buff *))
101 {
102 #if 0
103 /* root is playing with raw sockets. */
104 if ((*pskb)->len < sizeof(struct iphdr)
105 || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
106 if (net_ratelimit())
107 printk("ip6t_hook: happy cracking.\n");
108 return NF_ACCEPT;
109 }
110 #endif
111
112 return ip6t_do_table(pskb, hook, in, out, &packet_filter);
113 }
114
115 static struct nf_hook_ops ip6t_ops[] = {
116 {
117 .hook = ip6t_hook,
118 .owner = THIS_MODULE,
119 .pf = PF_INET6,
120 .hooknum = NF_IP6_LOCAL_IN,
121 .priority = NF_IP6_PRI_FILTER,
122 },
123 {
124 .hook = ip6t_hook,
125 .owner = THIS_MODULE,
126 .pf = PF_INET6,
127 .hooknum = NF_IP6_FORWARD,
128 .priority = NF_IP6_PRI_FILTER,
129 },
130 {
131 .hook = ip6t_local_out_hook,
132 .owner = THIS_MODULE,
133 .pf = PF_INET6,
134 .hooknum = NF_IP6_LOCAL_OUT,
135 .priority = NF_IP6_PRI_FILTER,
136 },
137 };
138
139 /* Default to forward because I got too much mail already. */
140 static int forward = NF_ACCEPT;
141 module_param(forward, bool, 0000);
142
143 static int __init ip6table_filter_init(void)
144 {
145 int ret;
146
147 if (forward < 0 || forward > NF_MAX_VERDICT) {
148 printk("iptables forward must be 0 or 1\n");
149 return -EINVAL;
150 }
151
152 /* Entry 1 is the FORWARD hook */
153 initial_table.entries[1].target.verdict = -forward - 1;
154
155 /* Register table */
156 ret = ip6t_register_table(&packet_filter, &initial_table.repl);
157 if (ret < 0)
158 return ret;
159
160 /* Register hooks */
161 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
162 if (ret < 0)
163 goto cleanup_table;
164
165 return ret;
166
167 cleanup_table:
168 ip6t_unregister_table(&packet_filter);
169 return ret;
170 }
171
172 static void __exit ip6table_filter_fini(void)
173 {
174 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
175 ip6t_unregister_table(&packet_filter);
176 }
177
178 module_init(ip6table_filter_init);
179 module_exit(ip6table_filter_fini);
This page took 0.034363 seconds and 5 git commands to generate.