Skip to content

Commit 793d5d6

Browse files
committed
netfilter: flowtable: reduce calls to pskb_may_pull()
Make two unfront calls to pskb_may_pull() to linearize the network and transport header. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent d3519cb commit 793d5d6

2 files changed

Lines changed: 30 additions & 27 deletions

File tree

net/netfilter/nf_flow_table_core.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,7 @@ static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff,
395395
{
396396
struct tcphdr *tcph;
397397

398-
if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) ||
399-
skb_try_make_writable(skb, thoff + sizeof(*tcph)))
398+
if (skb_try_make_writable(skb, thoff + sizeof(*tcph)))
400399
return -1;
401400

402401
tcph = (void *)(skb_network_header(skb) + thoff);
@@ -410,8 +409,7 @@ static int nf_flow_nat_port_udp(struct sk_buff *skb, unsigned int thoff,
410409
{
411410
struct udphdr *udph;
412411

413-
if (!pskb_may_pull(skb, thoff + sizeof(*udph)) ||
414-
skb_try_make_writable(skb, thoff + sizeof(*udph)))
412+
if (skb_try_make_writable(skb, thoff + sizeof(*udph)))
415413
return -1;
416414

417415
udph = (void *)(skb_network_header(skb) + thoff);
@@ -449,8 +447,7 @@ int nf_flow_snat_port(const struct flow_offload *flow,
449447
struct flow_ports *hdr;
450448
__be16 port, new_port;
451449

452-
if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) ||
453-
skb_try_make_writable(skb, thoff + sizeof(*hdr)))
450+
if (skb_try_make_writable(skb, thoff + sizeof(*hdr)))
454451
return -1;
455452

456453
hdr = (void *)(skb_network_header(skb) + thoff);
@@ -481,8 +478,7 @@ int nf_flow_dnat_port(const struct flow_offload *flow,
481478
struct flow_ports *hdr;
482479
__be16 port, new_port;
483480

484-
if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) ||
485-
skb_try_make_writable(skb, thoff + sizeof(*hdr)))
481+
if (skb_try_make_writable(skb, thoff + sizeof(*hdr)))
486482
return -1;
487483

488484
hdr = (void *)(skb_network_header(skb) + thoff);

net/netfilter/nf_flow_table_ip.c

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ static int nf_flow_state_check(struct flow_offload *flow, int proto,
2525
if (proto != IPPROTO_TCP)
2626
return 0;
2727

28-
if (!pskb_may_pull(skb, thoff + sizeof(*tcph)))
29-
return -1;
30-
3128
tcph = (void *)(skb_network_header(skb) + thoff);
3229
if (unlikely(tcph->fin || tcph->rst)) {
3330
flow_offload_teardown(flow);
@@ -42,8 +39,7 @@ static int nf_flow_nat_ip_tcp(struct sk_buff *skb, unsigned int thoff,
4239
{
4340
struct tcphdr *tcph;
4441

45-
if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) ||
46-
skb_try_make_writable(skb, thoff + sizeof(*tcph)))
42+
if (skb_try_make_writable(skb, thoff + sizeof(*tcph)))
4743
return -1;
4844

4945
tcph = (void *)(skb_network_header(skb) + thoff);
@@ -57,8 +53,7 @@ static int nf_flow_nat_ip_udp(struct sk_buff *skb, unsigned int thoff,
5753
{
5854
struct udphdr *udph;
5955

60-
if (!pskb_may_pull(skb, thoff + sizeof(*udph)) ||
61-
skb_try_make_writable(skb, thoff + sizeof(*udph)))
56+
if (skb_try_make_writable(skb, thoff + sizeof(*udph)))
6257
return -1;
6358

6459
udph = (void *)(skb_network_header(skb) + thoff);
@@ -167,8 +162,8 @@ static bool ip_has_options(unsigned int thoff)
167162
static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev,
168163
struct flow_offload_tuple *tuple)
169164
{
165+
unsigned int thoff, hdrsize;
170166
struct flow_ports *ports;
171-
unsigned int thoff;
172167
struct iphdr *iph;
173168

174169
if (!pskb_may_pull(skb, sizeof(*iph)))
@@ -181,15 +176,22 @@ static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev,
181176
unlikely(ip_has_options(thoff)))
182177
return -1;
183178

184-
if (iph->protocol != IPPROTO_TCP &&
185-
iph->protocol != IPPROTO_UDP)
179+
switch (iph->protocol) {
180+
case IPPROTO_TCP:
181+
hdrsize = sizeof(struct tcphdr);
182+
break;
183+
case IPPROTO_UDP:
184+
hdrsize = sizeof(struct udphdr);
185+
break;
186+
default:
186187
return -1;
188+
}
187189

188190
if (iph->ttl <= 1)
189191
return -1;
190192

191193
thoff = iph->ihl * 4;
192-
if (!pskb_may_pull(skb, thoff + sizeof(*ports)))
194+
if (!pskb_may_pull(skb, thoff + hdrsize))
193195
return -1;
194196

195197
iph = ip_hdr(skb);
@@ -315,8 +317,7 @@ static int nf_flow_nat_ipv6_tcp(struct sk_buff *skb, unsigned int thoff,
315317
{
316318
struct tcphdr *tcph;
317319

318-
if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) ||
319-
skb_try_make_writable(skb, thoff + sizeof(*tcph)))
320+
if (skb_try_make_writable(skb, thoff + sizeof(*tcph)))
320321
return -1;
321322

322323
tcph = (void *)(skb_network_header(skb) + thoff);
@@ -332,8 +333,7 @@ static int nf_flow_nat_ipv6_udp(struct sk_buff *skb, unsigned int thoff,
332333
{
333334
struct udphdr *udph;
334335

335-
if (!pskb_may_pull(skb, thoff + sizeof(*udph)) ||
336-
skb_try_make_writable(skb, thoff + sizeof(*udph)))
336+
if (skb_try_make_writable(skb, thoff + sizeof(*udph)))
337337
return -1;
338338

339339
udph = (void *)(skb_network_header(skb) + thoff);
@@ -439,24 +439,31 @@ static int nf_flow_nat_ipv6(const struct flow_offload *flow,
439439
static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev,
440440
struct flow_offload_tuple *tuple)
441441
{
442+
unsigned int thoff, hdrsize;
442443
struct flow_ports *ports;
443444
struct ipv6hdr *ip6h;
444-
unsigned int thoff;
445445

446446
if (!pskb_may_pull(skb, sizeof(*ip6h)))
447447
return -1;
448448

449449
ip6h = ipv6_hdr(skb);
450450

451-
if (ip6h->nexthdr != IPPROTO_TCP &&
452-
ip6h->nexthdr != IPPROTO_UDP)
451+
switch (ip6h->nexthdr) {
452+
case IPPROTO_TCP:
453+
hdrsize = sizeof(struct tcphdr);
454+
break;
455+
case IPPROTO_UDP:
456+
hdrsize = sizeof(struct udphdr);
457+
break;
458+
default:
453459
return -1;
460+
}
454461

455462
if (ip6h->hop_limit <= 1)
456463
return -1;
457464

458465
thoff = sizeof(*ip6h);
459-
if (!pskb_may_pull(skb, thoff + sizeof(*ports)))
466+
if (!pskb_may_pull(skb, thoff + hdrsize))
460467
return -1;
461468

462469
ip6h = ipv6_hdr(skb);

0 commit comments

Comments
 (0)