aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/mod_devicetable.h4
-rw-r--r--include/linux/netdevice.h62
-rw-r--r--include/linux/skbuff.h32
-rw-r--r--include/net/checksum.h5
-rw-r--r--include/net/vxlan.h4
-rw-r--r--include/uapi/linux/fou.h1
-rw-r--r--include/uapi/linux/if_link.h1
7 files changed, 88 insertions, 21 deletions
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 2e75ab00dbf2..e530533b94be 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -364,8 +364,6 @@ struct ssb_device_id {
364} __attribute__((packed, aligned(2))); 364} __attribute__((packed, aligned(2)));
365#define SSB_DEVICE(_vendor, _coreid, _revision) \ 365#define SSB_DEVICE(_vendor, _coreid, _revision) \
366 { .vendor = _vendor, .coreid = _coreid, .revision = _revision, } 366 { .vendor = _vendor, .coreid = _coreid, .revision = _revision, }
367#define SSB_DEVTABLE_END \
368 { 0, },
369 367
370#define SSB_ANY_VENDOR 0xFFFF 368#define SSB_ANY_VENDOR 0xFFFF
371#define SSB_ANY_ID 0xFFFF 369#define SSB_ANY_ID 0xFFFF
@@ -380,8 +378,6 @@ struct bcma_device_id {
380} __attribute__((packed,aligned(2))); 378} __attribute__((packed,aligned(2)));
381#define BCMA_CORE(_manuf, _id, _rev, _class) \ 379#define BCMA_CORE(_manuf, _id, _rev, _class) \
382 { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, } 380 { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, }
383#define BCMA_CORETABLE_END \
384 { 0, },
385 381
386#define BCMA_ANY_MANUF 0xFFFF 382#define BCMA_ANY_MANUF 0xFFFF
387#define BCMA_ANY_ID 0xFFFF 383#define BCMA_ANY_ID 0xFFFF
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d115256ed5a2..5897b4ea5a3f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1923,13 +1923,8 @@ struct napi_gro_cb {
1923 /* Number of segments aggregated. */ 1923 /* Number of segments aggregated. */
1924 u16 count; 1924 u16 count;
1925 1925
1926 /* This is non-zero if the packet may be of the same flow. */ 1926 /* Start offset for remote checksum offload */
1927 u8 same_flow; 1927 u16 gro_remcsum_start;
1928
1929 /* Free the skb? */
1930 u8 free;
1931#define NAPI_GRO_FREE 1
1932#define NAPI_GRO_FREE_STOLEN_HEAD 2
1933 1928
1934 /* jiffies when first packet was created/queued */ 1929 /* jiffies when first packet was created/queued */
1935 unsigned long age; 1930 unsigned long age;
@@ -1937,6 +1932,9 @@ struct napi_gro_cb {
1937 /* Used in ipv6_gro_receive() and foo-over-udp */ 1932 /* Used in ipv6_gro_receive() and foo-over-udp */
1938 u16 proto; 1933 u16 proto;
1939 1934
1935 /* This is non-zero if the packet may be of the same flow. */
1936 u8 same_flow:1;
1937
1940 /* Used in udp_gro_receive */ 1938 /* Used in udp_gro_receive */
1941 u8 udp_mark:1; 1939 u8 udp_mark:1;
1942 1940
@@ -1946,9 +1944,16 @@ struct napi_gro_cb {
1946 /* Number of checksums via CHECKSUM_UNNECESSARY */ 1944 /* Number of checksums via CHECKSUM_UNNECESSARY */
1947 u8 csum_cnt:3; 1945 u8 csum_cnt:3;
1948 1946
1947 /* Free the skb? */
1948 u8 free:2;
1949#define NAPI_GRO_FREE 1
1950#define NAPI_GRO_FREE_STOLEN_HEAD 2
1951
1949 /* Used in foo-over-udp, set in udp[46]_gro_receive */ 1952 /* Used in foo-over-udp, set in udp[46]_gro_receive */
1950 u8 is_ipv6:1; 1953 u8 is_ipv6:1;
1951 1954
1955 /* 7 bit hole */
1956
1952 /* used to support CHECKSUM_COMPLETE for tunneling protocols */ 1957 /* used to support CHECKSUM_COMPLETE for tunneling protocols */
1953 __wsum csum; 1958 __wsum csum;
1954 1959
@@ -2242,11 +2247,20 @@ static inline void skb_gro_postpull_rcsum(struct sk_buff *skb,
2242 2247
2243__sum16 __skb_gro_checksum_complete(struct sk_buff *skb); 2248__sum16 __skb_gro_checksum_complete(struct sk_buff *skb);
2244 2249
2250static inline bool skb_at_gro_remcsum_start(struct sk_buff *skb)
2251{
2252 return (NAPI_GRO_CB(skb)->gro_remcsum_start - skb_headroom(skb) ==
2253 skb_gro_offset(skb));
2254}
2255
2245static inline bool __skb_gro_checksum_validate_needed(struct sk_buff *skb, 2256static inline bool __skb_gro_checksum_validate_needed(struct sk_buff *skb,
2246 bool zero_okay, 2257 bool zero_okay,
2247 __sum16 check) 2258 __sum16 check)
2248{ 2259{
2249 return (skb->ip_summed != CHECKSUM_PARTIAL && 2260 return ((skb->ip_summed != CHECKSUM_PARTIAL ||
2261 skb_checksum_start_offset(skb) <
2262 skb_gro_offset(skb)) &&
2263 !skb_at_gro_remcsum_start(skb) &&
2250 NAPI_GRO_CB(skb)->csum_cnt == 0 && 2264 NAPI_GRO_CB(skb)->csum_cnt == 0 &&
2251 (!zero_okay || check)); 2265 (!zero_okay || check));
2252} 2266}
@@ -2321,20 +2335,48 @@ do { \
2321 compute_pseudo(skb, proto)); \ 2335 compute_pseudo(skb, proto)); \
2322} while (0) 2336} while (0)
2323 2337
2338struct gro_remcsum {
2339 int offset;
2340 __wsum delta;
2341};
2342
2343static inline void skb_gro_remcsum_init(struct gro_remcsum *grc)
2344{
2345 grc->delta = 0;
2346}
2347
2324static inline void skb_gro_remcsum_process(struct sk_buff *skb, void *ptr, 2348static inline void skb_gro_remcsum_process(struct sk_buff *skb, void *ptr,
2325 int start, int offset) 2349 int start, int offset,
2350 struct gro_remcsum *grc,
2351 bool nopartial)
2326{ 2352{
2327 __wsum delta; 2353 __wsum delta;
2328 2354
2329 BUG_ON(!NAPI_GRO_CB(skb)->csum_valid); 2355 BUG_ON(!NAPI_GRO_CB(skb)->csum_valid);
2330 2356
2357 if (!nopartial) {
2358 NAPI_GRO_CB(skb)->gro_remcsum_start =
2359 ((unsigned char *)ptr + start) - skb->head;
2360 return;
2361 }
2362
2331 delta = remcsum_adjust(ptr, NAPI_GRO_CB(skb)->csum, start, offset); 2363 delta = remcsum_adjust(ptr, NAPI_GRO_CB(skb)->csum, start, offset);
2332 2364
2333 /* Adjust skb->csum since we changed the packet */ 2365 /* Adjust skb->csum since we changed the packet */
2334 skb->csum = csum_add(skb->csum, delta);
2335 NAPI_GRO_CB(skb)->csum = csum_add(NAPI_GRO_CB(skb)->csum, delta); 2366 NAPI_GRO_CB(skb)->csum = csum_add(NAPI_GRO_CB(skb)->csum, delta);
2367
2368 grc->offset = (ptr + offset) - (void *)skb->head;
2369 grc->delta = delta;
2336} 2370}
2337 2371
2372static inline void skb_gro_remcsum_cleanup(struct sk_buff *skb,
2373 struct gro_remcsum *grc)
2374{
2375 if (!grc->delta)
2376 return;
2377
2378 remcsum_unadjust((__sum16 *)(skb->head + grc->offset), grc->delta);
2379}
2338 2380
2339static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, 2381static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
2340 unsigned short type, 2382 unsigned short type,
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1bb36edb66b9..30007afe70b3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -83,11 +83,15 @@
83 * 83 *
84 * CHECKSUM_PARTIAL: 84 * CHECKSUM_PARTIAL:
85 * 85 *
86 * This is identical to the case for output below. This may occur on a packet 86 * A checksum is set up to be offloaded to a device as described in the
87 * output description for CHECKSUM_PARTIAL. This may occur on a packet
87 * received directly from another Linux OS, e.g., a virtualized Linux kernel 88 * received directly from another Linux OS, e.g., a virtualized Linux kernel
88 * on the same host. The packet can be treated in the same way as 89 * on the same host, or it may be set in the input path in GRO or remote
89 * CHECKSUM_UNNECESSARY, except that on output (i.e., forwarding) the 90 * checksum offload. For the purposes of checksum verification, the checksum
90 * checksum must be filled in by the OS or the hardware. 91 * referred to by skb->csum_start + skb->csum_offset and any preceding
92 * checksums in the packet are considered verified. Any checksums in the
93 * packet that are after the checksum being offloaded are not considered to
94 * be verified.
91 * 95 *
92 * B. Checksumming on output. 96 * B. Checksumming on output.
93 * 97 *
@@ -2915,7 +2919,10 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb);
2915 2919
2916static inline int skb_csum_unnecessary(const struct sk_buff *skb) 2920static inline int skb_csum_unnecessary(const struct sk_buff *skb)
2917{ 2921{
2918 return ((skb->ip_summed & CHECKSUM_UNNECESSARY) || skb->csum_valid); 2922 return ((skb->ip_summed == CHECKSUM_UNNECESSARY) ||
2923 skb->csum_valid ||
2924 (skb->ip_summed == CHECKSUM_PARTIAL &&
2925 skb_checksum_start_offset(skb) >= 0));
2919} 2926}
2920 2927
2921/** 2928/**
@@ -3097,16 +3104,29 @@ do { \
3097 compute_pseudo(skb, proto)); \ 3104 compute_pseudo(skb, proto)); \
3098} while (0) 3105} while (0)
3099 3106
3107static inline void skb_remcsum_adjust_partial(struct sk_buff *skb, void *ptr,
3108 u16 start, u16 offset)
3109{
3110 skb->ip_summed = CHECKSUM_PARTIAL;
3111 skb->csum_start = ((unsigned char *)ptr + start) - skb->head;
3112 skb->csum_offset = offset - start;
3113}
3114
3100/* Update skbuf and packet to reflect the remote checksum offload operation. 3115/* Update skbuf and packet to reflect the remote checksum offload operation.
3101 * When called, ptr indicates the starting point for skb->csum when 3116 * When called, ptr indicates the starting point for skb->csum when
3102 * ip_summed is CHECKSUM_COMPLETE. If we need create checksum complete 3117 * ip_summed is CHECKSUM_COMPLETE. If we need create checksum complete
3103 * here, skb_postpull_rcsum is done so skb->csum start is ptr. 3118 * here, skb_postpull_rcsum is done so skb->csum start is ptr.
3104 */ 3119 */
3105static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr, 3120static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr,
3106 int start, int offset) 3121 int start, int offset, bool nopartial)
3107{ 3122{
3108 __wsum delta; 3123 __wsum delta;
3109 3124
3125 if (!nopartial) {
3126 skb_remcsum_adjust_partial(skb, ptr, start, offset);
3127 return;
3128 }
3129
3110 if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) { 3130 if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
3111 __skb_checksum_complete(skb); 3131 __skb_checksum_complete(skb);
3112 skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data); 3132 skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data);
diff --git a/include/net/checksum.h b/include/net/checksum.h
index e339a9513e29..0a55ac715077 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -167,4 +167,9 @@ static inline __wsum remcsum_adjust(void *ptr, __wsum csum,
167 return delta; 167 return delta;
168} 168}
169 169
170static inline void remcsum_unadjust(__sum16 *psum, __wsum delta)
171{
172 *psum = csum_fold(csum_sub(delta, *psum));
173}
174
170#endif 175#endif
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 2927d6244481..eabd3a038674 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -128,13 +128,15 @@ struct vxlan_sock {
128#define VXLAN_F_REMCSUM_TX 0x200 128#define VXLAN_F_REMCSUM_TX 0x200
129#define VXLAN_F_REMCSUM_RX 0x400 129#define VXLAN_F_REMCSUM_RX 0x400
130#define VXLAN_F_GBP 0x800 130#define VXLAN_F_GBP 0x800
131#define VXLAN_F_REMCSUM_NOPARTIAL 0x1000
131 132
132/* Flags that are used in the receive patch. These flags must match in 133/* Flags that are used in the receive patch. These flags must match in
133 * order for a socket to be shareable 134 * order for a socket to be shareable
134 */ 135 */
135#define VXLAN_F_RCV_FLAGS (VXLAN_F_GBP | \ 136#define VXLAN_F_RCV_FLAGS (VXLAN_F_GBP | \
136 VXLAN_F_UDP_ZERO_CSUM6_RX | \ 137 VXLAN_F_UDP_ZERO_CSUM6_RX | \
137 VXLAN_F_REMCSUM_RX) 138 VXLAN_F_REMCSUM_RX | \
139 VXLAN_F_REMCSUM_NOPARTIAL)
138 140
139struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port, 141struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
140 vxlan_rcv_t *rcv, void *data, 142 vxlan_rcv_t *rcv, void *data,
diff --git a/include/uapi/linux/fou.h b/include/uapi/linux/fou.h
index 8df06894da23..c303588bb767 100644
--- a/include/uapi/linux/fou.h
+++ b/include/uapi/linux/fou.h
@@ -14,6 +14,7 @@ enum {
14 FOU_ATTR_AF, /* u8 */ 14 FOU_ATTR_AF, /* u8 */
15 FOU_ATTR_IPPROTO, /* u8 */ 15 FOU_ATTR_IPPROTO, /* u8 */
16 FOU_ATTR_TYPE, /* u8 */ 16 FOU_ATTR_TYPE, /* u8 */
17 FOU_ATTR_REMCSUM_NOPARTIAL, /* flag */
17 18
18 __FOU_ATTR_MAX, 19 __FOU_ATTR_MAX,
19}; 20};
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 0deee3eeddbf..dfd0bb22e554 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -374,6 +374,7 @@ enum {
374 IFLA_VXLAN_REMCSUM_TX, 374 IFLA_VXLAN_REMCSUM_TX,
375 IFLA_VXLAN_REMCSUM_RX, 375 IFLA_VXLAN_REMCSUM_RX,
376 IFLA_VXLAN_GBP, 376 IFLA_VXLAN_GBP,
377 IFLA_VXLAN_REMCSUM_NOPARTIAL,
377 __IFLA_VXLAN_MAX 378 __IFLA_VXLAN_MAX
378}; 379};
379#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) 380#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)