diff options
author | Tom Herbert <therbert@google.com> | 2015-02-10 16:30:27 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-11 15:12:09 -0800 |
commit | 26c4f7da3e413da697a7beb22ad496390eda7da0 (patch) | |
tree | 55182c7a68fc4129369ffce2ac30a897cc3d55a1 /include/net | |
parent | 13101602c4a9f653d59af9469040797bc5b361ca (diff) |
net: Fix remcsum in GRO path to not change packet
Remote checksum offload processing is currently the same for both
the GRO and non-GRO path. When the remote checksum offload option
is encountered, the checksum field referred to is modified in
the packet. So in the GRO case, the packet is modified in the
GRO path and then the operation is skipped when the packet goes
through the normal path based on skb->remcsum_offload. There is
a problem in that the packet may be modified in the GRO path, but
then forwarded off host still containing the remote checksum option.
A remote host will again perform RCO but now the checksum verification
will fail since GRO RCO already modified the checksum.
To fix this, we ensure that GRO restores a packet to it's original
state before returning. In this model, when GRO processes a remote
checksum option it still changes the checksum per the algorithm
but on return from lower layer processing the checksum is restored
to its original value.
In this patch we add define gro_remcsum structure which is passed
to skb_gro_remcsum_process to save offset and delta for the checksum
being changed. After lower layer processing, skb_gro_remcsum_cleanup
is called to restore the checksum before returning from GRO.
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/checksum.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/include/net/checksum.h b/include/net/checksum.h index e339a9513e2..0a55ac71507 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -167,4 +167,9 @@ static inline __wsum remcsum_adjust(void *ptr, __wsum csum, return delta; } +static inline void remcsum_unadjust(__sum16 *psum, __wsum delta) +{ + *psum = csum_fold(csum_sub(delta, *psum)); +} + #endif |