diff options
author | Sven Eckelmann <sven@narfation.org> | 2012-10-17 21:10:39 +0200 |
---|---|---|
committer | Antonio Quartulli <ordex@autistici.org> | 2012-11-21 12:35:41 +0100 |
commit | 95a066d82c422c812c10bfd4de01225b1714fa45 (patch) | |
tree | e040f780728ea700af9d2df22e28b9188f586071 /net/batman-adv/main.c | |
parent | 60d8cce7c53f188d99cb01a0a013cf3544f35e29 (diff) | |
download | lwn-95a066d82c422c812c10bfd4de01225b1714fa45.tar.gz lwn-95a066d82c422c812c10bfd4de01225b1714fa45.zip |
batman-adv: Add function to calculate crc32c for the skb payload
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Diffstat (limited to 'net/batman-adv/main.c')
-rw-r--r-- | net/batman-adv/main.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index dc33a0c484a4..f65a222b7b83 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -17,6 +17,8 @@ * 02110-1301, USA */ +#include <linux/crc32c.h> +#include <linux/highmem.h> #include "main.h" #include "sysfs.h" #include "debugfs.h" @@ -420,6 +422,38 @@ int batadv_algo_seq_print_text(struct seq_file *seq, void *offset) return 0; } +/** + * batadv_skb_crc32 - calculate CRC32 of the whole packet and skip bytes in + * the header + * @skb: skb pointing to fragmented socket buffers + * @payload_ptr: Pointer to position inside the head buffer of the skb + * marking the start of the data to be CRC'ed + * + * payload_ptr must always point to an address in the skb head buffer and not to + * a fragment. + */ +__be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr) +{ + u32 crc = 0; + unsigned int from; + unsigned int to = skb->len; + struct skb_seq_state st; + const u8 *data; + unsigned int len; + unsigned int consumed = 0; + + from = (unsigned int)(payload_ptr - skb->data); + + skb_prepare_seq_read(skb, from, to, &st); + while ((len = skb_seq_read(consumed, &data, &st)) != 0) { + crc = crc32c(crc, data, len); + consumed += len; + } + skb_abort_seq_read(&st); + + return htonl(crc); +} + static int batadv_param_set_ra(const char *val, const struct kernel_param *kp) { struct batadv_algo_ops *bat_algo_ops; |