Skip to content

Commit 716b23c

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: nat: un-export nf_nat_l4proto_unique_tuple
almost all l4proto->unique_tuple implementations just call this helper, so make ->unique_tuple() optional and call its helper directly if the l4proto doesn't override it. This is an intermediate step to get rid of ->unique_tuple completely. Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 912da92 commit 716b23c

File tree

7 files changed

+75
-135
lines changed

7 files changed

+75
-135
lines changed

include/net/netfilter/nf_nat_l4proto.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,6 @@ bool nf_nat_l4proto_in_range(const struct nf_conntrack_tuple *tuple,
7070
const union nf_conntrack_man_proto *min,
7171
const union nf_conntrack_man_proto *max);
7272

73-
void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
74-
struct nf_conntrack_tuple *tuple,
75-
const struct nf_nat_range2 *range,
76-
enum nf_nat_manip_type maniptype,
77-
const struct nf_conn *ct);
78-
7973
int nf_nat_l4proto_nlattr_to_range(struct nlattr *tb[],
8074
struct nf_nat_range2 *range);
8175

net/netfilter/nf_nat_core.c

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,77 @@ find_best_ips_proto(const struct nf_conntrack_zone *zone,
310310
}
311311
}
312312

313+
static void nf_nat_l4proto_unique_tuple(struct nf_conntrack_tuple *tuple,
314+
const struct nf_nat_range2 *range,
315+
enum nf_nat_manip_type maniptype,
316+
const struct nf_conn *ct)
317+
{
318+
unsigned int range_size, min, max, i, attempts;
319+
__be16 *portptr;
320+
u16 off;
321+
static const unsigned int max_attempts = 128;
322+
323+
if (maniptype == NF_NAT_MANIP_SRC)
324+
portptr = &tuple->src.u.all;
325+
else
326+
portptr = &tuple->dst.u.all;
327+
328+
/* If no range specified... */
329+
if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)) {
330+
/* If it's dst rewrite, can't change port */
331+
if (maniptype == NF_NAT_MANIP_DST)
332+
return;
333+
334+
if (ntohs(*portptr) < 1024) {
335+
/* Loose convention: >> 512 is credential passing */
336+
if (ntohs(*portptr) < 512) {
337+
min = 1;
338+
range_size = 511 - min + 1;
339+
} else {
340+
min = 600;
341+
range_size = 1023 - min + 1;
342+
}
343+
} else {
344+
min = 1024;
345+
range_size = 65535 - 1024 + 1;
346+
}
347+
} else {
348+
min = ntohs(range->min_proto.all);
349+
max = ntohs(range->max_proto.all);
350+
if (unlikely(max < min))
351+
swap(max, min);
352+
range_size = max - min + 1;
353+
}
354+
355+
if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
356+
off = (ntohs(*portptr) - ntohs(range->base_proto.all));
357+
else
358+
off = prandom_u32();
359+
360+
attempts = range_size;
361+
if (attempts > max_attempts)
362+
attempts = max_attempts;
363+
364+
/* We are in softirq; doing a search of the entire range risks
365+
* soft lockup when all tuples are already used.
366+
*
367+
* If we can't find any free port from first offset, pick a new
368+
* one and try again, with ever smaller search window.
369+
*/
370+
another_round:
371+
for (i = 0; i < attempts; i++, off++) {
372+
*portptr = htons(min + off % range_size);
373+
if (!nf_nat_used_tuple(tuple, ct))
374+
return;
375+
}
376+
377+
if (attempts >= range_size || attempts < 16)
378+
return;
379+
attempts /= 2;
380+
off = prandom_u32();
381+
goto another_round;
382+
}
383+
313384
/* Manipulate the tuple into the range given. For NF_INET_POST_ROUTING,
314385
* we change the source to map into the range. For NF_INET_PRE_ROUTING
315386
* and NF_INET_LOCAL_OUT, we change the destination to map into the
@@ -383,7 +454,10 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
383454
}
384455

385456
/* Last chance: get protocol to try to obtain unique tuple. */
386-
l4proto->unique_tuple(l3proto, tuple, range, maniptype, ct);
457+
if (l4proto->unique_tuple)
458+
l4proto->unique_tuple(l3proto, tuple, range, maniptype, ct);
459+
else
460+
nf_nat_l4proto_unique_tuple(tuple, range, maniptype, ct);
387461
out:
388462
rcu_read_unlock();
389463
}

net/netfilter/nf_nat_proto_common.c

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -34,79 +34,6 @@ bool nf_nat_l4proto_in_range(const struct nf_conntrack_tuple *tuple,
3434
}
3535
EXPORT_SYMBOL_GPL(nf_nat_l4proto_in_range);
3636

37-
void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
38-
struct nf_conntrack_tuple *tuple,
39-
const struct nf_nat_range2 *range,
40-
enum nf_nat_manip_type maniptype,
41-
const struct nf_conn *ct)
42-
{
43-
unsigned int range_size, min, max, i, attempts;
44-
__be16 *portptr;
45-
u16 off;
46-
static const unsigned int max_attempts = 128;
47-
48-
if (maniptype == NF_NAT_MANIP_SRC)
49-
portptr = &tuple->src.u.all;
50-
else
51-
portptr = &tuple->dst.u.all;
52-
53-
/* If no range specified... */
54-
if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)) {
55-
/* If it's dst rewrite, can't change port */
56-
if (maniptype == NF_NAT_MANIP_DST)
57-
return;
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_proto.all);
74-
max = ntohs(range->max_proto.all);
75-
if (unlikely(max < min))
76-
swap(max, min);
77-
range_size = max - min + 1;
78-
}
79-
80-
if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
81-
off = (ntohs(*portptr) - ntohs(range->base_proto.all));
82-
else
83-
off = prandom_u32();
84-
85-
attempts = range_size;
86-
if (attempts > max_attempts)
87-
attempts = max_attempts;
88-
89-
/* We are in softirq; doing a search of the entire range risks
90-
* soft lockup when all tuples are already used.
91-
*
92-
* If we can't find any free port from first offset, pick a new
93-
* one and try again, with ever smaller search window.
94-
*/
95-
another_round:
96-
for (i = 0; i < attempts; i++, off++) {
97-
*portptr = htons(min + off % range_size);
98-
if (!nf_nat_used_tuple(tuple, ct))
99-
return;
100-
}
101-
102-
if (attempts >= range_size || attempts < 16)
103-
return;
104-
attempts /= 2;
105-
off = prandom_u32();
106-
goto another_round;
107-
}
108-
EXPORT_SYMBOL_GPL(nf_nat_l4proto_unique_tuple);
109-
11037
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
11138
int nf_nat_l4proto_nlattr_to_range(struct nlattr *tb[],
11239
struct nf_nat_range2 *range)

net/netfilter/nf_nat_proto_dccp.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,6 @@
1818
#include <net/netfilter/nf_nat_l3proto.h>
1919
#include <net/netfilter/nf_nat_l4proto.h>
2020

