~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/ipv6/netfilter/ip6t_MASQUERADE.c

Version: ~ [ linux-5.10-rc5 ] ~ [ linux-5.9.10 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.79 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.159 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.208 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.245 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.245 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU General Public License version 2 as
  6  * published by the Free Software Foundation.
  7  *
  8  * Based on Rusty Russell's IPv6 MASQUERADE target. Development of IPv6
  9  * NAT funded by Astaro.
 10  */
 11 
 12 #include <linux/kernel.h>
 13 #include <linux/module.h>
 14 #include <linux/netdevice.h>
 15 #include <linux/ipv6.h>
 16 #include <linux/netfilter.h>
 17 #include <linux/netfilter_ipv6.h>
 18 #include <linux/netfilter/x_tables.h>
 19 #include <net/netfilter/nf_nat.h>
 20 #include <net/addrconf.h>
 21 #include <net/ipv6.h>
 22 
 23 static unsigned int
 24 masquerade_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 25 {
 26         const struct nf_nat_range *range = par->targinfo;
 27         enum ip_conntrack_info ctinfo;
 28         struct in6_addr src;
 29         struct nf_conn *ct;
 30         struct nf_nat_range newrange;
 31 
 32         ct = nf_ct_get(skb, &ctinfo);
 33         NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
 34                             ctinfo == IP_CT_RELATED_REPLY));
 35 
 36         if (ipv6_dev_get_saddr(dev_net(par->out), par->out,
 37                                &ipv6_hdr(skb)->daddr, 0, &src) < 0)
 38                 return NF_DROP;
 39 
 40         nfct_nat(ct)->masq_index = par->out->ifindex;
 41 
 42         newrange.flags          = range->flags | NF_NAT_RANGE_MAP_IPS;
 43         newrange.min_addr.in6   = src;
 44         newrange.max_addr.in6   = src;
 45         newrange.min_proto      = range->min_proto;
 46         newrange.max_proto      = range->max_proto;
 47 
 48         return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
 49 }
 50 
 51 static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par)
 52 {
 53         const struct nf_nat_range *range = par->targinfo;
 54 
 55         if (range->flags & NF_NAT_RANGE_MAP_IPS)
 56                 return -EINVAL;
 57         return 0;
 58 }
 59 
 60 static int device_cmp(struct nf_conn *ct, void *ifindex)
 61 {
 62         const struct nf_conn_nat *nat = nfct_nat(ct);
 63 
 64         if (!nat)
 65                 return 0;
 66         if (nf_ct_l3num(ct) != NFPROTO_IPV6)
 67                 return 0;
 68         return nat->masq_index == (int)(long)ifindex;
 69 }
 70 
 71 static int masq_device_event(struct notifier_block *this,
 72                              unsigned long event, void *ptr)
 73 {
 74         const struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 75         struct net *net = dev_net(dev);
 76 
 77         if (event == NETDEV_DOWN)
 78                 nf_ct_iterate_cleanup(net, device_cmp,
 79                                       (void *)(long)dev->ifindex, 0, 0);
 80 
 81         return NOTIFY_DONE;
 82 }
 83 
 84 static struct notifier_block masq_dev_notifier = {
 85         .notifier_call  = masq_device_event,
 86 };
 87 
 88 static int masq_inet_event(struct notifier_block *this,
 89                            unsigned long event, void *ptr)
 90 {
 91         struct inet6_ifaddr *ifa = ptr;
 92         struct netdev_notifier_info info;
 93 
 94         netdev_notifier_info_init(&info, ifa->idev->dev);
 95         return masq_device_event(this, event, &info);
 96 }
 97 
 98 static struct notifier_block masq_inet_notifier = {
 99         .notifier_call  = masq_inet_event,
100 };
101 
102 static struct xt_target masquerade_tg6_reg __read_mostly = {
103         .name           = "MASQUERADE",
104         .family         = NFPROTO_IPV6,
105         .checkentry     = masquerade_tg6_checkentry,
106         .target         = masquerade_tg6,
107         .targetsize     = sizeof(struct nf_nat_range),
108         .table          = "nat",
109         .hooks          = 1 << NF_INET_POST_ROUTING,
110         .me             = THIS_MODULE,
111 };
112 
113 static int __init masquerade_tg6_init(void)
114 {
115         int err;
116 
117         err = xt_register_target(&masquerade_tg6_reg);
118         if (err == 0) {
119                 register_netdevice_notifier(&masq_dev_notifier);
120                 register_inet6addr_notifier(&masq_inet_notifier);
121         }
122 
123         return err;
124 }
125 static void __exit masquerade_tg6_exit(void)
126 {
127         unregister_inet6addr_notifier(&masq_inet_notifier);
128         unregister_netdevice_notifier(&masq_dev_notifier);
129         xt_unregister_target(&masquerade_tg6_reg);
130 }
131 
132 module_init(masquerade_tg6_init);
133 module_exit(masquerade_tg6_exit);
134 
135 MODULE_LICENSE("GPL");
136 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
137 MODULE_DESCRIPTION("Xtables: automatic address SNAT");
138 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp