aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/udp.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/udp.h')
-rw-r--r--include/net/udp.h10
1 files changed, 10 insertions, 0 deletions
diff --git a/include/net/udp.h b/include/net/udp.h
index 79d141d2103b..f2c1178f6e12 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -476,6 +476,16 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk,
if (!inet_get_convert_csum(sk))
features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ /* UDP segmentation expects packets of type CHECKSUM_PARTIAL or
+ * CHECKSUM_NONE in __udp_gso_segment. UDP GRO indeed builds partial
+ * packets in udp_gro_complete_segment. As does UDP GSO, verified by
+ * udp_send_skb. But when those packets are looped in dev_loopback_xmit
+ * their ip_summed is set to CHECKSUM_UNNECESSARY. Reset in this
+ * specific case, where PARTIAL is both correct and required.
+ */
+ if (skb->pkt_type == PACKET_LOOPBACK)
+ skb->ip_summed = CHECKSUM_PARTIAL;
+
/* the GSO CB lays after the UDP one, no need to save and restore any
* CB fragment
*/