diff options
-rw-r--r-- | include/net/netfilter/nf_nat_protocol.h | 11 | ||||
-rw-r--r-- | net/ipv4/netfilter/Makefile | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_proto_common.c | 85 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_proto_gre.c | 20 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_proto_tcp.c | 65 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_proto_udp.c | 64 |
6 files changed, 106 insertions, 141 deletions
diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h index 4aa0edbb5b96..fa06f6d0de54 100644 --- a/include/net/netfilter/nf_nat_protocol.h +++ b/include/net/netfilter/nf_nat_protocol.h | |||
@@ -62,6 +62,17 @@ extern int init_protocols(void) __init; | |||
62 | extern void cleanup_protocols(void); | 62 | extern void cleanup_protocols(void); |
63 | extern const struct nf_nat_protocol *find_nat_proto(u_int16_t protonum); | 63 | extern const struct nf_nat_protocol *find_nat_proto(u_int16_t protonum); |
64 | 64 | ||
65 | extern int nf_nat_proto_in_range(const struct nf_conntrack_tuple *tuple, | ||
66 | enum nf_nat_manip_type maniptype, | ||
67 | const union nf_conntrack_man_proto *min, | ||
68 | const union nf_conntrack_man_proto *max); | ||
69 | |||
70 | extern int nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, | ||
71 | const struct nf_nat_range *range, | ||
72 | enum nf_nat_manip_type maniptype, | ||
73 | const struct nf_conn *ct, | ||
74 | u_int16_t *rover); | ||
75 | |||
65 | extern int nf_nat_port_range_to_nlattr(struct sk_buff *skb, | 76 | extern int nf_nat_port_range_to_nlattr(struct sk_buff *skb, |
66 | const struct nf_nat_range *range); | 77 | const struct nf_nat_range *range); |
67 | extern int nf_nat_port_nlattr_to_range(struct nlattr *tb[], | 78 | extern int nf_nat_port_nlattr_to_range(struct nlattr *tb[], |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 0c7dc78a62e9..e73d0eb9994a 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -10,7 +10,7 @@ nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o | |||
10 | endif | 10 | endif |
11 | endif | 11 | endif |
12 | 12 | ||
13 | nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o | 13 | nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o |
14 | iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o | 14 | iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o |
15 | 15 | ||
16 | # connection tracking | 16 | # connection tracking |
diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c new file mode 100644 index 000000000000..a124213fb9da --- /dev/null +++ b/net/ipv4/netfilter/nf_nat_proto_common.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
2 | * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> | ||
3 | * (C) 2008 Patrick McHardy <kaber@trash.net> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/random.h> | ||
12 | #include <linux/ip.h> | ||
13 | |||
14 | #include <linux/netfilter.h> | ||
15 | #include <net/netfilter/nf_nat.h> | ||
16 | #include <net/netfilter/nf_nat_core.h> | ||
17 | #include <net/netfilter/nf_nat_rule.h> | ||
18 | #include <net/netfilter/nf_nat_protocol.h> | ||
19 | |||
20 | int nf_nat_proto_in_range(const struct nf_conntrack_tuple *tuple, | ||
21 | enum nf_nat_manip_type maniptype, | ||
22 | const union nf_conntrack_man_proto *min, | ||
23 | const union nf_conntrack_man_proto *max) | ||
24 | { | ||
25 | __be16 port; | ||
26 | |||
27 | if (maniptype == IP_NAT_MANIP_SRC) | ||
28 | port = tuple->src.u.all; | ||
29 | else | ||
30 | port = tuple->dst.u.all; | ||
31 | |||
32 | return ntohs(port) >= ntohs(min->all) && | ||
33 | ntohs(port) <= ntohs(max->all); | ||
34 | } | ||
35 | EXPORT_SYMBOL_GPL(nf_nat_proto_in_range); | ||
36 | |||
37 | int nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, | ||
38 | const struct nf_nat_range *range, | ||
39 | enum nf_nat_manip_type maniptype, | ||
40 | const struct nf_conn *ct, | ||
41 | u_int16_t *rover) | ||
42 | { | ||
43 | unsigned int range_size, min, i; | ||
44 | __be16 *portptr; | ||
45 | |||
46 | if (maniptype == IP_NAT_MANIP_SRC) | ||
47 | portptr = &tuple->src.u.all; | ||
48 | else | ||
49 | portptr = &tuple->dst.u.all; | ||
50 | |||
51 | /* If no range specified... */ | ||
52 | if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { | ||
53 | /* If it's dst rewrite, can't change port */ | ||
54 | if (maniptype == IP_NAT_MANIP_DST) | ||
55 | return 0; | ||
56 | |||
57 | if (ntohs(*portptr) < 1024) { | ||
58 | /* Loose convention: >> 512 is credential passing */ | ||
59 | if (ntohs(*portptr) < 512) { | ||
60 | min = 1; | ||
61 | range_size = 511 - min + 1; | ||
62 | } else { | ||
63 | min = 600; | ||
64 | range_size = 1023 - min + 1; | ||
65 | } | ||
66 | } else { | ||
67 | min = 1024; | ||
68 | range_size = 65535 - 1024 + 1; | ||
69 | } | ||
70 | } else { | ||
71 | min = ntohs(range->min.all); | ||
72 | range_size = ntohs(range->max.all) - min + 1; | ||
73 | } | ||
74 | |||
75 | if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) | ||
76 | *rover = net_random(); | ||
77 | |||
78 | for (i = 0; i < range_size; i++, (*rover)++) { | ||
79 | *portptr = htons(min + *rover % range_size); | ||
80 | if (!nf_nat_used_tuple(tuple, ct)) | ||
81 | return 1; | ||
82 | } | ||
83 | return 0; | ||
84 | } | ||
85 | EXPORT_SYMBOL_GPL(nf_nat_proto_unique_tuple); | ||
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c index a1e4da16da2e..87af63d9e692 100644 --- a/net/ipv4/netfilter/nf_nat_proto_gre.c +++ b/net/ipv4/netfilter/nf_nat_proto_gre.c | |||
@@ -36,24 +36,6 @@ MODULE_LICENSE("GPL"); | |||
36 | MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); | 36 | MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); |
37 | MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); | 37 | MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); |
38 | 38 | ||
39 | /* is key in given range between min and max */ | ||
40 | static int | ||
41 | gre_in_range(const struct nf_conntrack_tuple *tuple, | ||
42 | enum nf_nat_manip_type maniptype, | ||
43 | const union nf_conntrack_man_proto *min, | ||
44 | const union nf_conntrack_man_proto *max) | ||
45 | { | ||
46 | __be16 key; | ||
47 | |||
48 | if (maniptype == IP_NAT_MANIP_SRC) | ||
49 | key = tuple->src.u.gre.key; | ||
50 | else | ||
51 | key = tuple->dst.u.gre.key; | ||
52 | |||
53 | return ntohs(key) >= ntohs(min->gre.key) && | ||
54 | ntohs(key) <= ntohs(max->gre.key); | ||
55 | } | ||
56 | |||
57 | /* generate unique tuple ... */ | 39 | /* generate unique tuple ... */ |
58 | static int | 40 | static int |
59 | gre_unique_tuple(struct nf_conntrack_tuple *tuple, | 41 | gre_unique_tuple(struct nf_conntrack_tuple *tuple, |
@@ -140,7 +122,7 @@ static const struct nf_nat_protocol gre = { | |||
140 | .protonum = IPPROTO_GRE, | 122 | .protonum = IPPROTO_GRE, |
141 | .me = THIS_MODULE, | 123 | .me = THIS_MODULE, |
142 | .manip_pkt = gre_manip_pkt, | 124 | .manip_pkt = gre_manip_pkt, |
143 | .in_range = gre_in_range, | 125 | .in_range = nf_nat_proto_in_range, |
144 | .unique_tuple = gre_unique_tuple, | 126 | .unique_tuple = gre_unique_tuple, |
145 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 127 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
146 | .range_to_nlattr = nf_nat_port_range_to_nlattr, | 128 | .range_to_nlattr = nf_nat_port_range_to_nlattr, |
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c index ffd5d1589eca..f8c498fc24fd 100644 --- a/net/ipv4/netfilter/nf_nat_proto_tcp.c +++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/random.h> | ||
12 | #include <linux/ip.h> | 11 | #include <linux/ip.h> |
13 | #include <linux/tcp.h> | 12 | #include <linux/tcp.h> |
14 | 13 | ||
@@ -19,22 +18,7 @@ | |||
19 | #include <net/netfilter/nf_nat_protocol.h> | 18 | #include <net/netfilter/nf_nat_protocol.h> |
20 | #include <net/netfilter/nf_nat_core.h> | 19 | #include <net/netfilter/nf_nat_core.h> |
21 | 20 | ||
22 | static int | 21 | static u_int16_t tcp_port_rover; |
23 | tcp_in_range(const struct nf_conntrack_tuple *tuple, | ||
24 | enum nf_nat_manip_type maniptype, | ||
25 | const union nf_conntrack_man_proto *min, | ||
26 | const union nf_conntrack_man_proto *max) | ||
27 | { | ||
28 | __be16 port; | ||
29 | |||
30 | if (maniptype == IP_NAT_MANIP_SRC) | ||
31 | port = tuple->src.u.tcp.port; | ||
32 | else | ||
33 | port = tuple->dst.u.tcp.port; | ||
34 | |||
35 | return ntohs(port) >= ntohs(min->tcp.port) && | ||
36 | ntohs(port) <= ntohs(max->tcp.port); | ||
37 | } | ||
38 | 22 | ||
39 | static int | 23 | static int |
40 | tcp_unique_tuple(struct nf_conntrack_tuple *tuple, | 24 | tcp_unique_tuple(struct nf_conntrack_tuple *tuple, |
@@ -42,49 +26,8 @@ tcp_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
42 | enum nf_nat_manip_type maniptype, | 26 | enum nf_nat_manip_type maniptype, |
43 | const struct nf_conn *ct) | 27 | const struct nf_conn *ct) |
44 | { | 28 | { |
45 | static u_int16_t port; | 29 | return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, |
46 | __be16 *portptr; | 30 | &tcp_port_rover); |
47 | unsigned int range_size, min, i; | ||
48 | |||
49 | if (maniptype == IP_NAT_MANIP_SRC) | ||
50 | portptr = &tuple->src.u.tcp.port; | ||
51 | else | ||
52 | portptr = &tuple->dst.u.tcp.port; | ||
53 | |||
54 | /* If no range specified... */ | ||
55 | if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { | ||
56 | /* If it's dst rewrite, can't change port */ | ||
57 | if (maniptype == IP_NAT_MANIP_DST) | ||
58 | return 0; | ||
59 | |||
60 | /* Map privileged onto privileged. */ | ||
61 | if (ntohs(*portptr) < 1024) { | ||
62 | /* Loose convention: >> 512 is credential passing */ | ||
63 | if (ntohs(*portptr)<512) { | ||
64 | min = 1; | ||
65 | range_size = 511 - min + 1; | ||
66 | } else { | ||
67 | min = 600; | ||
68 | range_size = 1023 - min + 1; | ||
69 | } | ||
70 | } else { | ||
71 | min = 1024; | ||
72 | range_size = 65535 - 1024 + 1; | ||
73 | } | ||
74 | } else { | ||
75 | min = ntohs(range->min.tcp.port); | ||
76 | range_size = ntohs(range->max.tcp.port) - min + 1; | ||
77 | } | ||
78 | |||
79 | if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) | ||
80 | port = net_random(); | ||
81 | |||
82 | for (i = 0; i < range_size; i++, port++) { | ||
83 | *portptr = htons(min + port % range_size); | ||
84 | if (!nf_nat_used_tuple(tuple, ct)) | ||
85 | return 1; | ||
86 | } | ||
87 | return 0; | ||
88 | } | 31 | } |
89 | 32 | ||
90 | static int | 33 | static int |
@@ -142,7 +85,7 @@ const struct nf_nat_protocol nf_nat_protocol_tcp = { | |||
142 | .protonum = IPPROTO_TCP, | 85 | .protonum = IPPROTO_TCP, |
143 | .me = THIS_MODULE, | 86 | .me = THIS_MODULE, |
144 | .manip_pkt = tcp_manip_pkt, | 87 | .manip_pkt = tcp_manip_pkt, |
145 | .in_range = tcp_in_range, | 88 | .in_range = nf_nat_proto_in_range, |
146 | .unique_tuple = tcp_unique_tuple, | 89 | .unique_tuple = tcp_unique_tuple, |
147 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 90 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
148 | .range_to_nlattr = nf_nat_port_range_to_nlattr, | 91 | .range_to_nlattr = nf_nat_port_range_to_nlattr, |
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c index 4b8f49910ff2..a182f5ac3177 100644 --- a/net/ipv4/netfilter/nf_nat_proto_udp.c +++ b/net/ipv4/netfilter/nf_nat_proto_udp.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/random.h> | ||
12 | #include <linux/ip.h> | 11 | #include <linux/ip.h> |
13 | #include <linux/udp.h> | 12 | #include <linux/udp.h> |
14 | 13 | ||
@@ -18,22 +17,7 @@ | |||
18 | #include <net/netfilter/nf_nat_rule.h> | 17 | #include <net/netfilter/nf_nat_rule.h> |
19 | #include <net/netfilter/nf_nat_protocol.h> | 18 | #include <net/netfilter/nf_nat_protocol.h> |
20 | 19 | ||
21 | static int | 20 | static u_int16_t udp_port_rover; |
22 | udp_in_range(const struct nf_conntrack_tuple *tuple, | ||
23 | enum nf_nat_manip_type maniptype, | ||
24 | const union nf_conntrack_man_proto *min, | ||
25 | const union nf_conntrack_man_proto *max) | ||
26 | { | ||
27 | __be16 port; | ||
28 | |||
29 | if (maniptype == IP_NAT_MANIP_SRC) | ||
30 | port = tuple->src.u.udp.port; | ||
31 | else | ||
32 | port = tuple->dst.u.udp.port; | ||
33 | |||
34 | return ntohs(port) >= ntohs(min->udp.port) && | ||
35 | ntohs(port) <= ntohs(max->udp.port); | ||
36 | } | ||
37 | 21 | ||
38 | static int | 22 | static int |
39 | udp_unique_tuple(struct nf_conntrack_tuple *tuple, | 23 | udp_unique_tuple(struct nf_conntrack_tuple *tuple, |
@@ -41,48 +25,8 @@ udp_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
41 | enum nf_nat_manip_type maniptype, | 25 | enum nf_nat_manip_type maniptype, |
42 | const struct nf_conn *ct) | 26 | const struct nf_conn *ct) |
43 | { | 27 | { |
44 | static u_int16_t port; | 28 | return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, |
45 | __be16 *portptr; | 29 | &udp_port_rover); |
46 | unsigned int range_size, min, i; | ||
47 | |||
48 | if (maniptype == IP_NAT_MANIP_SRC) | ||
49 | portptr = &tuple->src.u.udp.port; | ||
50 | else | ||
51 | portptr = &tuple->dst.u.udp.port; | ||
52 | |||
53 | /* If no range specified... */ | ||
54 | if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { | ||
55 | /* If it's dst rewrite, can't change port */ | ||
56 | if (maniptype == IP_NAT_MANIP_DST) | ||
57 | return 0; | ||
58 | |||
59 | if (ntohs(*portptr) < 1024) { | ||
60 | /* Loose convention: >> 512 is credential passing */ | ||
61 | if (ntohs(*portptr)<512) { | ||
62 | min = 1; | ||
63 | range_size = 511 - min + 1; | ||
64 | } else { | ||
65 | min = 600; | ||
66 | range_size = 1023 - min + 1; | ||
67 | } | ||
68 | } else { | ||
69 | min = 1024; | ||
70 | range_size = 65535 - 1024 + 1; | ||
71 | } | ||
72 | } else { | ||
73 | min = ntohs(range->min.udp.port); | ||
74 | range_size = ntohs(range->max.udp.port) - min + 1; | ||
75 | } | ||
76 | |||
77 | if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) | ||
78 | port = net_random(); | ||
79 | |||
80 | for (i = 0; i < range_size; i++, port++) { | ||
81 | *portptr = htons(min + port % range_size); | ||
82 | if (!nf_nat_used_tuple(tuple, ct)) | ||
83 | return 1; | ||
84 | } | ||
85 | return 0; | ||
86 | } | 30 | } |
87 | 31 | ||
88 | static int | 32 | static int |
@@ -132,7 +76,7 @@ const struct nf_nat_protocol nf_nat_protocol_udp = { | |||
132 | .protonum = IPPROTO_UDP, | 76 | .protonum = IPPROTO_UDP, |
133 | .me = THIS_MODULE, | 77 | .me = THIS_MODULE, |
134 | .manip_pkt = udp_manip_pkt, | 78 | .manip_pkt = udp_manip_pkt, |
135 | .in_range = udp_in_range, | 79 | .in_range = nf_nat_proto_in_range, |
136 | .unique_tuple = udp_unique_tuple, | 80 | .unique_tuple = udp_unique_tuple, |
137 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 81 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
138 | .range_to_nlattr = nf_nat_port_range_to_nlattr, | 82 | .range_to_nlattr = nf_nat_port_range_to_nlattr, |