Commit 91f5bd84 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents a068833b 3dfb0534
...@@ -1716,6 +1716,7 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) ...@@ -1716,6 +1716,7 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
{ {
/* note: a 0-length skb is used as an error indication */ /* note: a 0-length skb is used as an error indication */
if (skb->len > 0) { if (skb->len > 0) {
skb_checksum_complete_unset(skb);
#ifdef CONFIG_PPP_MULTILINK #ifdef CONFIG_PPP_MULTILINK
/* XXX do channel-level decompression here */ /* XXX do channel-level decompression here */
if (PPP_PROTO(skb) == PPP_MP) if (PPP_PROTO(skb) == PPP_MP)
......
...@@ -3016,6 +3016,18 @@ static inline bool __skb_checksum_validate_needed(struct sk_buff *skb, ...@@ -3016,6 +3016,18 @@ static inline bool __skb_checksum_validate_needed(struct sk_buff *skb,
*/ */
#define CHECKSUM_BREAK 76 #define CHECKSUM_BREAK 76
/* Unset checksum-complete
*
* Unset checksum complete can be done when packet is being modified
* (uncompressed for instance) and checksum-complete value is
* invalidated.
*/
static inline void skb_checksum_complete_unset(struct sk_buff *skb)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->ip_summed = CHECKSUM_NONE;
}
/* Validate (init) checksum based on checksum complete. /* Validate (init) checksum based on checksum complete.
* *
* Return values: * Return values:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment