root/net/ipv6/netfilter/ip6table_nat.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ip6table_nat_do_chain
  2. ip6t_nat_register_lookups
  3. ip6t_nat_unregister_lookups
  4. ip6table_nat_table_init
  5. ip6table_nat_net_exit
  6. ip6table_nat_init
  7. ip6table_nat_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
   4  *
   5  * Based on Rusty Russell's IPv4 NAT code. Development of IPv6 NAT
   6  * funded by Astaro.
   7  */
   8 
   9 #include <linux/module.h>
  10 #include <linux/netfilter.h>
  11 #include <linux/netfilter_ipv6.h>
  12 #include <linux/netfilter_ipv6/ip6_tables.h>
  13 #include <linux/ipv6.h>
  14 #include <net/ipv6.h>
  15 
  16 #include <net/netfilter/nf_nat.h>
  17 
  18 static int __net_init ip6table_nat_table_init(struct net *net);
  19 
  20 static const struct xt_table nf_nat_ipv6_table = {
  21         .name           = "nat",
  22         .valid_hooks    = (1 << NF_INET_PRE_ROUTING) |
  23                           (1 << NF_INET_POST_ROUTING) |
  24                           (1 << NF_INET_LOCAL_OUT) |
  25                           (1 << NF_INET_LOCAL_IN),
  26         .me             = THIS_MODULE,
  27         .af             = NFPROTO_IPV6,
  28         .table_init     = ip6table_nat_table_init,
  29 };
  30 
  31 static unsigned int ip6table_nat_do_chain(void *priv,
  32                                           struct sk_buff *skb,
  33                                           const struct nf_hook_state *state)
  34 {
  35         return ip6t_do_table(skb, state, state->net->ipv6.ip6table_nat);
  36 }
  37 
  38 static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
  39         {
  40                 .hook           = ip6table_nat_do_chain,
  41                 .pf             = NFPROTO_IPV6,
  42                 .hooknum        = NF_INET_PRE_ROUTING,
  43                 .priority       = NF_IP6_PRI_NAT_DST,
  44         },
  45         {
  46                 .hook           = ip6table_nat_do_chain,
  47                 .pf             = NFPROTO_IPV6,
  48                 .hooknum        = NF_INET_POST_ROUTING,
  49                 .priority       = NF_IP6_PRI_NAT_SRC,
  50         },
  51         {
  52                 .hook           = ip6table_nat_do_chain,
  53                 .pf             = NFPROTO_IPV6,
  54                 .hooknum        = NF_INET_LOCAL_OUT,
  55                 .priority       = NF_IP6_PRI_NAT_DST,
  56         },
  57         {
  58                 .hook           = ip6table_nat_do_chain,
  59                 .pf             = NFPROTO_IPV6,
  60                 .hooknum        = NF_INET_LOCAL_IN,
  61                 .priority       = NF_IP6_PRI_NAT_SRC,
  62         },
  63 };
  64 
  65 static int ip6t_nat_register_lookups(struct net *net)
  66 {
  67         int i, ret;
  68 
  69         for (i = 0; i < ARRAY_SIZE(nf_nat_ipv6_ops); i++) {
  70                 ret = nf_nat_ipv6_register_fn(net, &nf_nat_ipv6_ops[i]);
  71                 if (ret) {
  72                         while (i)
  73                                 nf_nat_ipv6_unregister_fn(net, &nf_nat_ipv6_ops[--i]);
  74 
  75                         return ret;
  76                 }
  77         }
  78 
  79         return 0;
  80 }
  81 
  82 static void ip6t_nat_unregister_lookups(struct net *net)
  83 {
  84         int i;
  85 
  86         for (i = 0; i < ARRAY_SIZE(nf_nat_ipv6_ops); i++)
  87                 nf_nat_ipv6_unregister_fn(net, &nf_nat_ipv6_ops[i]);
  88 }
  89 
  90 static int __net_init ip6table_nat_table_init(struct net *net)
  91 {
  92         struct ip6t_replace *repl;
  93         int ret;
  94 
  95         if (net->ipv6.ip6table_nat)
  96                 return 0;
  97 
  98         repl = ip6t_alloc_initial_table(&nf_nat_ipv6_table);
  99         if (repl == NULL)
 100                 return -ENOMEM;
 101         ret = ip6t_register_table(net, &nf_nat_ipv6_table, repl,
 102                                   NULL, &net->ipv6.ip6table_nat);
 103         if (ret < 0) {
 104                 kfree(repl);
 105                 return ret;
 106         }
 107 
 108         ret = ip6t_nat_register_lookups(net);
 109         if (ret < 0) {
 110                 ip6t_unregister_table(net, net->ipv6.ip6table_nat, NULL);
 111                 net->ipv6.ip6table_nat = NULL;
 112         }
 113         kfree(repl);
 114         return ret;
 115 }
 116 
 117 static void __net_exit ip6table_nat_net_exit(struct net *net)
 118 {
 119         if (!net->ipv6.ip6table_nat)
 120                 return;
 121         ip6t_nat_unregister_lookups(net);
 122         ip6t_unregister_table(net, net->ipv6.ip6table_nat, NULL);
 123         net->ipv6.ip6table_nat = NULL;
 124 }
 125 
 126 static struct pernet_operations ip6table_nat_net_ops = {
 127         .exit   = ip6table_nat_net_exit,
 128 };
 129 
 130 static int __init ip6table_nat_init(void)
 131 {
 132         int ret = register_pernet_subsys(&ip6table_nat_net_ops);
 133 
 134         if (ret)
 135                 return ret;
 136 
 137         ret = ip6table_nat_table_init(&init_net);
 138         if (ret)
 139                 unregister_pernet_subsys(&ip6table_nat_net_ops);
 140         return ret;
 141 }
 142 
 143 static void __exit ip6table_nat_exit(void)
 144 {
 145         unregister_pernet_subsys(&ip6table_nat_net_ops);
 146 }
 147 
 148 module_init(ip6table_nat_init);
 149 module_exit(ip6table_nat_exit);
 150 
 151 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */