linux/net/ipv6/netfilter/ip6table_security.c
<<
>>
Prefs
   1/*
   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>
  20
  21MODULE_LICENSE("GPL");
  22MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>");
  23MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
  24
  25#define SECURITY_VALID_HOOKS    (1 << NF_INET_LOCAL_IN) | \
  26                                (1 << NF_INET_FORWARD) | \
  27                                (1 << NF_INET_LOCAL_OUT)
  28
  29static const struct
  30{
  31        struct ip6t_replace repl;
  32        struct ip6t_standard entries[3];
  33        struct ip6t_error term;
  34} initial_table __net_initdata = {
  35        .repl = {
  36                .name = "security",
  37                .valid_hooks = SECURITY_VALID_HOOKS,
  38                .num_entries = 4,
  39                .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
  40                .hook_entry = {
  41                        [NF_INET_LOCAL_IN]      = 0,
  42                        [NF_INET_FORWARD]       = sizeof(struct ip6t_standard),
  43                        [NF_INET_LOCAL_OUT]     = sizeof(struct ip6t_standard) * 2,
  44                },
  45                .underflow = {
  46                        [NF_INET_LOCAL_IN]      = 0,
  47                        [NF_INET_FORWARD]       = sizeof(struct ip6t_standard),
  48                        [NF_INET_LOCAL_OUT]     = sizeof(struct ip6t_standard) * 2,
  49                },
  50        },
  51        .entries = {
  52                IP6T_STANDARD_INIT(NF_ACCEPT),  /* LOCAL_IN */
  53                IP6T_STANDARD_INIT(NF_ACCEPT),  /* FORWARD */
  54                IP6T_STANDARD_INIT(NF_ACCEPT),  /* LOCAL_OUT */
  55        },
  56        .term = IP6T_ERROR_INIT,                /* ERROR */
  57};
  58
  59static const struct xt_table security_table = {
  60        .name           = "security",
  61        .valid_hooks    = SECURITY_VALID_HOOKS,
  62        .me             = THIS_MODULE,
  63        .af             = NFPROTO_IPV6,
  64};
  65
  66static unsigned int
  67ip6t_local_in_hook(unsigned int hook,
  68                   struct sk_buff *skb,
  69                   const struct net_device *in,
  70                   const struct net_device *out,
  71                   int (*okfn)(struct sk_buff *))
  72{
  73        return ip6t_do_table(skb, hook, in, out,
  74                             dev_net(in)->ipv6.ip6table_security);
  75}
  76
  77static unsigned int
  78ip6t_forward_hook(unsigned int hook,
  79                  struct sk_buff *skb,
  80                  const struct net_device *in,
  81                  const struct net_device *out,
  82                  int (*okfn)(struct sk_buff *))
  83{
  84        return ip6t_do_table(skb, hook, in, out,
  85                             dev_net(in)->ipv6.ip6table_security);
  86}
  87
  88static unsigned int
  89ip6t_local_out_hook(unsigned int hook,
  90                    struct sk_buff *skb,
  91                    const struct net_device *in,
  92                    const struct net_device *out,
  93                    int (*okfn)(struct sk_buff *))
  94{
  95        /* TBD: handle short packets via raw socket */
  96        return ip6t_do_table(skb, hook, in, out,
  97                             dev_net(out)->ipv6.ip6table_security);
  98}
  99
 100static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 101        {
 102                .hook           = ip6t_local_in_hook,
 103                .owner          = THIS_MODULE,
 104                .pf             = NFPROTO_IPV6,
 105                .hooknum        = NF_INET_LOCAL_IN,
 106                .priority       = NF_IP6_PRI_SECURITY,
 107        },
 108        {
 109                .hook           = ip6t_forward_hook,
 110                .owner          = THIS_MODULE,
 111                .pf             = NFPROTO_IPV6,
 112                .hooknum        = NF_INET_FORWARD,
 113                .priority       = NF_IP6_PRI_SECURITY,
 114        },
 115        {
 116                .hook           = ip6t_local_out_hook,
 117                .owner          = THIS_MODULE,
 118                .pf             = NFPROTO_IPV6,
 119                .hooknum        = NF_INET_LOCAL_OUT,
 120                .priority       = NF_IP6_PRI_SECURITY,
 121        },
 122};
 123
 124static int __net_init ip6table_security_net_init(struct net *net)
 125{
 126        net->ipv6.ip6table_security =
 127                ip6t_register_table(net, &security_table, &initial_table.repl);
 128
 129        if (IS_ERR(net->ipv6.ip6table_security))
 130                return PTR_ERR(net->ipv6.ip6table_security);
 131
 132        return 0;
 133}
 134
 135static void __net_exit ip6table_security_net_exit(struct net *net)
 136{
 137        ip6t_unregister_table(net->ipv6.ip6table_security);
 138}
 139
 140static struct pernet_operations ip6table_security_net_ops = {
 141        .init = ip6table_security_net_init,
 142        .exit = ip6table_security_net_exit,
 143};
 144
 145static int __init ip6table_security_init(void)
 146{
 147        int ret;
 148
 149        ret = register_pernet_subsys(&ip6table_security_net_ops);
 150        if (ret < 0)
 151                return ret;
 152
 153        ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
 154        if (ret < 0)
 155                goto cleanup_table;
 156
 157        return ret;
 158
 159cleanup_table:
 160        unregister_pernet_subsys(&ip6table_security_net_ops);
 161        return ret;
 162}
 163
 164static void __exit ip6table_security_fini(void)
 165{
 166        nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
 167        unregister_pernet_subsys(&ip6table_security_net_ops);
 168}
 169
 170module_init(ip6table_security_init);
 171module_exit(ip6table_security_fini);
 172