Commit 47d27aad authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

ipv4: gso: send_check() & segment() cleanups

inet_gso_segment() and inet_gso_send_check() are called by
skb_mac_gso_segment() under rcu lock, no need to use
rcu_read_lock() / rcu_read_unlock()

Avoid calling ip_hdr() twice per function.

We can use ip_send_check() helper.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a729e83a
...@@ -1254,20 +1254,19 @@ static int inet_gso_send_check(struct sk_buff *skb) ...@@ -1254,20 +1254,19 @@ static int inet_gso_send_check(struct sk_buff *skb)
if (ihl < sizeof(*iph)) if (ihl < sizeof(*iph))
goto out; goto out;
proto = iph->protocol;
/* Warning: after this point, iph might be no longer valid */
if (unlikely(!pskb_may_pull(skb, ihl))) if (unlikely(!pskb_may_pull(skb, ihl)))
goto out; goto out;
__skb_pull(skb, ihl); __skb_pull(skb, ihl);
skb_reset_transport_header(skb); skb_reset_transport_header(skb);
iph = ip_hdr(skb);
proto = iph->protocol;
err = -EPROTONOSUPPORT; err = -EPROTONOSUPPORT;
rcu_read_lock();
ops = rcu_dereference(inet_offloads[proto]); ops = rcu_dereference(inet_offloads[proto]);
if (likely(ops && ops->callbacks.gso_send_check)) if (likely(ops && ops->callbacks.gso_send_check))
err = ops->callbacks.gso_send_check(skb); err = ops->callbacks.gso_send_check(skb);
rcu_read_unlock();
out: out:
return err; return err;
...@@ -1305,23 +1304,23 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, ...@@ -1305,23 +1304,23 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
if (ihl < sizeof(*iph)) if (ihl < sizeof(*iph))
goto out; goto out;
id = ntohs(iph->id);
proto = iph->protocol;
/* Warning: after this point, iph might be no longer valid */
if (unlikely(!pskb_may_pull(skb, ihl))) if (unlikely(!pskb_may_pull(skb, ihl)))
goto out; goto out;
__skb_pull(skb, ihl);
tunnel = !!skb->encapsulation; tunnel = !!skb->encapsulation;
__skb_pull(skb, ihl);
skb_reset_transport_header(skb); skb_reset_transport_header(skb);
iph = ip_hdr(skb);
id = ntohs(iph->id);
proto = iph->protocol;
segs = ERR_PTR(-EPROTONOSUPPORT); segs = ERR_PTR(-EPROTONOSUPPORT);
rcu_read_lock();
ops = rcu_dereference(inet_offloads[proto]); ops = rcu_dereference(inet_offloads[proto]);
if (likely(ops && ops->callbacks.gso_segment)) if (likely(ops && ops->callbacks.gso_segment))
segs = ops->callbacks.gso_segment(skb, features); segs = ops->callbacks.gso_segment(skb, features);
rcu_read_unlock();
if (IS_ERR_OR_NULL(segs)) if (IS_ERR_OR_NULL(segs))
goto out; goto out;
...@@ -1339,8 +1338,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, ...@@ -1339,8 +1338,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
iph->id = htons(id++); iph->id = htons(id++);
} }
iph->tot_len = htons(skb->len - skb->mac_len); iph->tot_len = htons(skb->len - skb->mac_len);
iph->check = 0; ip_send_check(iph);
iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
} while ((skb = skb->next)); } while ((skb = skb->next));
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment