1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/types.h>
4 #include <linux/atomic.h>
5 #include <linux/inetdevice.h>
6 #include <linux/netfilter.h>
7 #include <linux/netfilter_ipv4.h>
8 #include <linux/netfilter_ipv6.h>
10 #include <net/netfilter/nf_nat_masquerade.h>
12 static DEFINE_MUTEX(masq_mutex
);
13 static unsigned int masq_refcnt __read_mostly
;
16 nf_nat_masquerade_ipv4(struct sk_buff
*skb
, unsigned int hooknum
,
17 const struct nf_nat_range2
*range
,
18 const struct net_device
*out
)
21 struct nf_conn_nat
*nat
;
22 enum ip_conntrack_info ctinfo
;
23 struct nf_nat_range2 newrange
;
24 const struct rtable
*rt
;
27 WARN_ON(hooknum
!= NF_INET_POST_ROUTING
);
29 ct
= nf_ct_get(skb
, &ctinfo
);
31 WARN_ON(!(ct
&& (ctinfo
== IP_CT_NEW
|| ctinfo
== IP_CT_RELATED
||
32 ctinfo
== IP_CT_RELATED_REPLY
)));
34 /* Source address is 0.0.0.0 - locally generated packet that is
35 * probably not supposed to be masqueraded.
37 if (ct
->tuplehash
[IP_CT_DIR_ORIGINAL
].tuple
.src
.u3
.ip
== 0)
41 nh
= rt_nexthop(rt
, ip_hdr(skb
)->daddr
);
42 newsrc
= inet_select_addr(out
, nh
, RT_SCOPE_UNIVERSE
);
44 pr_info("%s ate my IP address\n", out
->name
);
48 nat
= nf_ct_nat_ext_add(ct
);
50 nat
->masq_index
= out
->ifindex
;
52 /* Transfer from original range. */
53 memset(&newrange
.min_addr
, 0, sizeof(newrange
.min_addr
));
54 memset(&newrange
.max_addr
, 0, sizeof(newrange
.max_addr
));
55 newrange
.flags
= range
->flags
| NF_NAT_RANGE_MAP_IPS
;
56 newrange
.min_addr
.ip
= newsrc
;
57 newrange
.max_addr
.ip
= newsrc
;
58 newrange
.min_proto
= range
->min_proto
;
59 newrange
.max_proto
= range
->max_proto
;
61 /* Hand modified range to generic setup. */
62 return nf_nat_setup_info(ct
, &newrange
, NF_NAT_MANIP_SRC
);
64 EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv4
);
66 static int device_cmp(struct nf_conn
*i
, void *ifindex
)
68 const struct nf_conn_nat
*nat
= nfct_nat(i
);
72 return nat
->masq_index
== (int)(long)ifindex
;
75 static int masq_device_event(struct notifier_block
*this,
79 const struct net_device
*dev
= netdev_notifier_info_to_dev(ptr
);
80 struct net
*net
= dev_net(dev
);
82 if (event
== NETDEV_DOWN
) {
83 /* Device was downed. Search entire table for
84 * conntracks which were associated with that device,
88 nf_ct_iterate_cleanup_net(net
, device_cmp
,
89 (void *)(long)dev
->ifindex
, 0, 0);
95 static int inet_cmp(struct nf_conn
*ct
, void *ptr
)
97 struct in_ifaddr
*ifa
= (struct in_ifaddr
*)ptr
;
98 struct net_device
*dev
= ifa
->ifa_dev
->dev
;
99 struct nf_conntrack_tuple
*tuple
;
101 if (!device_cmp(ct
, (void *)(long)dev
->ifindex
))
104 tuple
= &ct
->tuplehash
[IP_CT_DIR_REPLY
].tuple
;
106 return ifa
->ifa_address
== tuple
->dst
.u3
.ip
;
109 static int masq_inet_event(struct notifier_block
*this,
113 struct in_device
*idev
= ((struct in_ifaddr
*)ptr
)->ifa_dev
;
114 struct net
*net
= dev_net(idev
->dev
);
116 /* The masq_dev_notifier will catch the case of the device going
117 * down. So if the inetdev is dead and being destroyed we have
118 * no work to do. Otherwise this is an individual address removal
119 * and we have to perform the flush.
124 if (event
== NETDEV_DOWN
)
125 nf_ct_iterate_cleanup_net(net
, inet_cmp
, ptr
, 0, 0);
130 static struct notifier_block masq_dev_notifier
= {
131 .notifier_call
= masq_device_event
,
134 static struct notifier_block masq_inet_notifier
= {
135 .notifier_call
= masq_inet_event
,
138 #if IS_ENABLED(CONFIG_IPV6)
139 static atomic_t v6_worker_count __read_mostly
;
142 nat_ipv6_dev_get_saddr(struct net
*net
, const struct net_device
*dev
,
143 const struct in6_addr
*daddr
, unsigned int srcprefs
,
144 struct in6_addr
*saddr
)
146 #ifdef CONFIG_IPV6_MODULE
147 const struct nf_ipv6_ops
*v6_ops
= nf_get_ipv6_ops();
150 return -EHOSTUNREACH
;
152 return v6_ops
->dev_get_saddr(net
, dev
, daddr
, srcprefs
, saddr
);
154 return ipv6_dev_get_saddr(net
, dev
, daddr
, srcprefs
, saddr
);
159 nf_nat_masquerade_ipv6(struct sk_buff
*skb
, const struct nf_nat_range2
*range
,
160 const struct net_device
*out
)
162 enum ip_conntrack_info ctinfo
;
163 struct nf_conn_nat
*nat
;
166 struct nf_nat_range2 newrange
;
168 ct
= nf_ct_get(skb
, &ctinfo
);
169 WARN_ON(!(ct
&& (ctinfo
== IP_CT_NEW
|| ctinfo
== IP_CT_RELATED
||
170 ctinfo
== IP_CT_RELATED_REPLY
)));
172 if (nat_ipv6_dev_get_saddr(nf_ct_net(ct
), out
,
173 &ipv6_hdr(skb
)->daddr
, 0, &src
) < 0)
176 nat
= nf_ct_nat_ext_add(ct
);
178 nat
->masq_index
= out
->ifindex
;
180 newrange
.flags
= range
->flags
| NF_NAT_RANGE_MAP_IPS
;
181 newrange
.min_addr
.in6
= src
;
182 newrange
.max_addr
.in6
= src
;
183 newrange
.min_proto
= range
->min_proto
;
184 newrange
.max_proto
= range
->max_proto
;
186 return nf_nat_setup_info(ct
, &newrange
, NF_NAT_MANIP_SRC
);
188 EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6
);
190 struct masq_dev_work
{
191 struct work_struct work
;
193 struct in6_addr addr
;
197 static int inet6_cmp(struct nf_conn
*ct
, void *work
)
199 struct masq_dev_work
*w
= (struct masq_dev_work
*)work
;
200 struct nf_conntrack_tuple
*tuple
;
202 if (!device_cmp(ct
, (void *)(long)w
->ifindex
))
205 tuple
= &ct
->tuplehash
[IP_CT_DIR_REPLY
].tuple
;
207 return ipv6_addr_equal(&w
->addr
, &tuple
->dst
.u3
.in6
);
210 static void iterate_cleanup_work(struct work_struct
*work
)
212 struct masq_dev_work
*w
;
214 w
= container_of(work
, struct masq_dev_work
, work
);
216 nf_ct_iterate_cleanup_net(w
->net
, inet6_cmp
, (void *)w
, 0, 0);
220 atomic_dec(&v6_worker_count
);
221 module_put(THIS_MODULE
);
224 /* atomic notifier; can't call nf_ct_iterate_cleanup_net (it can sleep).
226 * Defer it to the system workqueue.
228 * As we can have 'a lot' of inet_events (depending on amount of ipv6
229 * addresses being deleted), we also need to limit work item queue.
231 static int masq_inet6_event(struct notifier_block
*this,
232 unsigned long event
, void *ptr
)
234 struct inet6_ifaddr
*ifa
= ptr
;
235 const struct net_device
*dev
;
236 struct masq_dev_work
*w
;
239 if (event
!= NETDEV_DOWN
|| atomic_read(&v6_worker_count
) >= 16)
242 dev
= ifa
->idev
->dev
;
243 net
= maybe_get_net(dev_net(dev
));
247 if (!try_module_get(THIS_MODULE
))
250 w
= kmalloc(sizeof(*w
), GFP_ATOMIC
);
252 atomic_inc(&v6_worker_count
);
254 INIT_WORK(&w
->work
, iterate_cleanup_work
);
255 w
->ifindex
= dev
->ifindex
;
258 schedule_work(&w
->work
);
263 module_put(THIS_MODULE
);
269 static struct notifier_block masq_inet6_notifier
= {
270 .notifier_call
= masq_inet6_event
,
273 static int nf_nat_masquerade_ipv6_register_notifier(void)
275 return register_inet6addr_notifier(&masq_inet6_notifier
);
278 static inline int nf_nat_masquerade_ipv6_register_notifier(void) { return 0; }
281 int nf_nat_masquerade_inet_register_notifiers(void)
285 mutex_lock(&masq_mutex
);
286 if (WARN_ON_ONCE(masq_refcnt
== UINT_MAX
)) {
291 /* check if the notifier was already set */
292 if (++masq_refcnt
> 1)
295 /* Register for device down reports */
296 ret
= register_netdevice_notifier(&masq_dev_notifier
);
299 /* Register IP address change reports */
300 ret
= register_inetaddr_notifier(&masq_inet_notifier
);
304 ret
= nf_nat_masquerade_ipv6_register_notifier();
308 mutex_unlock(&masq_mutex
);
311 unregister_inetaddr_notifier(&masq_inet_notifier
);
313 unregister_netdevice_notifier(&masq_dev_notifier
);
317 mutex_unlock(&masq_mutex
);
320 EXPORT_SYMBOL_GPL(nf_nat_masquerade_inet_register_notifiers
);
322 void nf_nat_masquerade_inet_unregister_notifiers(void)
324 mutex_lock(&masq_mutex
);
325 /* check if the notifiers still have clients */
326 if (--masq_refcnt
> 0)
329 unregister_netdevice_notifier(&masq_dev_notifier
);
330 unregister_inetaddr_notifier(&masq_inet_notifier
);
331 #if IS_ENABLED(CONFIG_IPV6)
332 unregister_inet6addr_notifier(&masq_inet6_notifier
);
335 mutex_unlock(&masq_mutex
);
337 EXPORT_SYMBOL_GPL(nf_nat_masquerade_inet_unregister_notifiers
);