summaryrefslogtreecommitdiff
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/udp.c4
-rw-r--r--net/ipv6/udp_offload.c24
2 files changed, 21 insertions, 7 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 12fcce8fba46..f6ba535b6feb 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -891,6 +891,10 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
goto csum_error;
}
+ if (udp_sk(sk)->convert_csum && uh->check && !IS_UDPLITE(sk))
+ skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
+ ip6_compute_pseudo);
+
ret = udpv6_queue_rcv_skb(sk, skb);
sock_put(sk);
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index b13e377e9c53..89cb9a9b8537 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -134,16 +134,26 @@ static struct sk_buff **udp6_gro_receive(struct sk_buff **head,
{
struct udphdr *uh = udp_gro_udphdr(skb);
+ if (unlikely(!uh))
+ goto flush;
+
/* Don't bother verifying checksum if we're going to flush anyway. */
- if (unlikely(!uh) ||
- (!NAPI_GRO_CB(skb)->flush &&
- skb_gro_checksum_validate_zero_check(skb, IPPROTO_UDP, uh->check,
- ip6_gro_compute_pseudo))) {
- NAPI_GRO_CB(skb)->flush = 1;
- return NULL;
- }
+ if (!NAPI_GRO_CB(skb)->flush)
+ goto skip;
+ if (skb_gro_checksum_validate_zero_check(skb, IPPROTO_UDP, uh->check,
+ ip6_gro_compute_pseudo))
+ goto flush;
+ else if (uh->check)
+ skb_gro_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
+ ip6_gro_compute_pseudo);
+
+skip:
return udp_gro_receive(head, skb, uh);
+
+flush:
+ NAPI_GRO_CB(skb)->flush = 1;
+ return NULL;
}
int udp6_gro_complete(struct sk_buff *skb, int nhoff)