aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/netdevice.h
diff options
context:
space:
mode:
authorTom Herbert <therbert@google.com>2014-08-22 16:33:47 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-24 21:09:23 -0400
commit573e8fca255a27e3573b51f9b183d62641c47a3d (patch)
tree037fa48ffcd2b80e9b861904370ae64a6cba4224 /include/linux/netdevice.h
parent8fc54f68919298ff9689d980efb495707ef43f30 (diff)
net: skb_gro_checksum_* functions
Add skb_gro_checksum_validate, skb_gro_checksum_validate_zero_check, and skb_gro_checksum_simple_validate, and __skb_gro_checksum_complete. These are the cognates of the normal checksum functions but are used in the gro_receive path and operate on GRO related fields in sk_buffs. Signed-off-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/netdevice.h')
-rw-r--r--include/linux/netdevice.h76
1 files changed, 74 insertions, 2 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7e2b0b8b5cd7..eb73444e1bd0 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1883,7 +1883,13 @@ struct napi_gro_cb {
1883 u16 proto; 1883 u16 proto;
1884 1884
1885 /* Used in udp_gro_receive */ 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 /* used to support CHECKSUM_COMPLETE for tunneling protocols */ 1894 /* used to support CHECKSUM_COMPLETE for tunneling protocols */
1889 __wsum csum; 1895 __wsum csum;
@@ -2154,11 +2160,77 @@ static inline void *skb_gro_network_header(struct sk_buff *skb)
2154static inline void skb_gro_postpull_rcsum(struct sk_buff *skb, 2160static inline void skb_gro_postpull_rcsum(struct sk_buff *skb,
2155 const void *start, unsigned int len) 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 NAPI_GRO_CB(skb)->csum = csum_sub(NAPI_GRO_CB(skb)->csum, 2164 NAPI_GRO_CB(skb)->csum = csum_sub(NAPI_GRO_CB(skb)->csum,
2159 csum_partial(start, len, 0)); 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
2175static 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
2185static 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 */
2201static 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
2162static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, 2234static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
2163 unsigned short type, 2235 unsigned short type,
2164 const void *daddr, const void *saddr, 2236 const void *daddr, const void *saddr,