Skip to content

Commit f440126

Browse files
committed
netfilter: flowtable: fast NAT functions never fail
Simplify existing fast NAT routines by returning void. After the skb_try_make_writable() call consolidation, these routines cannot ever fail. Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 4f08f17 commit f440126

File tree

3 files changed

+84
-116
lines changed

3 files changed

+84
-116
lines changed

include/net/netfilter/nf_flow_table.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,12 @@ void nf_flow_table_free(struct nf_flowtable *flow_table);
229229

230230
void flow_offload_teardown(struct flow_offload *flow);
231231

232-
int nf_flow_snat_port(const struct flow_offload *flow,
233-
struct sk_buff *skb, unsigned int thoff,
234-
u8 protocol, enum flow_offload_tuple_dir dir);
235-
int nf_flow_dnat_port(const struct flow_offload *flow,
236-
struct sk_buff *skb, unsigned int thoff,
237-
u8 protocol, enum flow_offload_tuple_dir dir);
232+
void nf_flow_snat_port(const struct flow_offload *flow,
233+
struct sk_buff *skb, unsigned int thoff,
234+
u8 protocol, enum flow_offload_tuple_dir dir);
235+
void nf_flow_dnat_port(const struct flow_offload *flow,
236+
struct sk_buff *skb, unsigned int thoff,
237+
u8 protocol, enum flow_offload_tuple_dir dir);
238238

239239
struct flow_ports {
240240
__be16 source, dest;

net/netfilter/nf_flow_table_core.c

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -389,20 +389,17 @@ static void nf_flow_offload_work_gc(struct work_struct *work)
389389
queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ);
390390
}
391391

392-
393-
static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff,
394-
__be16 port, __be16 new_port)
392+
static void nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff,
393+
__be16 port, __be16 new_port)
395394
{
396395
struct tcphdr *tcph;
397396

398397
tcph = (void *)(skb_network_header(skb) + thoff);
399398
inet_proto_csum_replace2(&tcph->check, skb, port, new_port, false);
400-
401-
return 0;
402399
}
403400

404-
static int nf_flow_nat_port_udp(struct sk_buff *skb, unsigned int thoff,
405-
__be16 port, __be16 new_port)
401+
static void nf_flow_nat_port_udp(struct sk_buff *skb, unsigned int thoff,
402+
__be16 port, __be16 new_port)
406403
{
407404
struct udphdr *udph;
408405

@@ -413,30 +410,24 @@ static int nf_flow_nat_port_udp(struct sk_buff *skb, unsigned int thoff,
413410
if (!udph->check)
414411
udph->check = CSUM_MANGLED_0;
415412
}
416-
417-
return 0;
418413
}
419414

420-
static int nf_flow_nat_port(struct sk_buff *skb, unsigned int thoff,
421-
u8 protocol, __be16 port, __be16 new_port)
415+
static void nf_flow_nat_port(struct sk_buff *skb, unsigned int thoff,
416+
u8 protocol, __be16 port, __be16 new_port)
422417
{
423418
switch (protocol) {
424419
case IPPROTO_TCP:
425-
if (nf_flow_nat_port_tcp(skb, thoff, port, new_port) < 0)
426-
return NF_DROP;
420+
nf_flow_nat_port_tcp(skb, thoff, port, new_port);
427421
break;
428422
case IPPROTO_UDP:
429-
if (nf_flow_nat_port_udp(skb, thoff, port, new_port) < 0)
430-
return NF_DROP;
423+
nf_flow_nat_port_udp(skb, thoff, port, new_port);
431424
break;
432425
}
433-
434-
return 0;
435426
}
436427

437-
int nf_flow_snat_port(const struct flow_offload *flow,
438-
struct sk_buff *skb, unsigned int thoff,
439-
u8 protocol, enum flow_offload_tuple_dir dir)
428+
void nf_flow_snat_port(const struct flow_offload *flow,
429+
struct sk_buff *skb, unsigned int thoff,
430+
u8 protocol, enum flow_offload_tuple_dir dir)
440431
{
441432
struct flow_ports *hdr;
442433
__be16 port, new_port;
@@ -456,13 +447,13 @@ int nf_flow_snat_port(const struct flow_offload *flow,
456447
break;
457448
}
458449

459-
return nf_flow_nat_port(skb, thoff, protocol, port, new_port);
450+
nf_flow_nat_port(skb, thoff, protocol, port, new_port);
460451
}
461452
EXPORT_SYMBOL_GPL(nf_flow_snat_port);
462453

