diff options
Diffstat (limited to 'net/batman-adv/bridge_loop_avoidance.c')
-rw-r--r-- | net/batman-adv/bridge_loop_avoidance.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 747755647c6a..b992ba12aa24 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -12,6 +12,7 @@ #include <linux/compiler.h> #include <linux/container_of.h> #include <linux/crc16.h> +#include <linux/crc32.h> #include <linux/err.h> #include <linux/errno.h> #include <linux/etherdevice.h> @@ -1585,6 +1586,39 @@ int batadv_bla_init(struct batadv_priv *bat_priv) } /** + * 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. + * + * Return: big endian crc32c of the checksummed data + */ +static __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr) +{ + unsigned int to = skb->len; + unsigned int consumed = 0; + struct skb_seq_state st; + unsigned int from; + unsigned int len; + const u8 *data; + u32 crc = 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; + } + + return htonl(crc); +} + +/** * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup. * @bat_priv: the bat priv with all the mesh interface information * @skb: contains the multicast packet to be checked |