@@ -1883,7 +1883,13 @@ struct napi_gro_cb {
1883
1883
u16 proto ;
1884
1884
1885
1885
/* Used in udp_gro_receive */
1886
- u16 udp_mark ;
1886
+ u8 udp_mark :1 ;
1887
+
1888
+ /* GRO checksum is valid */
1889
+ u8 csum_valid :1 ;
1890
+
1891
+ /* Number encapsulation layers crossed */
1892
+ u8 encapsulation ;
1887
1893
1888
1894
/* used to support CHECKSUM_COMPLETE for tunneling protocols */
1889
1895
__wsum csum ;
@@ -2154,11 +2160,77 @@ static inline void *skb_gro_network_header(struct sk_buff *skb)
2154
2160
static inline void skb_gro_postpull_rcsum (struct sk_buff * skb ,
2155
2161
const void * start , unsigned int len )
2156
2162
{
2157
- if (skb -> ip_summed == CHECKSUM_COMPLETE )
2163
+ if (NAPI_GRO_CB ( skb ) -> csum_valid )
2158
2164
NAPI_GRO_CB (skb )-> csum = csum_sub (NAPI_GRO_CB (skb )-> csum ,
2159
2165
csum_partial (start , len , 0 ));
2160
2166
}
2161
2167
2168
+ /* GRO checksum functions. These are logical equivalents of the normal
2169
+ * checksum functions (in skbuff.h) except that they operate on the GRO
2170
+ * offsets and fields in sk_buff.
2171
+ */
2172
+
2173
+ __sum16 __skb_gro_checksum_complete (struct sk_buff * skb );
2174
+
2175
+ static inline bool __skb_gro_checksum_validate_needed (struct sk_buff * skb ,
2176
+ bool zero_okay ,
2177
+ __sum16 check )
2178
+ {
2179
+ return (skb -> ip_summed != CHECKSUM_PARTIAL &&
2180
+ (skb -> ip_summed != CHECKSUM_UNNECESSARY ||
2181
+ (NAPI_GRO_CB (skb )-> encapsulation > skb -> encapsulation )) &&
2182
+ (!zero_okay || check ));
2183
+ }
2184
+
2185
+ static inline __sum16 __skb_gro_checksum_validate_complete (struct sk_buff * skb ,
2186
+ __wsum psum )
2187
+ {
2188
+ if (NAPI_GRO_CB (skb )-> csum_valid &&
2189
+ !csum_fold (csum_add (psum , NAPI_GRO_CB (skb )-> csum )))
2190
+ return 0 ;
2191
+
2192
+ NAPI_GRO_CB (skb )-> csum = psum ;
2193
+
2194
+ return __skb_gro_checksum_complete (skb );
2195
+ }
2196
+
2197
+ /* Update skb for CHECKSUM_UNNECESSARY when we verified a top level
2198
+ * checksum or an encapsulated one during GRO. This saves work
2199
+ * if we fallback to normal path with the packet.
2200
+ */
2201
+ static inline void skb_gro_incr_csum_unnecessary (struct sk_buff * skb )
2202
+ {
2203
+ if (skb -> ip_summed == CHECKSUM_UNNECESSARY ) {
2204
+ if (NAPI_GRO_CB (skb )-> encapsulation )
2205
+ skb -> encapsulation = 1 ;
2206
+ } else if (skb -> ip_summed != CHECKSUM_PARTIAL ) {
2207
+ skb -> ip_summed = CHECKSUM_UNNECESSARY ;
2208
+ skb -> encapsulation = 0 ;
2209
+ }
2210
+ }
2211
+
2212
+ #define __skb_gro_checksum_validate (skb , proto , zero_okay , check , \
2213
+ compute_pseudo ) \
2214
+ ({ \
2215
+ __sum16 __ret = 0; \
2216
+ if (__skb_gro_checksum_validate_needed(skb, zero_okay, check)) \
2217
+ __ret = __skb_gro_checksum_validate_complete(skb, \
2218
+ compute_pseudo(skb, proto)); \
2219
+ if (!__ret) \
2220
+ skb_gro_incr_csum_unnecessary(skb); \
2221
+ __ret; \
2222
+ })
2223
+
2224
+ #define skb_gro_checksum_validate (skb , proto , compute_pseudo ) \
2225
+ __skb_gro_checksum_validate(skb, proto, false, 0, compute_pseudo)
2226
+
2227
+ #define skb_gro_checksum_validate_zero_check (skb , proto , check , \
2228
+ compute_pseudo ) \
2229
+ __skb_gro_checksum_validate(skb, proto, true, check, compute_pseudo)
2230
+
2231
+ #define skb_gro_checksum_simple_validate (skb ) \
2232
+ __skb_gro_checksum_validate(skb, 0, false, 0, null_compute_pseudo)
2233
+
2162
2234
static inline int dev_hard_header (struct sk_buff * skb , struct net_device * dev ,
2163
2235
unsigned short type ,
2164
2236
const void * daddr , const void * saddr ,
0 commit comments