463-
int nf_flow_dnat_port(const struct flow_offload *flow,
464-
struct sk_buff *skb, unsigned int thoff,
465-
u8 protocol, enum flow_offload_tuple_dir dir)
454+
void nf_flow_dnat_port(const struct flow_offload *flow, struct sk_buff *skb,
455+
unsigned int thoff, u8 protocol,
456+
enum flow_offload_tuple_dir dir)
466457
{
467458
struct flow_ports *hdr;
468459
__be16 port, new_port;
@@ -482,7 +473,7 @@ int nf_flow_dnat_port(const struct flow_offload *flow,
482473
break;
483474
}
484475

485-
return nf_flow_nat_port(skb, thoff, protocol, port, new_port);
476+
nf_flow_nat_port(skb, thoff, protocol, port, new_port);
486477
}
487478
EXPORT_SYMBOL_GPL(nf_flow_dnat_port);
488479

net/netfilter/nf_flow_table_ip.c

Lines changed: 62 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,17 @@ static int nf_flow_state_check(struct flow_offload *flow, int proto,
3434
return 0;
3535
}
3636

37-
static int nf_flow_nat_ip_tcp(struct sk_buff *skb, unsigned int thoff,
38-
__be32 addr, __be32 new_addr)
37+
static void nf_flow_nat_ip_tcp(struct sk_buff *skb, unsigned int thoff,
38+
__be32 addr, __be32 new_addr)
3939
{
4040
struct tcphdr *tcph;
4141

4242
tcph = (void *)(skb_network_header(skb) + thoff);
4343
inet_proto_csum_replace4(&tcph->check, skb, addr, new_addr, true);
44-
45-
return 0;
4644
}
4745

48-
static int nf_flow_nat_ip_udp(struct sk_buff *skb, unsigned int thoff,
49-
__be32 addr, __be32 new_addr)
46+
static void nf_flow_nat_ip_udp(struct sk_buff *skb, unsigned int thoff,
47+
__be32 addr, __be32 new_addr)
5048
{
5149
struct udphdr *udph;
5250

@@ -57,31 +55,25 @@ static int nf_flow_nat_ip_udp(struct sk_buff *skb, unsigned int thoff,
5755
if (!udph->check)
5856
udph->check = CSUM_MANGLED_0;
5957
}
60-
61-
return 0;
6258
}
6359

64-
static int nf_flow_nat_ip_l4proto(struct sk_buff *skb, struct iphdr *iph,
65-
unsigned int thoff, __be32 addr,
66-
__be32 new_addr)
60+
static void nf_flow_nat_ip_l4proto(struct sk_buff *skb, struct iphdr *iph,
61+
unsigned int thoff, __be32 addr,
62+
__be32 new_addr)
6763
{
6864
switch (iph->protocol) {
6965
case IPPROTO_TCP:
70-
if (nf_flow_nat_ip_tcp(skb, thoff, addr, new_addr) < 0)
71-
return NF_DROP;
66+
nf_flow_nat_ip_tcp(skb, thoff, addr, new_addr);
7267
break;
7368
case IPPROTO_UDP:
74-
if (nf_flow_nat_ip_udp(skb, thoff, addr, new_addr) < 0)
75-
return NF_DROP;
69+
nf_flow_nat_ip_udp(skb, thoff, addr, new_addr);
7670
break;
7771
}
78-
79-
return 0;
8072
}
8173

82-
static int nf_flow_snat_ip(const struct flow_offload *flow, struct sk_buff *skb,
83-
struct iphdr *iph, unsigned int thoff,
84-
enum flow_offload_tuple_dir dir)
74+
static void nf_flow_snat_ip(const struct flow_offload *flow,
75+
struct sk_buff *skb, struct iphdr *iph,
76+
unsigned int thoff, enum flow_offload_tuple_dir dir)
8577
{
8678
__be32 addr, new_addr;
8779

@@ -99,12 +91,12 @@ static int nf_flow_snat_ip(const struct flow_offload *flow, struct sk_buff *skb,
9991
}
10092
csum_replace4(&iph->check, addr, new_addr);
10193

102-
return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr);
94+
nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr);
10395
}
10496

105-
static int nf_flow_dnat_ip(const struct flow_offload *flow, struct sk_buff *skb,
106-
struct iphdr *iph, unsigned int thoff,
107-
enum flow_offload_tuple_dir dir)
97+
static void nf_flow_dnat_ip(const struct flow_offload *flow,
98+
struct sk_buff *skb, struct iphdr *iph,
99+
unsigned int thoff, enum flow_offload_tuple_dir dir)
108100
{
109101
__be32 addr, new_addr;
110102

@@ -122,24 +114,21 @@ static int nf_flow_dnat_ip(const struct flow_offload *flow, struct sk_buff *skb,
122114
}
123115
csum_replace4(&iph->check, addr, new_addr);
124116

125-
return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr);
117+
nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr);
126118
}
127119

128-
static int nf_flow_nat_ip(const struct flow_offload *flow, struct sk_buff *skb,
120+
static void nf_flow_nat_ip(const struct flow_offload *flow, struct sk_buff *skb,
129121
unsigned int thoff, enum flow_offload_tuple_dir dir,
130122
struct iphdr *iph)
131123
{
132-
if (test_bit(NF_FLOW_SNAT, &flow->flags) &&
133-
(nf_flow_snat_port(flow, skb, thoff, iph->protocol, dir) < 0 ||
134-
nf_flow_snat_ip(flow, skb, iph, thoff, dir) < 0))
135-
return -1;
136-
137-
if (test_bit(NF_FLOW_DNAT, &flow->flags) &&
138-
(nf_flow_dnat_port(flow, skb, thoff, iph->protocol, dir) < 0 ||
139-
nf_flow_dnat_ip(flow, skb, iph, thoff, dir) < 0))
140-
return -1;
141-
142-
return 0;
124+
if (test_bit(NF_FLOW_SNAT, &flow->flags)) {
125+
nf_flow_snat_port(flow, skb, thoff, iph->protocol, dir);
126+
nf_flow_snat_ip(flow, skb, iph, thoff, dir);
127+
}
128+
if (test_bit(NF_FLOW_DNAT, &flow->flags)) {
129+
nf_flow_dnat_port(flow, skb, thoff, iph->protocol, dir);
130+
nf_flow_dnat_ip(flow, skb, iph, thoff, dir);
131+
}
143132
}
144133

145134
static bool ip_has_options(unsigned int thoff)
@@ -276,8 +265,7 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
276265
return NF_DROP;
277266

278267
iph = ip_hdr(skb);
279-
if (nf_flow_nat_ip(flow, skb, thoff, dir, iph) < 0)
280-
return NF_DROP;
268+
nf_flow_nat_ip(flow, skb, thoff, dir, iph);
281269

282270
ip_decrease_ttl(iph);
283271
skb->tstamp = 0;
@@ -301,22 +289,21 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
301289
}
302290
EXPORT_SYMBOL_GPL(nf_flow_offload_ip_hook);
303291

304-
static int nf_flow_nat_ipv6_tcp(struct sk_buff *skb, unsigned int thoff,
305-
struct in6_addr *addr,
306-
struct in6_addr *new_addr)
292+
static void nf_flow_nat_ipv6_tcp(struct sk_buff *skb, unsigned int thoff,
293+
struct in6_addr *addr,
294+
struct in6_addr *new_addr,
295+
struct ipv6hdr *ip6h)
307296
{
308297
struct tcphdr *tcph;
309298

310299
tcph = (void *)(skb_network_header(skb) + thoff);
311300
inet_proto_csum_replace16(&tcph->check, skb, addr->s6_addr32,
312301
new_addr->s6_addr32, true);
313-
314-
return 0;
315302
}
316303

317-
static int nf_flow_nat_ipv6_udp(struct sk_buff *skb, unsigned int thoff,
318-
struct in6_addr *addr,
319-
struct in6_addr *new_addr)
304+
static void nf_flow_nat_ipv6_udp(struct sk_buff *skb, unsigned int thoff,
305+
struct in6_addr *addr,
306+
struct in6_addr *new_addr)
320307
{
321308
struct udphdr *udph;
322309

@@ -327,32 +314,26 @@ static int nf_flow_nat_ipv6_udp(struct sk_buff *skb, unsigned int thoff,
327314
if (!udph->check)
328315
udph->check = CSUM_MANGLED_0;
329316
}
330-
331-
return 0;
332317
}
333318

