Commit 35ffb665 authored by Richard Gobert's avatar Richard Gobert Committed by Paolo Abeni
Browse files

net: gro: skb_gro_header helper function



Introduce a simple helper function to replace a common pattern.
When accessing the GRO header, we fetch the pointer from frag0,
then test its validity and fetch it from the skb when necessary.

This leads to the pattern
skb_gro_header_fast -> skb_gro_header_hard -> skb_gro_header_slow
recurring many times throughout GRO code.

This patch replaces these patterns with a single inlined function
call, improving code readability.

Signed-off-by: default avatarRichard Gobert <richardbgobert@gmail.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20220823071034.GA56142@debian


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 77a70f9c
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -503,12 +503,9 @@ static struct sk_buff *geneve_gro_receive(struct sock *sk,

	off_gnv = skb_gro_offset(skb);
	hlen = off_gnv + sizeof(*gh);
	gh = skb_gro_header_fast(skb, off_gnv);
	if (skb_gro_header_hard(skb, hlen)) {
		gh = skb_gro_header_slow(skb, hlen, off_gnv);
	gh = skb_gro_header(skb, hlen, off_gnv);
	if (unlikely(!gh))
		goto out;
	}

	if (gh->ver != GENEVE_VER || gh->oam)
		goto out;
+3 −6
Original line number Diff line number Diff line
@@ -713,12 +713,9 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk,

	off_vx = skb_gro_offset(skb);
	hlen = off_vx + sizeof(*vh);
	vh   = skb_gro_header_fast(skb, off_vx);
	if (skb_gro_header_hard(skb, hlen)) {
		vh = skb_gro_header_slow(skb, hlen, off_vx);
	vh = skb_gro_header(skb, hlen, off_vx);
	if (unlikely(!vh))
		goto out;
	}

	skb_gro_postpull_rcsum(skb, vh, sizeof(struct vxlanhdr));

+18 −15
Original line number Diff line number Diff line
@@ -160,6 +160,17 @@ static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
	return skb->data + offset;
}

static inline void *skb_gro_header(struct sk_buff *skb,
					unsigned int hlen, unsigned int offset)
{
	void *ptr;

	ptr = skb_gro_header_fast(skb, offset);
	if (skb_gro_header_hard(skb, hlen))
		ptr = skb_gro_header_slow(skb, hlen, offset);
	return ptr;
}

static inline void *skb_gro_network_header(struct sk_buff *skb)
{
	return (NAPI_GRO_CB(skb)->frag0 ?: skb->data) +
@@ -301,12 +312,9 @@ static inline void *skb_gro_remcsum_process(struct sk_buff *skb, void *ptr,
		return ptr;
	}

	ptr = skb_gro_header_fast(skb, off);
	if (skb_gro_header_hard(skb, off + plen)) {
		ptr = skb_gro_header_slow(skb, off + plen, off);
	ptr = skb_gro_header(skb, off + plen, off);
	if (!ptr)
		return NULL;
	}

	delta = remcsum_adjust(ptr + hdrlen, NAPI_GRO_CB(skb)->csum,
			       start, offset);
@@ -329,12 +337,9 @@ static inline void skb_gro_remcsum_cleanup(struct sk_buff *skb,
	if (!grc->delta)
		return;

	ptr = skb_gro_header_fast(skb, grc->offset);
	if (skb_gro_header_hard(skb, grc->offset + sizeof(u16))) {
		ptr = skb_gro_header_slow(skb, plen, grc->offset);
	ptr = skb_gro_header(skb, plen, grc->offset);
	if (!ptr)
		return;
	}

	remcsum_unadjust((__sum16 *)ptr, grc->delta);
}
@@ -405,9 +410,7 @@ static inline struct udphdr *udp_gro_udphdr(struct sk_buff *skb)

	off  = skb_gro_offset(skb);
	hlen = off + sizeof(*uh);
	uh   = skb_gro_header_fast(skb, off);
	if (skb_gro_header_hard(skb, hlen))
		uh = skb_gro_header_slow(skb, hlen, off);
	uh   = skb_gro_header(skb, hlen, off);

	return uh;
}
+3 −6
Original line number Diff line number Diff line
@@ -467,12 +467,9 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head,

	off_vlan = skb_gro_offset(skb);
	hlen = off_vlan + sizeof(*vhdr);
	vhdr = skb_gro_header_fast(skb, off_vlan);
	if (skb_gro_header_hard(skb, hlen)) {
		vhdr = skb_gro_header_slow(skb, hlen, off_vlan);
	vhdr = skb_gro_header(skb, hlen, off_vlan);
	if (unlikely(!vhdr))
		goto out;
	}

	type = vhdr->h_vlan_encapsulated_proto;

+3 −6
Original line number Diff line number Diff line
@@ -414,12 +414,9 @@ struct sk_buff *eth_gro_receive(struct list_head *head, struct sk_buff *skb)

	off_eth = skb_gro_offset(skb);
	hlen = off_eth + sizeof(*eh);
	eh = skb_gro_header_fast(skb, off_eth);
	if (skb_gro_header_hard(skb, hlen)) {
		eh = skb_gro_header_slow(skb, hlen, off_eth);
	eh = skb_gro_header(skb, hlen, off_eth);
	if (unlikely(!eh))
		goto out;
	}

	flush = 0;

Loading