21-
static void
22-
dccp_unique_tuple(const struct nf_nat_l3proto *l3proto,
23-
struct nf_conntrack_tuple *tuple,
24-
const struct nf_nat_range2 *range,
25-
enum nf_nat_manip_type maniptype,
26-
const struct nf_conn *ct)
27-
{
28-
nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
29-
}
30-
3121
static bool
3222
dccp_manip_pkt(struct sk_buff *skb,
3323
const struct nf_nat_l3proto *l3proto,
@@ -72,7 +62,6 @@ const struct nf_nat_l4proto nf_nat_l4proto_dccp = {
7262
.l4proto = IPPROTO_DCCP,
7363
.manip_pkt = dccp_manip_pkt,
7464
.in_range = nf_nat_l4proto_in_range,
75-
.unique_tuple = dccp_unique_tuple,
7665
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
7766
.nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
7867
#endif

net/netfilter/nf_nat_proto_sctp.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,6 @@
1212

1313
#include <net/netfilter/nf_nat_l4proto.h>
1414

15-
static void
16-
sctp_unique_tuple(const struct nf_nat_l3proto *l3proto,
17-
struct nf_conntrack_tuple *tuple,
18-
const struct nf_nat_range2 *range,
19-
enum nf_nat_manip_type maniptype,
20-
const struct nf_conn *ct)
21-
{
22-
nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
23-
}
24-
2515
static bool
2616
sctp_manip_pkt(struct sk_buff *skb,
2717
const struct nf_nat_l3proto *l3proto,
@@ -67,7 +57,6 @@ const struct nf_nat_l4proto nf_nat_l4proto_sctp = {
6757
.l4proto = IPPROTO_SCTP,
6858
.manip_pkt = sctp_manip_pkt,
6959
.in_range = nf_nat_l4proto_in_range,
70-
.unique_tuple = sctp_unique_tuple,
7160
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
7261
.nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
7362
#endif

net/netfilter/nf_nat_proto_tcp.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,6 @@
1818
#include <net/netfilter/nf_nat_l4proto.h>
1919
#include <net/netfilter/nf_nat_core.h>
2020

21-
static void
22-
tcp_unique_tuple(const struct nf_nat_l3proto *l3proto,
23-
struct nf_conntrack_tuple *tuple,
24-
const struct nf_nat_range2 *range,
25-
enum nf_nat_manip_type maniptype,
26-
const struct nf_conn *ct)
27-
{
28-
nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
29-
}
30-
3121
static bool
3222
tcp_manip_pkt(struct sk_buff *skb,
3323
const struct nf_nat_l3proto *l3proto,
@@ -75,7 +65,6 @@ const struct nf_nat_l4proto nf_nat_l4proto_tcp = {
7565
.l4proto = IPPROTO_TCP,
7666
.manip_pkt = tcp_manip_pkt,
7767
.in_range = nf_nat_l4proto_in_range,
78-
.unique_tuple = tcp_unique_tuple,
7968
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
8069
.nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
8170
#endif

net/netfilter/nf_nat_proto_udp.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,6 @@
1717
#include <net/netfilter/nf_nat_l3proto.h>
1818
#include <net/netfilter/nf_nat_l4proto.h>
1919

20-
static void
21-
udp_unique_tuple(const struct nf_nat_l3proto *l3proto,
22-
struct nf_conntrack_tuple *tuple,
23-
const struct nf_nat_range2 *range,
24-
enum nf_nat_manip_type maniptype,
25-
const struct nf_conn *ct)
26-
{
27-
nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
28-
}
29-
3020
static void
3121
__udp_manip_pkt(struct sk_buff *skb,
3222
const struct nf_nat_l3proto *l3proto,
@@ -92,21 +82,10 @@ static bool udplite_manip_pkt(struct sk_buff *skb,
9282
return true;
9383
}
9484

95-
static void
96-
udplite_unique_tuple(const struct nf_nat_l3proto *l3proto,
97-
struct nf_conntrack_tuple *tuple,
98-
const struct nf_nat_range2 *range,
99-
enum nf_nat_manip_type maniptype,
100-
const struct nf_conn *ct)
101-
{
102-
nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
103-
}
104-
10585
const struct nf_nat_l4proto nf_nat_l4proto_udplite = {
10686
.l4proto = IPPROTO_UDPLITE,
10787
.manip_pkt = udplite_manip_pkt,
10888
.in_range = nf_nat_l4proto_in_range,
109-
.unique_tuple = udplite_unique_tuple,
11089
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
11190
.nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
11291
#endif
@@ -117,7 +96,6 @@ const struct nf_nat_l4proto nf_nat_l4proto_udp = {
11796
.l4proto = IPPROTO_UDP,
11897
.manip_pkt = udp_manip_pkt,
11998
.in_range = nf_nat_l4proto_in_range,
120-
.unique_tuple = udp_unique_tuple,
12199
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
122100
.nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
123101
#endif

0 commit comments

Comments
 (0)