blob: 0356e6da4bb749ba1dcfa07667dcac7b0aa92878 [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
Patrick McHardy795aa6e2013-10-10 09:21:55 +020023iptable_raw_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -040024 const struct nf_hook_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -070025{
Jan Engelhardt2b21e052009-06-13 06:57:10 +020026 const struct net *net;
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Patrick McHardy795aa6e2013-10-10 09:21:55 +020028 if (ops->hooknum == NF_INET_LOCAL_OUT &&
Jan Engelhardt2b21e052009-06-13 06:57:10 +020029 (skb->len < sizeof(struct iphdr) ||
30 ip_hdrlen(skb) < sizeof(struct iphdr)))
31 /* root is playing with raw sockets. */
Patrick McHardy802169a2007-05-10 14:17:36 -070032 return NF_ACCEPT;
Jan Engelhardt2b21e052009-06-13 06:57:10 +020033
David S. Miller238e54c2015-04-03 20:32:56 -040034 net = dev_net(state->in ? state->in : state->out);
David S. Miller1c491ba2015-04-03 20:56:08 -040035 return ipt_do_table(skb, ops->hooknum, state, net->ipv4.iptable_raw);
Patrick McHardy802169a2007-05-10 14:17:36 -070036}
37
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020038static struct nf_hook_ops *rawtable_ops __read_mostly;
Linus Torvalds1da177e2005-04-16 15:20:36 -070039
Alexey Dobriyan9335f042008-01-31 04:03:23 -080040static int __net_init iptable_raw_net_init(struct net *net)
41{
Jan Engelhardte3eaa992009-06-17 22:14:54 +020042 struct ipt_replace *repl;
43
44 repl = ipt_alloc_initial_table(&packet_raw);
45 if (repl == NULL)
46 return -ENOMEM;
Alexey Dobriyan9335f042008-01-31 04:03:23 -080047 net->ipv4.iptable_raw =
Jan Engelhardte3eaa992009-06-17 22:14:54 +020048 ipt_register_table(net, &packet_raw, repl);
49 kfree(repl);
Rusty Russell8c6ffba2013-07-15 11:20:32 +093050 return PTR_ERR_OR_ZERO(net->ipv4.iptable_raw);
Alexey Dobriyan9335f042008-01-31 04:03:23 -080051}
52
53static void __net_exit iptable_raw_net_exit(struct net *net)
54{
Alexey Dobriyanf54e9362010-01-18 08:25:47 +010055 ipt_unregister_table(net, net->ipv4.iptable_raw);
Alexey Dobriyan9335f042008-01-31 04:03:23 -080056}
57
58static struct pernet_operations iptable_raw_net_ops = {
59 .init = iptable_raw_net_init,
60 .exit = iptable_raw_net_exit,
61};
62
Andrew Morton65b4b4e2006-03-28 16:37:06 -080063static int __init iptable_raw_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070064{
65 int ret;
66
Alexey Dobriyan9335f042008-01-31 04:03:23 -080067 ret = register_pernet_subsys(&iptable_raw_net_ops);
68 if (ret < 0)
69 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
71 /* Register hooks */
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020072 rawtable_ops = xt_hook_link(&packet_raw, iptable_raw_hook);
73 if (IS_ERR(rawtable_ops)) {
74 ret = PTR_ERR(rawtable_ops);
Jean Sacren90efbed2012-08-19 15:11:32 +000075 unregister_pernet_subsys(&iptable_raw_net_ops);
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020076 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -070079}
80
Andrew Morton65b4b4e2006-03-28 16:37:06 -080081static void __exit iptable_raw_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070082{
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020083 xt_hook_unlink(&packet_raw, rawtable_ops);
Alexey Dobriyan9335f042008-01-31 04:03:23 -080084 unregister_pernet_subsys(&iptable_raw_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -070085}
86
Andrew Morton65b4b4e2006-03-28 16:37:06 -080087module_init(iptable_raw_init);
88module_exit(iptable_raw_fini);
Linus Torvalds1da177e2005-04-16 15:20:36 -070089MODULE_LICENSE("GPL");