udp: Avoid post-GRO UDP checksum recalculation
[linux-2.6-microblaze.git] / include / net / udp.h
index d8ce937..dbe030d 100644 (file)
@@ -471,12 +471,19 @@ void udpv6_encap_enable(void);
 static inline struct sk_buff *udp_rcv_segment(struct sock *sk,
                                              struct sk_buff *skb, bool ipv4)
 {
+       netdev_features_t features = NETIF_F_SG;
        struct sk_buff *segs;
 
+       /* Avoid csum recalculation by skb_segment unless userspace explicitly
+        * asks for the final checksum values
+        */
+       if (!inet_get_convert_csum(sk))
+               features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
        /* the GSO CB lays after the UDP one, no need to save and restore any
         * CB fragment
         */
-       segs = __skb_gso_segment(skb, NETIF_F_SG, false);
+       segs = __skb_gso_segment(skb, features, false);
        if (unlikely(IS_ERR_OR_NULL(segs))) {
                int segs_nr = skb_shinfo(skb)->gso_segs;