|
@@ -79,7 +79,11 @@ static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
|
|
|
__be16 *pd = data;
|
|
|
size_t start = ntohs(pd[0]);
|
|
|
size_t offset = ntohs(pd[1]);
|
|
|
- size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start);
|
|
|
+ size_t plen = sizeof(struct udphdr) + hdrlen +
|
|
|
+ max_t(size_t, offset + sizeof(u16), start);
|
|
|
+
|
|
|
+ if (skb->remcsum_offload)
|
|
|
+ return guehdr;
|
|
|
|
|
|
if (!pskb_may_pull(skb, plen))
|
|
|
return NULL;
|
|
@@ -221,29 +225,21 @@ out_unlock:
|
|
|
|
|
|
static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
|
|
|
struct guehdr *guehdr, void *data,
|
|
|
- size_t hdrlen, u8 ipproto,
|
|
|
- struct gro_remcsum *grc, bool nopartial)
|
|
|
+ size_t hdrlen, struct gro_remcsum *grc,
|
|
|
+ bool nopartial)
|
|
|
{
|
|
|
__be16 *pd = data;
|
|
|
size_t start = ntohs(pd[0]);
|
|
|
size_t offset = ntohs(pd[1]);
|
|
|
- size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start);
|
|
|
|
|
|
if (skb->remcsum_offload)
|
|
|
- return NULL;
|
|
|
+ return guehdr;
|
|
|
|
|
|
if (!NAPI_GRO_CB(skb)->csum_valid)
|
|
|
return NULL;
|
|
|
|
|
|
- /* Pull checksum that will be written */
|
|
|
- if (skb_gro_header_hard(skb, off + plen)) {
|
|
|
- guehdr = skb_gro_header_slow(skb, off + plen, off);
|
|
|
- if (!guehdr)
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- skb_gro_remcsum_process(skb, (void *)guehdr + hdrlen,
|
|
|
- start, offset, grc, nopartial);
|
|
|
+ guehdr = skb_gro_remcsum_process(skb, (void *)guehdr, off, hdrlen,
|
|
|
+ start, offset, grc, nopartial);
|
|
|
|
|
|
skb->remcsum_offload = 1;
|
|
|
|
|
@@ -307,10 +303,10 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head,
|
|
|
|
|
|
if (flags & GUE_PFLAG_REMCSUM) {
|
|
|
guehdr = gue_gro_remcsum(skb, off, guehdr,
|
|
|
- data + doffset, hdrlen,
|
|
|
- guehdr->proto_ctype, &grc,
|
|
|
+ data + doffset, hdrlen, &grc,
|
|
|
!!(fou->flags &
|
|
|
FOU_F_REMCSUM_NOPARTIAL));
|
|
|
+
|
|
|
if (!guehdr)
|
|
|
goto out;
|
|
|
|