* [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