diff options
| author | David S. Miller <davem@davemloft.net> | 2014-06-05 01:52:31 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-06-05 01:52:31 -0400 |
| commit | 00d115fc758c6ef331553a9c6aa34b7bd79116a5 (patch) | |
| tree | ca8567d5204c6b891dcf5d3e012ceb4a4f027c09 /include/linux | |
| parent | 6579867c8b02606e101a6c511c2511b027ed3f4a (diff) | |
| parent | 359a0ea9875ef4f32c8425bbe1ae348e1fd2ed2a (diff) | |
Merge branch 'inet_csums'
Tom Herbert says:
====================
net: Support checksum in UDP
This patch series adds support for using checksums in UDP tunnels. With
this it is possible that two or more checksums may be set within the
same packet and we would like to do that efficiently.
This series also creates some new helper functions to be used by various
tunnel protocol implementations.
v2: Fixed indentation in tcp_v6_send_check arguments.
v3: Move udp_set_csum and udp6_set_csum to be not inlined
Also have this functions call with a nocheck boolean argument
instead of passing a sock structure.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/netdev_features.h | 3 | ||||
| -rw-r--r-- | include/linux/skbuff.h | 30 |
2 files changed, 32 insertions, 1 deletions
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index c26d0ec2ef3a..e5a589435e2b 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h | |||
| @@ -42,9 +42,11 @@ enum { | |||
| 42 | NETIF_F_TSO6_BIT, /* ... TCPv6 segmentation */ | 42 | NETIF_F_TSO6_BIT, /* ... TCPv6 segmentation */ |
| 43 | NETIF_F_FSO_BIT, /* ... FCoE segmentation */ | 43 | NETIF_F_FSO_BIT, /* ... FCoE segmentation */ |
| 44 | NETIF_F_GSO_GRE_BIT, /* ... GRE with TSO */ | 44 | NETIF_F_GSO_GRE_BIT, /* ... GRE with TSO */ |
| 45 | NETIF_F_GSO_GRE_CSUM_BIT, /* ... GRE with csum with TSO */ | ||
| 45 | NETIF_F_GSO_IPIP_BIT, /* ... IPIP tunnel with TSO */ | 46 | NETIF_F_GSO_IPIP_BIT, /* ... IPIP tunnel with TSO */ |
| 46 | NETIF_F_GSO_SIT_BIT, /* ... SIT tunnel with TSO */ | 47 | NETIF_F_GSO_SIT_BIT, /* ... SIT tunnel with TSO */ |
| 47 | NETIF_F_GSO_UDP_TUNNEL_BIT, /* ... UDP TUNNEL with TSO */ | 48 | NETIF_F_GSO_UDP_TUNNEL_BIT, /* ... UDP TUNNEL with TSO */ |
| 49 | NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,/* ... UDP TUNNEL with TSO & CSUM */ | ||
| 48 | NETIF_F_GSO_MPLS_BIT, /* ... MPLS segmentation */ | 50 | NETIF_F_GSO_MPLS_BIT, /* ... MPLS segmentation */ |
| 49 | /**/NETIF_F_GSO_LAST = /* last bit, see GSO_MASK */ | 51 | /**/NETIF_F_GSO_LAST = /* last bit, see GSO_MASK */ |
| 50 | NETIF_F_GSO_MPLS_BIT, | 52 | NETIF_F_GSO_MPLS_BIT, |
| @@ -111,6 +113,7 @@ enum { | |||
| 111 | #define NETIF_F_RXFCS __NETIF_F(RXFCS) | 113 | #define NETIF_F_RXFCS __NETIF_F(RXFCS) |
| 112 | #define NETIF_F_RXALL __NETIF_F(RXALL) | 114 | #define NETIF_F_RXALL __NETIF_F(RXALL) |
| 113 | #define NETIF_F_GSO_GRE __NETIF_F(GSO_GRE) | 115 | #define NETIF_F_GSO_GRE __NETIF_F(GSO_GRE) |
| 116 | #define NETIF_F_GSO_GRE_CSUM __NETIF_F(GSO_GRE_CSUM) | ||
| 114 | #define NETIF_F_GSO_IPIP __NETIF_F(GSO_IPIP) | 117 | #define NETIF_F_GSO_IPIP __NETIF_F(GSO_IPIP) |
| 115 | #define NETIF_F_GSO_SIT __NETIF_F(GSO_SIT) | 118 | #define NETIF_F_GSO_SIT __NETIF_F(GSO_SIT) |
| 116 | #define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL) | 119 | #define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL) |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 7a9beeb1c458..c705808bef9c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -345,6 +345,10 @@ enum { | |||
| 345 | SKB_GSO_UDP_TUNNEL = 1 << 9, | 345 | SKB_GSO_UDP_TUNNEL = 1 << 9, |
| 346 | 346 | ||
| 347 | SKB_GSO_MPLS = 1 << 10, | 347 | SKB_GSO_MPLS = 1 << 10, |
| 348 | |||
| 349 | SKB_GSO_UDP_TUNNEL_CSUM = 1 << 11, | ||
| 350 | |||
| 351 | SKB_GSO_GRE_CSUM = 1 << 12, | ||
| 348 | }; | 352 | }; |
| 349 | 353 | ||
| 350 | #if BITS_PER_LONG > 32 | 354 | #if BITS_PER_LONG > 32 |
| @@ -567,7 +571,8 @@ struct sk_buff { | |||
| 567 | * headers if needed | 571 | * headers if needed |
| 568 | */ | 572 | */ |
| 569 | __u8 encapsulation:1; | 573 | __u8 encapsulation:1; |
| 570 | /* 6/8 bit hole (depending on ndisc_nodetype presence) */ | 574 | __u8 encap_hdr_csum:1; |
| 575 | /* 5/7 bit hole (depending on ndisc_nodetype presence) */ | ||
| 571 | kmemcheck_bitfield_end(flags2); | 576 | kmemcheck_bitfield_end(flags2); |
| 572 | 577 | ||
| 573 | #if defined CONFIG_NET_DMA || defined CONFIG_NET_RX_BUSY_POLL | 578 | #if defined CONFIG_NET_DMA || defined CONFIG_NET_RX_BUSY_POLL |
| @@ -2988,6 +2993,7 @@ static inline struct sec_path *skb_sec_path(struct sk_buff *skb) | |||
| 2988 | struct skb_gso_cb { | 2993 | struct skb_gso_cb { |
| 2989 | int mac_offset; | 2994 | int mac_offset; |
| 2990 | int encap_level; | 2995 | int encap_level; |
| 2996 | __u16 csum_start; | ||
| 2991 | }; | 2997 | }; |
| 2992 | #define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb) | 2998 | #define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb) |
| 2993 | 2999 | ||
| @@ -3012,6 +3018,28 @@ static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra) | |||
| 3012 | return 0; | 3018 | return 0; |
| 3013 | } | 3019 | } |
| 3014 | 3020 | ||
| 3021 | /* Compute the checksum for a gso segment. First compute the checksum value | ||
| 3022 | * from the start of transport header to SKB_GSO_CB(skb)->csum_start, and | ||
| 3023 | * then add in skb->csum (checksum from csum_start to end of packet). | ||
| 3024 | * skb->csum and csum_start are then updated to reflect the checksum of the | ||
| 3025 | * resultant packet starting from the transport header-- the resultant checksum | ||
| 3026 | * is in the res argument (i.e. normally zero or ~ of checksum of a pseudo | ||
| 3027 | * header. | ||
| 3028 | */ | ||
| 3029 | static inline __sum16 gso_make_checksum(struct sk_buff *skb, __wsum res) | ||
| 3030 | { | ||
| 3031 | int plen = SKB_GSO_CB(skb)->csum_start - skb_headroom(skb) - | ||
| 3032 | skb_transport_offset(skb); | ||
| 3033 | __u16 csum; | ||
| 3034 | |||
| 3035 | csum = csum_fold(csum_partial(skb_transport_header(skb), | ||
| 3036 | plen, skb->csum)); | ||
| 3037 | skb->csum = res; | ||
| 3038 | SKB_GSO_CB(skb)->csum_start -= plen; | ||
| 3039 | |||
| 3040 | return csum; | ||
| 3041 | } | ||
| 3042 | |||
| 3015 | static inline bool skb_is_gso(const struct sk_buff *skb) | 3043 | static inline bool skb_is_gso(const struct sk_buff *skb) |
| 3016 | { | 3044 | { |
| 3017 | return skb_shinfo(skb)->gso_size; | 3045 | return skb_shinfo(skb)->gso_size; |
