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>
This commit is contained in:
parent
d3519cb89f
commit
793d5d6124
@ -395,8 +395,7 @@ static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff,
|
||||
{
|
||||
struct tcphdr *tcph;
|
||||
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) ||
|
||||
skb_try_make_writable(skb, thoff + sizeof(*tcph)))
|
||||
if (skb_try_make_writable(skb, thoff + sizeof(*tcph)))
|
||||
return -1;
|
||||
|
||||
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,
|
||||
{
|
||||
struct udphdr *udph;
|
||||
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*udph)) ||
|
||||
skb_try_make_writable(skb, thoff + sizeof(*udph)))
|
||||
if (skb_try_make_writable(skb, thoff + sizeof(*udph)))
|
||||
return -1;
|
||||
|
||||
udph = (void *)(skb_network_header(skb) + thoff);
|
||||
@ -449,8 +447,7 @@ int nf_flow_snat_port(const struct flow_offload *flow,
|
||||
struct flow_ports *hdr;
|
||||
__be16 port, new_port;
|
||||
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) ||
|
||||
skb_try_make_writable(skb, thoff + sizeof(*hdr)))
|
||||
if (skb_try_make_writable(skb, thoff + sizeof(*hdr)))
|
||||
return -1;
|
||||
|
||||
hdr = (void *)(skb_network_header(skb) + thoff);
|
||||
@ -481,8 +478,7 @@ int nf_flow_dnat_port(const struct flow_offload *flow,
|
||||
struct flow_ports *hdr;
|
||||
__be16 port, new_port;
|
||||
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) ||
|
||||
skb_try_make_writable(skb, thoff + sizeof(*hdr)))
|
||||
if (skb_try_make_writable(skb, thoff + sizeof(*hdr)))
|
||||
return -1;
|
||||
|
||||
hdr = (void *)(skb_network_header(skb) + thoff);
|
||||
|
@ -25,9 +25,6 @@ static int nf_flow_state_check(struct flow_offload *flow, int proto,
|
||||
if (proto != IPPROTO_TCP)
|
||||
return 0;
|
||||
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*tcph)))
|
||||
return -1;
|
||||
|
||||
tcph = (void *)(skb_network_header(skb) + thoff);
|
||||
if (unlikely(tcph->fin || tcph->rst)) {
|
||||
flow_offload_teardown(flow);
|
||||
@ -42,8 +39,7 @@ static int nf_flow_nat_ip_tcp(struct sk_buff *skb, unsigned int thoff,
|
||||
{
|
||||
struct tcphdr *tcph;
|
||||
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) ||
|
||||
skb_try_make_writable(skb, thoff + sizeof(*tcph)))
|
||||
if (skb_try_make_writable(skb, thoff + sizeof(*tcph)))
|
||||
return -1;
|
||||
|
||||
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,
|
||||
{
|
||||
struct udphdr *udph;
|
||||
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*udph)) ||
|
||||
skb_try_make_writable(skb, thoff + sizeof(*udph)))
|
||||
if (skb_try_make_writable(skb, thoff + sizeof(*udph)))
|
||||
return -1;
|
||||
|
||||
udph = (void *)(skb_network_header(skb) + thoff);
|
||||
@ -167,8 +162,8 @@ static bool ip_has_options(unsigned int thoff)
|
||||
static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev,
|
||||
struct flow_offload_tuple *tuple)
|
||||
{
|
||||
unsigned int thoff, hdrsize;
|
||||
struct flow_ports *ports;
|
||||
unsigned int thoff;
|
||||
struct iphdr *iph;
|
||||
|
||||
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,
|
||||
unlikely(ip_has_options(thoff)))
|
||||
return -1;
|
||||
|
||||
if (iph->protocol != IPPROTO_TCP &&
|
||||
iph->protocol != IPPROTO_UDP)
|
||||
switch (iph->protocol) {
|
||||
case IPPROTO_TCP:
|
||||
hdrsize = sizeof(struct tcphdr);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
hdrsize = sizeof(struct udphdr);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iph->ttl <= 1)
|
||||
return -1;
|
||||
|
||||
thoff = iph->ihl * 4;
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*ports)))
|
||||
if (!pskb_may_pull(skb, thoff + hdrsize))
|
||||
return -1;
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
@ -315,8 +317,7 @@ static int nf_flow_nat_ipv6_tcp(struct sk_buff *skb, unsigned int thoff,
|
||||
{
|
||||
struct tcphdr *tcph;
|
||||
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) ||
|
||||
skb_try_make_writable(skb, thoff + sizeof(*tcph)))
|
||||
if (skb_try_make_writable(skb, thoff + sizeof(*tcph)))
|
||||
return -1;
|
||||
|
||||
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,
|
||||
{
|
||||
struct udphdr *udph;
|
||||
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*udph)) ||
|
||||
skb_try_make_writable(skb, thoff + sizeof(*udph)))
|
||||
if (skb_try_make_writable(skb, thoff + sizeof(*udph)))
|
||||
return -1;
|
||||
|
||||
udph = (void *)(skb_network_header(skb) + thoff);
|
||||
@ -439,24 +439,31 @@ static int nf_flow_nat_ipv6(const struct flow_offload *flow,
|
||||
static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev,
|
||||
struct flow_offload_tuple *tuple)
|
||||
{
|
||||
unsigned int thoff, hdrsize;
|
||||
struct flow_ports *ports;
|
||||
struct ipv6hdr *ip6h;
|
||||
unsigned int thoff;
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(*ip6h)))
|
||||
return -1;
|
||||
|
||||
ip6h = ipv6_hdr(skb);
|
||||
|
||||
if (ip6h->nexthdr != IPPROTO_TCP &&
|
||||
ip6h->nexthdr != IPPROTO_UDP)
|
||||
switch (ip6h->nexthdr) {
|
||||
case IPPROTO_TCP:
|
||||
hdrsize = sizeof(struct tcphdr);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
hdrsize = sizeof(struct udphdr);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ip6h->hop_limit <= 1)
|
||||
return -1;
|
||||
|
||||
thoff = sizeof(*ip6h);
|
||||
if (!pskb_may_pull(skb, thoff + sizeof(*ports)))
|
||||
if (!pskb_may_pull(skb, thoff + hdrsize))
|
||||
return -1;
|
||||
|
||||
ip6h = ipv6_hdr(skb);
|
||||
|
Loading…
Reference in New Issue
Block a user