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

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
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -1254,20 +1254,19 @@ static int inet_gso_send_check(struct sk_buff *skb)
	if (ihl < sizeof(*iph))
		goto out;

	proto = iph->protocol;

	/* Warning: after this point, iph might be no longer valid */
	if (unlikely(!pskb_may_pull(skb, ihl)))
		goto out;

	__skb_pull(skb, ihl);

	skb_reset_transport_header(skb);
	iph = ip_hdr(skb);
	proto = iph->protocol;
	err = -EPROTONOSUPPORT;

	rcu_read_lock();
	ops = rcu_dereference(inet_offloads[proto]);
	if (likely(ops && ops->callbacks.gso_send_check))
		err = ops->callbacks.gso_send_check(skb);
	rcu_read_unlock();

out:
	return err;
@@ -1305,23 +1304,23 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
	if (ihl < sizeof(*iph))
		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)))
		goto out;
	__skb_pull(skb, ihl);

	tunnel = !!skb->encapsulation;

	__skb_pull(skb, ihl);
	skb_reset_transport_header(skb);
	iph = ip_hdr(skb);
	id = ntohs(iph->id);
	proto = iph->protocol;

	segs = ERR_PTR(-EPROTONOSUPPORT);

	rcu_read_lock();
	ops = rcu_dereference(inet_offloads[proto]);
	if (likely(ops && ops->callbacks.gso_segment))
		segs = ops->callbacks.gso_segment(skb, features);
	rcu_read_unlock();

	if (IS_ERR_OR_NULL(segs))
		goto out;
@@ -1339,8 +1338,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
			iph->id = htons(id++);
		}
		iph->tot_len = htons(skb->len - skb->mac_len);
		iph->check = 0;
		iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
		ip_send_check(iph);
	} while ((skb = skb->next));

out: