blob: 7667f223d7f8c12321537919dbc5260c0813e474 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/netfilter_ipv4/ip_tables.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090016#include <linux/slab.h>
Arnaldo Carvalho de Meloc9bdd4b2007-03-12 20:09:15 -030017#include <net/ip.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
19MODULE_LICENSE("GPL");
20MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
21MODULE_DESCRIPTION("iptables filter table");
22
Patrick McHardy6e23ae22007-11-19 18:53:30 -080023#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
24 (1 << NF_INET_FORWARD) | \
25 (1 << NF_INET_LOCAL_OUT))
Florian Westphalb9e69e12016-02-25 10:08:36 +010026static int __net_init iptable_filter_table_init(struct net *net);
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Jan Engelhardt35aad0f2009-08-24 14:56:30 +020028static const struct xt_table packet_filter = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 .name = "filter",
30 .valid_hooks = FILTER_VALID_HOOKS,
Harald Welte2e4e6a12006-01-12 13:30:04 -080031 .me = THIS_MODULE,
Jan Engelhardtf88e6a82009-06-13 06:25:44 +020032 .af = NFPROTO_IPV4,
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020033 .priority = NF_IP_PRI_FILTER,
Florian Westphalb9e69e12016-02-25 10:08:36 +010034 .table_init = iptable_filter_table_init,
Linus Torvalds1da177e2005-04-16 15:20:36 -070035};
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037static unsigned int
Eric W. Biederman06198b32015-09-18 14:33:06 -050038iptable_filter_hook(void *priv, struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -040039 const struct nf_hook_state *state)
Alexey Dobriyan666953df2008-04-14 09:56:02 +020040{
Eric W. Biederman6cb8ff3f12015-09-18 14:32:55 -050041 if (state->hook == NF_INET_LOCAL_OUT &&
Jan Engelhardt2b21e052009-06-13 06:57:10 +020042 (skb->len < sizeof(struct iphdr) ||
43 ip_hdrlen(skb) < sizeof(struct iphdr)))
44 /* root is playing with raw sockets. */
45 return NF_ACCEPT;
Jan Engelhardt737535c2009-06-13 06:46:36 +020046
Eric W. Biederman6cb8ff3f12015-09-18 14:32:55 -050047 return ipt_do_table(skb, state, state->net->ipv4.iptable_filter);
Alexey Dobriyan666953df2008-04-14 09:56:02 +020048}
49
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020050static struct nf_hook_ops *filter_ops __read_mostly;
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
52/* Default to forward because I got too much mail already. */
Florian Westphalb9e69e12016-02-25 10:08:36 +010053static bool forward __read_mostly = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070054module_param(forward, bool, 0000);
55
Florian Westphalb9e69e12016-02-25 10:08:36 +010056static int __net_init iptable_filter_table_init(struct net *net)
Alexey Dobriyan9335f042008-01-31 04:03:23 -080057{
Jan Engelhardte3eaa992009-06-17 22:14:54 +020058 struct ipt_replace *repl;
Florian Westphala67dd262016-02-25 10:08:35 +010059 int err;
Jan Engelhardte3eaa992009-06-17 22:14:54 +020060
Florian Westphalb9e69e12016-02-25 10:08:36 +010061 if (net->ipv4.iptable_filter)
62 return 0;
63
Jan Engelhardte3eaa992009-06-17 22:14:54 +020064 repl = ipt_alloc_initial_table(&packet_filter);
65 if (repl == NULL)
66 return -ENOMEM;
67 /* Entry 1 is the FORWARD hook */
68 ((struct ipt_standard *)repl->entries)[1].target.verdict =
Rusty Russell523f6102012-03-22 12:27:06 +000069 forward ? -NF_ACCEPT - 1 : -NF_DROP - 1;
Jan Engelhardte3eaa992009-06-17 22:14:54 +020070
Florian Westphala67dd262016-02-25 10:08:35 +010071 err = ipt_register_table(net, &packet_filter, repl, filter_ops,
72 &net->ipv4.iptable_filter);
Jan Engelhardte3eaa992009-06-17 22:14:54 +020073 kfree(repl);
Florian Westphala67dd262016-02-25 10:08:35 +010074 return err;
Alexey Dobriyan9335f042008-01-31 04:03:23 -080075}
76
Florian Westphalb9e69e12016-02-25 10:08:36 +010077static int __net_init iptable_filter_net_init(struct net *net)
78{
79 if (net == &init_net || !forward)
80 return iptable_filter_table_init(net);
81
82 return 0;
83}
84
Alexey Dobriyan9335f042008-01-31 04:03:23 -080085static void __net_exit iptable_filter_net_exit(struct net *net)
86{
Florian Westphalb9e69e12016-02-25 10:08:36 +010087 if (!net->ipv4.iptable_filter)
88 return;
Florian Westphala67dd262016-02-25 10:08:35 +010089 ipt_unregister_table(net, net->ipv4.iptable_filter, filter_ops);
Florian Westphalb9e69e12016-02-25 10:08:36 +010090 net->ipv4.iptable_filter = NULL;
Alexey Dobriyan9335f042008-01-31 04:03:23 -080091}
92
93static struct pernet_operations iptable_filter_net_ops = {
94 .init = iptable_filter_net_init,
95 .exit = iptable_filter_net_exit,
96};
97
Andrew Morton65b4b4e2006-03-28 16:37:06 -080098static int __init iptable_filter_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070099{
100 int ret;
101
Florian Westphalb9e69e12016-02-25 10:08:36 +0100102 filter_ops = xt_hook_ops_alloc(&packet_filter, iptable_filter_hook);
103 if (IS_ERR(filter_ops))
104 return PTR_ERR(filter_ops);
105
Alexey Dobriyan9335f042008-01-31 04:03:23 -0800106 ret = register_pernet_subsys(&iptable_filter_net_ops);
107 if (ret < 0)
Florian Westphalb9e69e12016-02-25 10:08:36 +0100108 kfree(filter_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Andrew Morton65b4b4e2006-03-28 16:37:06 -0800113static void __exit iptable_filter_fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114{
Alexey Dobriyan9335f042008-01-31 04:03:23 -0800115 unregister_pernet_subsys(&iptable_filter_net_ops);
Florian Westphalb9e69e12016-02-25 10:08:36 +0100116 kfree(filter_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117}
118
Andrew Morton65b4b4e2006-03-28 16:37:06 -0800119module_init(iptable_filter_init);
120module_exit(iptable_filter_fini);