334-
static int nf_flow_nat_ipv6_l4proto(struct sk_buff *skb, struct ipv6hdr *ip6h,
335-
unsigned int thoff, struct in6_addr *addr,
336-
struct in6_addr *new_addr)
319+
static void nf_flow_nat_ipv6_l4proto(struct sk_buff *skb, struct ipv6hdr *ip6h,
320+
unsigned int thoff, struct in6_addr *addr,
321+
struct in6_addr *new_addr)
337322
{
338323
switch (ip6h->nexthdr) {
339324
case IPPROTO_TCP:
340-
if (nf_flow_nat_ipv6_tcp(skb, thoff, addr, new_addr) < 0)
341-
return NF_DROP;
325+
nf_flow_nat_ipv6_tcp(skb, thoff, addr, new_addr, ip6h);
342326
break;
343327
case IPPROTO_UDP:
344-
if (nf_flow_nat_ipv6_udp(skb, thoff, addr, new_addr) < 0)
345-
return NF_DROP;
328+
nf_flow_nat_ipv6_udp(skb, thoff, addr, new_addr);
346329
break;
347330
}
348-
349-
return 0;
350331
}
351332

352-
static int nf_flow_snat_ipv6(const struct flow_offload *flow,
353-
struct sk_buff *skb, struct ipv6hdr *ip6h,
354-
unsigned int thoff,
355-
enum flow_offload_tuple_dir dir)
333+
static void nf_flow_snat_ipv6(const struct flow_offload *flow,
334+
struct sk_buff *skb, struct ipv6hdr *ip6h,
335+
unsigned int thoff,
336+
enum flow_offload_tuple_dir dir)
356337
{
357338
struct in6_addr addr, new_addr;
358339

@@ -369,13 +350,13 @@ static int nf_flow_snat_ipv6(const struct flow_offload *flow,
369350
break;
370351
}
371352

372-
return nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr);
353+
nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr);
373354
}
374355

375-
static int nf_flow_dnat_ipv6(const struct flow_offload *flow,
376-
struct sk_buff *skb, struct ipv6hdr *ip6h,
377-
unsigned int thoff,
378-
enum flow_offload_tuple_dir dir)
356+
static void nf_flow_dnat_ipv6(const struct flow_offload *flow,
357+
struct sk_buff *skb, struct ipv6hdr *ip6h,
358+
unsigned int thoff,
359+
enum flow_offload_tuple_dir dir)
379360
{
380361
struct in6_addr addr, new_addr;
381362

@@ -392,27 +373,24 @@ static int nf_flow_dnat_ipv6(const struct flow_offload *flow,
392373
break;
393374
}
394375

395-
return nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr);
376+
nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr);
396377
}
397378

398-
static int nf_flow_nat_ipv6(const struct flow_offload *flow,
399-
struct sk_buff *skb,
400-
enum flow_offload_tuple_dir dir,
401-
struct ipv6hdr *ip6h)
379+
static void nf_flow_nat_ipv6(const struct flow_offload *flow,
380+
struct sk_buff *skb,
381+
enum flow_offload_tuple_dir dir,
382+
struct ipv6hdr *ip6h)
402383
{
403384
unsigned int thoff = sizeof(*ip6h);
404385

405-
if (test_bit(NF_FLOW_SNAT, &flow->flags) &&
406-
(nf_flow_snat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 ||
407-
nf_flow_snat_ipv6(flow, skb, ip6h, thoff, dir) < 0))
408-
return -1;
409-
410-
if (test_bit(NF_FLOW_DNAT, &flow->flags) &&
411-
(nf_flow_dnat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 ||
412-
nf_flow_dnat_ipv6(flow, skb, ip6h, thoff, dir) < 0))
413-
return -1;
414-
415-
return 0;
386+
if (test_bit(NF_FLOW_SNAT, &flow->flags)) {
387+
nf_flow_snat_port(flow, skb, thoff, ip6h->nexthdr, dir);
388+
nf_flow_snat_ipv6(flow, skb, ip6h, thoff, dir);
389+
}
390+
if (test_bit(NF_FLOW_DNAT, &flow->flags)) {
391+
nf_flow_dnat_port(flow, skb, thoff, ip6h->nexthdr, dir);
392+
nf_flow_dnat_ipv6(flow, skb, ip6h, thoff, dir);
393+
}
416394
}
417395

418396
static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev,
@@ -507,8 +485,7 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
507485
return NF_DROP;
508486

509487
ip6h = ipv6_hdr(skb);
510-
if (nf_flow_nat_ipv6(flow, skb, dir, ip6h) < 0)
511-
return NF_DROP;
488+
nf_flow_nat_ipv6(flow, skb, dir, ip6h);
512489

513490
ip6h->hop_limit--;
514491
skb->tstamp = 0;

0 commit comments

Comments
 (0)