Blame view
net/netfilter/nf_nat_redirect.c
3.06 KB
d2912cb15 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
8b13eddfd netfilter: refact... |
2 3 4 5 6 |
/* * (C) 1999-2001 Paul `Rusty' Russell * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> * Copyright (c) 2011 Patrick McHardy <kaber@trash.net> * |
8b13eddfd netfilter: refact... |
7 8 9 10 11 12 13 14 |
* Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6 * NAT funded by Astaro. */ #include <linux/if.h> #include <linux/inetdevice.h> #include <linux/ip.h> #include <linux/kernel.h> |
8b13eddfd netfilter: refact... |
15 16 17 18 |
#include <linux/netdevice.h> #include <linux/netfilter.h> #include <linux/types.h> #include <linux/netfilter_ipv4.h> |
b59eaf9e2 netfilter: combin... |
19 |
#include <linux/netfilter_ipv6.h> |
8b13eddfd netfilter: refact... |
20 21 22 23 24 |
#include <linux/netfilter/x_tables.h> #include <net/addrconf.h> #include <net/checksum.h> #include <net/protocol.h> #include <net/netfilter/nf_nat.h> |
b59eaf9e2 netfilter: combin... |
25 |
#include <net/netfilter/nf_nat_redirect.h> |
8b13eddfd netfilter: refact... |
26 27 28 29 30 31 32 33 34 |
unsigned int nf_nat_redirect_ipv4(struct sk_buff *skb, const struct nf_nat_ipv4_multi_range_compat *mr, unsigned int hooknum) { struct nf_conn *ct; enum ip_conntrack_info ctinfo; __be32 newdst; |
2eb0f624b netfilter: add NA... |
35 |
struct nf_nat_range2 newrange; |
8b13eddfd netfilter: refact... |
36 |
|
44d6e2f27 net: Replace NF_C... |
37 38 |
WARN_ON(hooknum != NF_INET_PRE_ROUTING && hooknum != NF_INET_LOCAL_OUT); |
8b13eddfd netfilter: refact... |
39 40 |
ct = nf_ct_get(skb, &ctinfo); |
44d6e2f27 net: Replace NF_C... |
41 |
WARN_ON(!(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED))); |
8b13eddfd netfilter: refact... |
42 43 44 45 46 |
/* Local packets: make them go to loopback */ if (hooknum == NF_INET_LOCAL_OUT) { newdst = htonl(0x7F000001); } else { |
2638eb8b5 net: ipv4: provid... |
47 |
const struct in_device *indev; |
8b13eddfd netfilter: refact... |
48 49 |
newdst = 0; |
8b13eddfd netfilter: refact... |
50 |
indev = __in_dev_get_rcu(skb->dev); |
2638eb8b5 net: ipv4: provid... |
51 52 53 54 55 56 |
if (indev) { const struct in_ifaddr *ifa; ifa = rcu_dereference(indev->ifa_list); if (ifa) newdst = ifa->ifa_local; |
8b13eddfd netfilter: refact... |
57 |
} |
8b13eddfd netfilter: refact... |
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
if (!newdst) return NF_DROP; } /* Transfer from original range. */ memset(&newrange.min_addr, 0, sizeof(newrange.min_addr)); memset(&newrange.max_addr, 0, sizeof(newrange.max_addr)); newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS; newrange.min_addr.ip = newdst; newrange.max_addr.ip = newdst; newrange.min_proto = mr->range[0].min; newrange.max_proto = mr->range[0].max; /* Hand modified range to generic setup. */ return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); } EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4); |
b59eaf9e2 netfilter: combin... |
76 77 78 |
static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; unsigned int |
2eb0f624b netfilter: add NA... |
79 |
nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, |
b59eaf9e2 netfilter: combin... |
80 81 |
unsigned int hooknum) { |
2eb0f624b netfilter: add NA... |
82 |
struct nf_nat_range2 newrange; |
b59eaf9e2 netfilter: combin... |
83 84 85 86 87 88 89 90 91 92 93 |
struct in6_addr newdst; enum ip_conntrack_info ctinfo; struct nf_conn *ct; ct = nf_ct_get(skb, &ctinfo); if (hooknum == NF_INET_LOCAL_OUT) { newdst = loopback_addr; } else { struct inet6_dev *idev; struct inet6_ifaddr *ifa; bool addr = false; |
b59eaf9e2 netfilter: combin... |
94 95 |
idev = __in6_dev_get(skb->dev); if (idev != NULL) { |
0c7930e57 netfilter: make i... |
96 |
read_lock_bh(&idev->lock); |
b59eaf9e2 netfilter: combin... |
97 98 99 100 101 |
list_for_each_entry(ifa, &idev->addr_list, if_list) { newdst = ifa->addr; addr = true; break; } |
0c7930e57 netfilter: make i... |
102 |
read_unlock_bh(&idev->lock); |
b59eaf9e2 netfilter: combin... |
103 |
} |
b59eaf9e2 netfilter: combin... |
104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
if (!addr) return NF_DROP; } newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS; newrange.min_addr.in6 = newdst; newrange.max_addr.in6 = newdst; newrange.min_proto = range->min_proto; newrange.max_proto = range->max_proto; return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); } EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv6); |