* [B.A.T.M.A.N.] [RFC] batman-adv: Add function to calculate crc32c for the skb payload
@ 2012-10-17 15:59 Sven Eckelmann
2012-10-17 16:11 ` Martin Hundebøll
2012-10-17 17:18 ` [B.A.T.M.A.N.] [RFCv2] " Sven Eckelmann
0 siblings, 2 replies; 5+ messages in thread
From: Sven Eckelmann @ 2012-10-17 15:59 UTC (permalink / raw)
To: b.a.t.m.a.n
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
main.c | 34 ++++++++++++++++++++++++++++++++++
main.h | 1 +
2 files changed, 35 insertions(+)
diff --git a/main.c b/main.c
index 70797de..122c675 100644
--- a/main.c
+++ b/main.c
@@ -33,6 +33,7 @@
#include "vis.h"
#include "hash.h"
#include "bat_algo.h"
+#include <linux/crc32c.h>
/* List manipulations on hardif_list have to be rtnl_lock()'ed,
@@ -432,6 +433,39 @@ int batadv_compat_seq_print_text(struct seq_file *seq, void *offset)
return 0;
}
+/**
+ * batadv_crc32 - calculate CRC32 of the whole packet and skip bytes in 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 the point in the skb head buffer and not to
+ * a fragment.
+ */
+__be32 batadv_crc32(const struct sk_buff *skb, u8 *payload_ptr)
+{
+ u32 crc = 0;
+ struct sk_buff *iter;
+ size_t skip_len, read_len;
+ const skb_frag_t *f;
+ int i;
+
+ skip_len = payload_ptr - skb->data;
+ read_len = skb_headlen(skb) - skip_len;
+ if (read_len)
+ crc = crc32c(crc, payload_ptr, read_len);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ f = &skb_shinfo(skb)->frags[i];
+ crc = crc32c(crc, skb_frag_address(f), skb_frag_size(f));
+ }
+
+ skb_walk_frags(skb, iter)
+ crc = crc32c(crc, iter->data, skb_headlen(iter));
+
+ return htonl(crc);
+}
+
static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
{
struct batadv_algo_ops *bat_algo_ops;
diff --git a/main.h b/main.h
index 2dfcf8c..bb0a710 100644
--- a/main.h
+++ b/main.h
@@ -177,6 +177,7 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
int batadv_compat_seq_print_text(struct seq_file *seq, void *offset);
+__be32 batadv_crc32(const struct sk_buff *skb, u8 *payload_ptr);
/**
* enum batadv_dbg_level - available log levels
--
1.7.10.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [B.A.T.M.A.N.] [RFC] batman-adv: Add function to calculate crc32c for the skb payload
2012-10-17 15:59 [B.A.T.M.A.N.] [RFC] batman-adv: Add function to calculate crc32c for the skb payload Sven Eckelmann
@ 2012-10-17 16:11 ` Martin Hundebøll
2012-10-17 17:18 ` [B.A.T.M.A.N.] [RFCv2] " Sven Eckelmann
1 sibling, 0 replies; 5+ messages in thread
From: Martin Hundebøll @ 2012-10-17 16:11 UTC (permalink / raw)
To: b.a.t.m.a.n
On 2012-10-17 17:59, Sven Eckelmann wrote:
> +__be32 batadv_crc32(const struct sk_buff *skb, u8 *payload_ptr)
> +{
> + u32 crc = 0;
> + struct sk_buff *iter;
> + size_t skip_len, read_len;
> + const skb_frag_t *f;
> + int i;
> +
> + skip_len = payload_ptr - skb->data;
> + read_len = skb_headlen(skb) - skip_len;
> + if (read_len)
> + crc = crc32c(crc, payload_ptr, read_len);
> +
> + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
> + f = &skb_shinfo(skb)->frags[i];
> + crc = crc32c(crc, skb_frag_address(f), skb_frag_size(f));
> + }
> +
> + skb_walk_frags(skb, iter)
> + crc = crc32c(crc, iter->data, skb_headlen(iter));
> +
> + return htonl(crc);
> +}
I tested the crc'ing of non-linear skb buffers and can confirm that it
works as expected, so:
Tested-by: Martin Hundebøll <martin@hundeboll.net>
... at least for batadv_crc32() :)
--
Kind Regards
Martin Hundebøll
Frederiks Allé 99, 1.th
8000 Aarhus C
Denmark
+45 61 65 54 61
martin@hundeboll.net
^ permalink raw reply [flat|nested] 5+ messages in thread
* [B.A.T.M.A.N.] [RFCv2] batman-adv: Add function to calculate crc32c for the skb payload
2012-10-17 15:59 [B.A.T.M.A.N.] [RFC] batman-adv: Add function to calculate crc32c for the skb payload Sven Eckelmann
2012-10-17 16:11 ` Martin Hundebøll
@ 2012-10-17 17:18 ` Sven Eckelmann
2012-10-17 19:10 ` [B.A.T.M.A.N.] [RFCv3] " Sven Eckelmann
1 sibling, 1 reply; 5+ messages in thread
From: Sven Eckelmann @ 2012-10-17 17:18 UTC (permalink / raw)
To: b.a.t.m.a.n
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
v2:
- Added compat code for kernel like 2.6.39
- Use kmap_atomic to get the page
compat.h | 20 ++++++++++++++++++++
main.c | 38 ++++++++++++++++++++++++++++++++++++++
main.h | 1 +
3 files changed, 59 insertions(+)
diff --git a/compat.h b/compat.h
index 0caf43b..4e059e8 100644
--- a/compat.h
+++ b/compat.h
@@ -146,6 +146,26 @@ static inline void skb_reset_mac_len(struct sk_buff *skb)
#endif /* < KERNEL_VERSION(3, 0, 0) */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
+
+static inline struct page *skb_frag_page(const skb_frag_t *frag)
+{
+ return frag->page;
+}
+
+static inline void *skb_frag_address(const skb_frag_t *frag)
+{
+ return page_address(skb_frag_page(frag)) + frag->page_offset;
+}
+
+static inline unsigned int skb_frag_size(const skb_frag_t *frag)
+{
+ return frag->size;
+}
+
+#endif /* < KERNEL_VERSION(3, 2, 0) */
+
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
static inline void eth_hw_addr_random(struct net_device *dev)
diff --git a/main.c b/main.c
index 70797de..009c9b0 100644
--- a/main.c
+++ b/main.c
@@ -33,6 +33,8 @@
#include "vis.h"
#include "hash.h"
#include "bat_algo.h"
+#include <linux/crc32c.h>
+#include <linux/highmem.h>
/* List manipulations on hardif_list have to be rtnl_lock()'ed,
@@ -432,6 +434,42 @@ int batadv_compat_seq_print_text(struct seq_file *seq, void *offset)
return 0;
}
+/**
+ * batadv_crc32 - calculate CRC32 of the whole packet and skip bytes in 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 the point in the skb head buffer and not to
+ * a fragment.
+ */
+__be32 batadv_crc32(const struct sk_buff *skb, u8 *payload_ptr)
+{
+ u32 crc = 0;
+ struct sk_buff *iter;
+ size_t skip_len, read_len;
+ const skb_frag_t *f;
+ u8 *vaddr;
+ int i;
+
+ skip_len = payload_ptr - skb->data;
+ read_len = skb_headlen(skb) - skip_len;
+ if (read_len)
+ crc = crc32c(crc, payload_ptr, read_len);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ f = &skb_shinfo(skb)->frags[i];
+ vaddr = kmap_atomic(skb_frag_page(f));
+ crc = crc32c(crc, vaddr + f->page_offset, skb_frag_size(f));
+ kunmap_atomic(vaddr);
+ }
+
+ skb_walk_frags(skb, iter)
+ crc = crc32c(crc, iter->data, skb_headlen(iter));
+
+ return htonl(crc);
+}
+
static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
{
struct batadv_algo_ops *bat_algo_ops;
diff --git a/main.h b/main.h
index 2dfcf8c..bb0a710 100644
--- a/main.h
+++ b/main.h
@@ -177,6 +177,7 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
int batadv_compat_seq_print_text(struct seq_file *seq, void *offset);
+__be32 batadv_crc32(const struct sk_buff *skb, u8 *payload_ptr);
/**
* enum batadv_dbg_level - available log levels
--
1.7.10.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [B.A.T.M.A.N.] [RFCv3] batman-adv: Add function to calculate crc32c for the skb payload
2012-10-17 17:18 ` [B.A.T.M.A.N.] [RFCv2] " Sven Eckelmann
@ 2012-10-17 19:10 ` Sven Eckelmann
2012-10-17 19:57 ` Marek Lindner
0 siblings, 1 reply; 5+ messages in thread
From: Sven Eckelmann @ 2012-10-17 19:10 UTC (permalink / raw)
To: b.a.t.m.a.n
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
v3: Now with support for kernels till 2.6.29
compat.h | 34 ++++++++++++++++++++++++++++++++++
main.c | 38 ++++++++++++++++++++++++++++++++++++++
main.h | 1 +
3 files changed, 73 insertions(+)
diff --git a/compat.h b/compat.h
index 0caf43b..83befd1 100644
--- a/compat.h
+++ b/compat.h
@@ -37,6 +37,9 @@
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
+#define skb_walk_frags(skb, iter) \
+ for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next)
+
#define __compat__module_param_call(p1, p2, p3, p4, p5, p6, p7) \
__module_param_call(p1, p2, p3, p4, p5, p7)
@@ -78,6 +81,17 @@
#endif /* < KERNEL_VERSION(2, 6, 35) */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+
+#define kmap_atomic(p) kmap_atomic(p, KM_SKB_DATA_SOFTIRQ)
+
+#ifdef kunmap_atomic
+#undef kunmap_atomic
+#endif
+#define kunmap_atomic(x, arg...) do { pagefault_enable(); } while (0)
+
+#endif /* < KERNEL_VERSION(2, 6, 37) */
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
@@ -146,6 +160,26 @@ static inline void skb_reset_mac_len(struct sk_buff *skb)
#endif /* < KERNEL_VERSION(3, 0, 0) */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
+
+static inline struct page *skb_frag_page(const skb_frag_t *frag)
+{
+ return frag->page;
+}
+
+static inline void *skb_frag_address(const skb_frag_t *frag)
+{
+ return page_address(skb_frag_page(frag)) + frag->page_offset;
+}
+
+static inline unsigned int skb_frag_size(const skb_frag_t *frag)
+{
+ return frag->size;
+}
+
+#endif /* < KERNEL_VERSION(3, 2, 0) */
+
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
static inline void eth_hw_addr_random(struct net_device *dev)
diff --git a/main.c b/main.c
index 70797de..df5f7d6 100644
--- a/main.c
+++ b/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"
@@ -432,6 +434,42 @@ int batadv_compat_seq_print_text(struct seq_file *seq, void *offset)
return 0;
}
+/**
+ * batadv_crc32 - calculate CRC32 of the whole packet and skip bytes in 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 the point in the skb head buffer and not to
+ * a fragment.
+ */
+__be32 batadv_crc32(const struct sk_buff *skb, u8 *payload_ptr)
+{
+ u32 crc = 0;
+ struct sk_buff *iter;
+ size_t skip_len, read_len;
+ const skb_frag_t *f;
+ u8 *vaddr;
+ int i;
+
+ skip_len = payload_ptr - skb->data;
+ read_len = skb_headlen(skb) - skip_len;
+ if (read_len)
+ crc = crc32c(crc, payload_ptr, read_len);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ f = &skb_shinfo(skb)->frags[i];
+ vaddr = kmap_atomic(skb_frag_page(f));
+ crc = crc32c(crc, vaddr + f->page_offset, skb_frag_size(f));
+ kunmap_atomic(vaddr);
+ }
+
+ skb_walk_frags(skb, iter)
+ crc = crc32c(crc, iter->data, skb_headlen(iter));
+
+ return htonl(crc);
+}
+
static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
{
struct batadv_algo_ops *bat_algo_ops;
diff --git a/main.h b/main.h
index 2dfcf8c..bb0a710 100644
--- a/main.h
+++ b/main.h
@@ -177,6 +177,7 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
int batadv_compat_seq_print_text(struct seq_file *seq, void *offset);
+__be32 batadv_crc32(const struct sk_buff *skb, u8 *payload_ptr);
/**
* enum batadv_dbg_level - available log levels
--
1.7.10.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [B.A.T.M.A.N.] [RFCv3] batman-adv: Add function to calculate crc32c for the skb payload
2012-10-17 19:10 ` [B.A.T.M.A.N.] [RFCv3] " Sven Eckelmann
@ 2012-10-17 19:57 ` Marek Lindner
0 siblings, 0 replies; 5+ messages in thread
From: Marek Lindner @ 2012-10-17 19:57 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking
On Thursday, October 18, 2012 03:10:39 Sven Eckelmann wrote:
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> ---
> v3: Now with support for kernels till 2.6.29
>
> compat.h | 34 ++++++++++++++++++++++++++++++++++
> main.c | 38 ++++++++++++++++++++++++++++++++++++++
> main.h | 1 +
> 3 files changed, 73 insertions(+)
Applied in revision a7fe307.
Thanks,
Marek
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-10-17 19:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-17 15:59 [B.A.T.M.A.N.] [RFC] batman-adv: Add function to calculate crc32c for the skb payload Sven Eckelmann
2012-10-17 16:11 ` Martin Hundebøll
2012-10-17 17:18 ` [B.A.T.M.A.N.] [RFCv2] " Sven Eckelmann
2012-10-17 19:10 ` [B.A.T.M.A.N.] [RFCv3] " Sven Eckelmann
2012-10-17 19:57 ` Marek Lindner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox