aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-04-20 21:57:26 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-20 21:57:26 -0400
commit91f5bd8437d39feecfee215e032f440b1faa25f8 (patch)
tree7b3ff2ea9fad06843c9334dff0adbff2fd0a5d59
parenta068833bbf0ede9203410f8fd186178c758ade9b (diff)
parent3dfb05340ec6676e6fc71a9ae87bbbe66d3c2998 (diff)
Merge branch 'ppp_csum_unset'
Tom Herbert says: ==================== net: Fix "hw csum failure" message flood for ppp tunnel This patch set addresses bug "Bug 95171 - "hw csum failure" message flood for ppp tunnel since upgrade to 3.16". The problem is that pppoe is being used over UDP with UDP checksusm enabled. On receive checksum conversion turns checksum-unnecessary in checksum- complete. The PPP receive functions do not properly pull the checksum over its headers, so that when an encapsulated checksums is considered the checksum-complete value is incorrect. This patch adds skb_checksum_complete_unset which can be called in the receive path in lieu of pulling checksum complete in layer. This is useful when the packet is being modified (e.g. decompressed) and the checksum-complete value is no longer relevant. In the ppp_receive_frame we call skb_checksum_complete_unset to toss out checksum-complete. This should eliminate the reported messages. Alternatively, we could add skb_postpull_rcsum and probably special case handling for VJ compression if maintaining the checksum-complete is needed (not clear to me this is worth the effort). I haven't tested this since setting up the failure scenario doesn't seem trivial to configure. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ppp/ppp_generic.c1
-rw-r--r--include/linux/skbuff.h12
2 files changed, 13 insertions, 0 deletions
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index af034dba9bd6..9d15566521a7 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1716,6 +1716,7 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
1716{ 1716{
1717 /* note: a 0-length skb is used as an error indication */ 1717 /* note: a 0-length skb is used as an error indication */
1718 if (skb->len > 0) { 1718 if (skb->len > 0) {
1719 skb_checksum_complete_unset(skb);
1719#ifdef CONFIG_PPP_MULTILINK 1720#ifdef CONFIG_PPP_MULTILINK
1720 /* XXX do channel-level decompression here */ 1721 /* XXX do channel-level decompression here */
1721 if (PPP_PROTO(skb) == PPP_MP) 1722 if (PPP_PROTO(skb) == PPP_MP)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 0991259643d6..06793b598f44 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3016,6 +3016,18 @@ static inline bool __skb_checksum_validate_needed(struct sk_buff *skb,
3016 */ 3016 */
3017#define CHECKSUM_BREAK 76 3017#define CHECKSUM_BREAK 76
3018 3018
3019/* Unset checksum-complete
3020 *
3021 * Unset checksum complete can be done when packet is being modified
3022 * (uncompressed for instance) and checksum-complete value is
3023 * invalidated.
3024 */
3025static inline void skb_checksum_complete_unset(struct sk_buff *skb)
3026{
3027 if (skb->ip_summed == CHECKSUM_COMPLETE)
3028 skb->ip_summed = CHECKSUM_NONE;
3029}
3030
3019/* Validate (init) checksum based on checksum complete. 3031/* Validate (init) checksum based on checksum complete.
3020 * 3032 *
3021 * Return values: 3033 * Return values: