Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 1 | /* SCTP kernel reference Implementation |
| 2 | * Copyright (c) 1999-2001 Motorola, Inc. |
| 3 | * Copyright (c) 2001-2003 International Business Machines, Corp. |
| 4 | * |
| 5 | * This file is part of the SCTP kernel reference Implementation |
| 6 | * |
| 7 | * SCTP Checksum functions |
| 8 | * |
| 9 | * The SCTP reference implementation is free software; |
| 10 | * you can redistribute it and/or modify it under the terms of |
| 11 | * the GNU General Public License as published by |
| 12 | * the Free Software Foundation; either version 2, or (at your option) |
| 13 | * any later version. |
| 14 | * |
| 15 | * The SCTP reference implementation is distributed in the hope that it |
| 16 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied |
| 17 | * ************************ |
| 18 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| 19 | * See the GNU General Public License for more details. |
| 20 | * |
| 21 | * You should have received a copy of the GNU General Public License |
Jeff Kirsher | a6227e2 | 2013-12-06 09:13:40 -0800 | [diff] [blame] | 22 | * along with GNU CC; see the file COPYING. If not, see |
| 23 | * <http://www.gnu.org/licenses/>. |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 24 | * |
| 25 | * Please send any bug reports or fixes you make to the |
| 26 | * email address(es): |
Daniel Borkmann | 91705c6 | 2013-07-23 14:51:47 +0200 | [diff] [blame] | 27 | * lksctp developers <linux-sctp@vger.kernel.org> |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 28 | * |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 29 | * Written or modified by: |
| 30 | * Dinakaran Joseph |
| 31 | * Jon Grimm <jgrimm@us.ibm.com> |
| 32 | * Sridhar Samudrala <sri@us.ibm.com> |
| 33 | * |
| 34 | * Rewritten to use libcrc32c by: |
| 35 | * Vlad Yasevich <vladislav.yasevich@hp.com> |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 36 | */ |
| 37 | |
Daniel Borkmann | a05b101 | 2013-07-01 18:10:36 +0200 | [diff] [blame] | 38 | #ifndef __sctp_checksum_h__ |
| 39 | #define __sctp_checksum_h__ |
| 40 | |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 41 | #include <linux/types.h> |
| 42 | #include <net/sctp/sctp.h> |
| 43 | #include <linux/crc32c.h> |
Daniel Borkmann | e6d8b64 | 2013-10-30 11:50:52 +0100 | [diff] [blame] | 44 | #include <linux/crc32.h> |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 45 | |
Daniel Borkmann | e6d8b64 | 2013-10-30 11:50:52 +0100 | [diff] [blame] | 46 | static inline __wsum sctp_csum_update(const void *buff, int len, __wsum sum) |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 47 | { |
Daniel Borkmann | e6d8b64 | 2013-10-30 11:50:52 +0100 | [diff] [blame] | 48 | /* This uses the crypto implementation of crc32c, which is either |
| 49 | * implemented w/ hardware support or resolves to __crc32c_le(). |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 50 | */ |
Daniel Borkmann | e6d8b64 | 2013-10-30 11:50:52 +0100 | [diff] [blame] | 51 | return crc32c(sum, buff, len); |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 52 | } |
| 53 | |
Daniel Borkmann | e6d8b64 | 2013-10-30 11:50:52 +0100 | [diff] [blame] | 54 | static inline __wsum sctp_csum_combine(__wsum csum, __wsum csum2, |
| 55 | int offset, int len) |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 56 | { |
Daniel Borkmann | e6d8b64 | 2013-10-30 11:50:52 +0100 | [diff] [blame] | 57 | return __crc32c_le_combine(csum, csum2, len); |
Vlad Yasevich | 9ad0977 | 2007-12-16 14:06:41 -0800 | [diff] [blame] | 58 | } |
| 59 | |
Joe Stringer | 024ec3d | 2013-07-25 10:52:05 +0900 | [diff] [blame] | 60 | static inline __le32 sctp_compute_cksum(const struct sk_buff *skb, |
| 61 | unsigned int offset) |
| 62 | { |
Daniel Borkmann | e6d8b64 | 2013-10-30 11:50:52 +0100 | [diff] [blame] | 63 | struct sctphdr *sh = sctp_hdr(skb); |
| 64 | __le32 ret, old = sh->checksum; |
| 65 | const struct skb_checksum_ops ops = { |
| 66 | .update = sctp_csum_update, |
| 67 | .combine = sctp_csum_combine, |
| 68 | }; |
Joe Stringer | 024ec3d | 2013-07-25 10:52:05 +0900 | [diff] [blame] | 69 | |
Daniel Borkmann | e6d8b64 | 2013-10-30 11:50:52 +0100 | [diff] [blame] | 70 | sh->checksum = 0; |
| 71 | ret = cpu_to_le32(~__skb_checksum(skb, offset, skb->len - offset, |
| 72 | ~(__u32)0, &ops)); |
| 73 | sh->checksum = old; |
Joe Stringer | 024ec3d | 2013-07-25 10:52:05 +0900 | [diff] [blame] | 74 | |
Daniel Borkmann | e6d8b64 | 2013-10-30 11:50:52 +0100 | [diff] [blame] | 75 | return ret; |
Joe Stringer | 024ec3d | 2013-07-25 10:52:05 +0900 | [diff] [blame] | 76 | } |
| 77 | |
Daniel Borkmann | a05b101 | 2013-07-01 18:10:36 +0200 | [diff] [blame] | 78 | #endif /* __sctp_checksum_h__ */ |