blob: 07fb710cd722f329ea297b764f50cfeb0ad8175e [file] [log] [blame]
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * '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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +09008#include <linux/slab.h>
Patrick McHardy802169a2007-05-10 14:17:36 -07009#include <net/ip.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010
Patrick McHardy6e23ae22007-11-19 18:53:30 -080011#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
Jan Engelhardt35aad0f2009-08-24 14:56:30 +020013static const struct xt_table packet_raw = {
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090014 .name = "raw",
15 .valid_hooks = RAW_VALID_HOOKS,
Harald Welte2e4e6a12006-01-12 13:30:04 -080016 .me = THIS_MODULE,
Jan Engelhardtf88e6a82009-06-13 06:25:44 +020017 .af = NFPROTO_IPV4,
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020018 .priority = NF_IP_PRI_RAW,
Linus Torvalds1da177e2005-04-16 15:20:36 -070019};
20
21/* The work comes in here from netfilter.c. */
22static unsigned int
Jan Engelhardt737535c2009-06-13 06:46:36 +020023iptable_raw_hook(unsigned int hook, struct sk_buff *skb,
24 const struct net_device *in, const struct net_device *out,
25 int (*okfn)(struct sk_buff *))
Linus Torvalds1da177e2005-04-16 15:20:36 -070026{
Jan Engelhardt2b21e052009-06-13 06:57:10 +020027 const struct net *net;
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
Jan Engelhardt2b21e052009-06-13 06:57:10 +020029 if (hook == NF_INET_LOCAL_OUT &&
30 (skb->len < sizeof(struct iphdr) ||
31 ip_hdrlen(skb) < sizeof(struct iphdr)))
32 /* root is playing with raw sockets. */
Patrick McHardy802169a2007-05-10 14:17:36 -070033 return NF_ACCEPT;
Jan Engelhardt2b21e052009-06-13 06:57:10 +020034
35 net = dev_net((in != NULL) ? in : out);
36 return ipt_do_table(skb, hook, in, out, net->ipv4.iptable_raw);
Patrick McHardy802169a2007-05-10 14:17:36 -070037}
38
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020039static struct nf_hook_ops *rawtable_ops __read_mostly;
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Alexey Dobriyan9335f042008-01-31 04:03:23 -080041static int __net_init iptable_raw_net_init(struct net *net)
42{
Jan Engelhardte3eaa992009-06-17 22:14:54 +020043 struct ipt_replace *repl;
44
45 repl = ipt_alloc_initial_table(&packet_raw);
46 if (repl == NULL)
47 return -ENOMEM;
Alexey Dobriyan9335f042008-01-31 04:03:23 -080048 net->ipv4.iptable_raw =
Jan Engelhardte3eaa992009-06-17 22:14:54 +020049 ipt_register_table(net, &packet_raw, repl);
50 kfree(repl);
Alexey Dobriyan9335f042008-01-31 04:03:23 -080051 if (IS_ERR(net->ipv4.iptable_raw))
52 return PTR_ERR(net->ipv4.iptable_raw);
53 return 0;
54}
55
56static void __net_exit iptable_raw_net_exit(struct net *net)
57{
Alexey Dobriyanf54e9362010-01-18 08:25:47 +010058 ipt_unregister_table(net, net->ipv4.iptable_raw);
Alexey Dobriyan9335f042008-01-31 04:03:23 -080059}
60
61static struct pernet_operations iptable_raw_net_ops = {
62 .init = iptable_raw_net_init,
63 .exit = iptable_raw_net_exit,
64};
65
Andrew Morton65b4b4e2006-03-28 16:37:06 -080066static int __init iptable_raw_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
68 int ret;
69
Alexey Dobriyan9335f042008-01-31 04:03:23 -080070 ret = register_pernet_subsys(&iptable_raw_net_ops);
71 if (ret < 0)
72 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
74 /* Register hooks */
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020075 rawtable_ops = xt_hook_link(&packet_raw, iptable_raw_hook);
76 if (IS_ERR(rawtable_ops)) {
77 ret = PTR_ERR(rawtable_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 goto cleanup_table;
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020079 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 return ret;
82
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 cleanup_table:
Alexey Dobriyan9335f042008-01-31 04:03:23 -080084 unregister_pernet_subsys(&iptable_raw_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 return ret;
86}
87
Andrew Morton65b4b4e2006-03-28 16:37:06 -080088static void __exit iptable_raw_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070089{
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020090 xt_hook_unlink(&packet_raw, rawtable_ops);
Alexey Dobriyan9335f042008-01-31 04:03:23 -080091 unregister_pernet_subsys(&iptable_raw_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092}
93
Andrew Morton65b4b4e2006-03-28 16:37:06 -080094module_init(iptable_raw_init);
95module_exit(iptable_raw_fini);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096MODULE_LICENSE("GPL");