blob: cf26ccb04056e1346f40a1d34ff44e2b8eb9f518 [file] [log] [blame]
James Morris17e6e592008-06-09 15:58:05 -07001/*
2 * "security" table for IPv6
3 *
4 * This is for use by Mandatory Access Control (MAC) security models,
5 * which need to be able to manage security policy in separate context
6 * to DAC.
7 *
8 * Based on iptable_mangle.c
9 *
10 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
11 * Copyright (C) 2000-2004 Netfilter Core Team <coreteam <at> netfilter.org>
12 * Copyright (C) 2008 Red Hat, Inc., James Morris <jmorris <at> redhat.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18#include <linux/module.h>
19#include <linux/netfilter_ipv6/ip6_tables.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090020#include <linux/slab.h>
James Morris17e6e592008-06-09 15:58:05 -070021
22MODULE_LICENSE("GPL");
23MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>");
24MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
25
26#define SECURITY_VALID_HOOKS (1 << NF_INET_LOCAL_IN) | \
27 (1 << NF_INET_FORWARD) | \
28 (1 << NF_INET_LOCAL_OUT)
29
Florian Westphalb9e69e12016-02-25 10:08:36 +010030static int __net_init ip6table_security_table_init(struct net *net);
31
Jan Engelhardt35aad0f2009-08-24 14:56:30 +020032static const struct xt_table security_table = {
James Morris17e6e592008-06-09 15:58:05 -070033 .name = "security",
34 .valid_hooks = SECURITY_VALID_HOOKS,
James Morris17e6e592008-06-09 15:58:05 -070035 .me = THIS_MODULE,
Jan Engelhardtf88e6a82009-06-13 06:25:44 +020036 .af = NFPROTO_IPV6,
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020037 .priority = NF_IP6_PRI_SECURITY,
Florian Westphalb9e69e12016-02-25 10:08:36 +010038 .table_init = ip6table_security_table_init,
James Morris17e6e592008-06-09 15:58:05 -070039};
40
41static unsigned int
Eric W. Biederman06198b32015-09-18 14:33:06 -050042ip6table_security_hook(void *priv, struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -040043 const struct nf_hook_state *state)
James Morris17e6e592008-06-09 15:58:05 -070044{
Eric W. Biederman6cb8ff3f12015-09-18 14:32:55 -050045 return ip6t_do_table(skb, state, state->net->ipv6.ip6table_security);
James Morris17e6e592008-06-09 15:58:05 -070046}
47
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020048static struct nf_hook_ops *sectbl_ops __read_mostly;
James Morris17e6e592008-06-09 15:58:05 -070049
Florian Westphalb9e69e12016-02-25 10:08:36 +010050static int __net_init ip6table_security_table_init(struct net *net)
James Morris17e6e592008-06-09 15:58:05 -070051{
Jan Engelhardte3eaa992009-06-17 22:14:54 +020052 struct ip6t_replace *repl;
Florian Westphala67dd262016-02-25 10:08:35 +010053 int ret;
James Morris17e6e592008-06-09 15:58:05 -070054
Florian Westphalb9e69e12016-02-25 10:08:36 +010055 if (net->ipv6.ip6table_security)
56 return 0;
57
Jan Engelhardte3eaa992009-06-17 22:14:54 +020058 repl = ip6t_alloc_initial_table(&security_table);
59 if (repl == NULL)
60 return -ENOMEM;
Florian Westphala67dd262016-02-25 10:08:35 +010061 ret = ip6t_register_table(net, &security_table, repl, sectbl_ops,
62 &net->ipv6.ip6table_security);
Jan Engelhardte3eaa992009-06-17 22:14:54 +020063 kfree(repl);
Florian Westphala67dd262016-02-25 10:08:35 +010064 return ret;
James Morris17e6e592008-06-09 15:58:05 -070065}
66
67static void __net_exit ip6table_security_net_exit(struct net *net)
68{
Florian Westphalb9e69e12016-02-25 10:08:36 +010069 if (!net->ipv6.ip6table_security)
70 return;
Florian Westphala67dd262016-02-25 10:08:35 +010071 ip6t_unregister_table(net, net->ipv6.ip6table_security, sectbl_ops);
Florian Westphalb9e69e12016-02-25 10:08:36 +010072 net->ipv6.ip6table_security = NULL;
James Morris17e6e592008-06-09 15:58:05 -070073}
74
75static struct pernet_operations ip6table_security_net_ops = {
James Morris17e6e592008-06-09 15:58:05 -070076 .exit = ip6table_security_net_exit,
77};
78
79static int __init ip6table_security_init(void)
80{
81 int ret;
82
Florian Westphalb9e69e12016-02-25 10:08:36 +010083 sectbl_ops = xt_hook_ops_alloc(&security_table, ip6table_security_hook);
84 if (IS_ERR(sectbl_ops))
85 return PTR_ERR(sectbl_ops);
James Morris17e6e592008-06-09 15:58:05 -070086
Florian Westphalb9e69e12016-02-25 10:08:36 +010087 ret = register_pernet_subsys(&ip6table_security_net_ops);
88 if (ret < 0) {
89 kfree(sectbl_ops);
90 return ret;
Jan Engelhardt2b95efe2009-06-17 13:57:48 +020091 }
James Morris17e6e592008-06-09 15:58:05 -070092
Florian Westphalb9e69e12016-02-25 10:08:36 +010093 ret = ip6table_security_table_init(&init_net);
94 if (ret) {
95 unregister_pernet_subsys(&ip6table_security_net_ops);
96 kfree(sectbl_ops);
97 }
James Morris17e6e592008-06-09 15:58:05 -070098 return ret;
99}
100
101static void __exit ip6table_security_fini(void)
102{
James Morris17e6e592008-06-09 15:58:05 -0700103 unregister_pernet_subsys(&ip6table_security_net_ops);
Florian Westphalb9e69e12016-02-25 10:08:36 +0100104 kfree(sectbl_ops);
James Morris17e6e592008-06-09 15:58:05 -0700105}
106
107module_init(ip6table_security_init);
108module_exit(ip6table_security_fini);