finally in sync with archive
[bcm963xx.git] / kernel / linux / net / ipv4 / netfilter / iptable_raw.c
1 /* 
2  * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
3  *
4  * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5  */
6 #include <linux/module.h>
7 #include <linux/netfilter_ipv4/ip_tables.h>
8
9 #define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
10
11 /* Standard entry. */
12 struct ipt_standard
13 {
14         struct ipt_entry entry;
15         struct ipt_standard_target target;
16 };
17
18 struct ipt_error_target
19 {
20         struct ipt_entry_target target;
21         char errorname[IPT_FUNCTION_MAXNAMELEN];
22 };
23
24 struct ipt_error
25 {
26         struct ipt_entry entry;
27         struct ipt_error_target target;
28 };
29
30 static struct
31 {
32         struct ipt_replace repl;
33         struct ipt_standard entries[2];
34         struct ipt_error term;
35 } initial_table __initdata = {
36         .repl = {
37                 .name = "raw", 
38                 .valid_hooks = RAW_VALID_HOOKS, 
39                 .num_entries = 3,
40                 .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
41                 .hook_entry = { 
42                         [NF_IP_PRE_ROUTING] = 0,
43                         [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) },
44                 .underflow = { 
45                         [NF_IP_PRE_ROUTING] = 0,
46                         [NF_IP_LOCAL_OUT]  = sizeof(struct ipt_standard) },
47         },
48         .entries = {
49              /* PRE_ROUTING */
50              { 
51                      .entry = { 
52                              .target_offset = sizeof(struct ipt_entry),
53                              .next_offset = sizeof(struct ipt_standard),
54                      },
55                      .target = { 
56                           .target = { 
57                                   .u = {
58                                           .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
59                                   },
60                           },
61                           .verdict = -NF_ACCEPT - 1,
62                      },
63              },
64
65              /* LOCAL_OUT */
66              {
67                      .entry = {
68                              .target_offset = sizeof(struct ipt_entry),
69                              .next_offset = sizeof(struct ipt_standard),
70                      },
71                      .target = {
72                              .target = {
73                                      .u = {
74                                              .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
75                                      },
76                              },
77                              .verdict = -NF_ACCEPT - 1,
78                      },
79              },
80         },
81         /* ERROR */
82         .term = {
83                 .entry = {
84                         .target_offset = sizeof(struct ipt_entry),
85                         .next_offset = sizeof(struct ipt_error),
86                 },
87                 .target = {
88                         .target = {
89                                 .u = {
90                                         .user = {
91                                                 .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)), 
92                                                 .name = IPT_ERROR_TARGET,
93                                         },
94                                 },
95                         },
96                         .errorname = "ERROR",
97                 },
98         }
99 };
100
101 static struct ipt_table packet_raw = { 
102         .name = "raw", 
103         .table = &initial_table.repl,
104         .valid_hooks =  RAW_VALID_HOOKS, 
105         .lock = RW_LOCK_UNLOCKED, 
106         .me = THIS_MODULE
107 };
108
109 /* The work comes in here from netfilter.c. */
110 static unsigned int
111 ipt_hook(unsigned int hook,
112          struct sk_buff **pskb,
113          const struct net_device *in,
114          const struct net_device *out,
115          int (*okfn)(struct sk_buff *))
116 {
117         return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
118 }
119
120 /* 'raw' is the very first table. */
121 static struct nf_hook_ops ipt_ops[] = {
122         {
123           .hook = ipt_hook, 
124           .pf = PF_INET, 
125           .hooknum = NF_IP_PRE_ROUTING, 
126           .priority = NF_IP_PRI_RAW
127         },
128         {
129           .hook = ipt_hook, 
130           .pf = PF_INET, 
131           .hooknum = NF_IP_LOCAL_OUT, 
132           .priority = NF_IP_PRI_RAW
133         },
134 };
135
136 static int __init init(void)
137 {
138         int ret;
139
140         /* Register table */
141         ret = ipt_register_table(&packet_raw);
142         if (ret < 0)
143                 return ret;
144
145         /* Register hooks */
146         ret = nf_register_hook(&ipt_ops[0]);
147         if (ret < 0)
148                 goto cleanup_table;
149
150         ret = nf_register_hook(&ipt_ops[1]);
151         if (ret < 0)
152                 goto cleanup_hook0;
153
154         return ret;
155
156  cleanup_hook0:
157         nf_unregister_hook(&ipt_ops[0]);
158  cleanup_table:
159         ipt_unregister_table(&packet_raw);
160
161         return ret;
162 }
163
164 static void __exit fini(void)
165 {
166         unsigned int i;
167
168         for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
169                 nf_unregister_hook(&ipt_ops[i]);
170
171         ipt_unregister_table(&packet_raw);
172 }
173
174 module_init(init);
175 module_exit(fini);
176 MODULE_LICENSE("GPL");