skb_checksum_help is designed to compute the Internet Checksum only. To
avoid duplicating code when other checksumming algorithms (e.g. crc32c)
are used, separate common part from RFC1624-specific part.

Reviewed-by: Marcelo Ricardo Leitner <marcelo.leit...@gmail.com>
Signed-off-by: Davide Caratti <dcara...@redhat.com>
---
 net/core/dev.c | 51 +++++++++++++++++++++++++++++++++++----------------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index ad5959e..6742160 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2532,13 +2532,36 @@ static void skb_warn_bad_offload(const struct sk_buff 
*skb)
             skb_shinfo(skb)->gso_type, skb->ip_summed);
 }
 
-/*
- * Invalidate hardware checksum when packet is to be mangled, and
+/* compute 16-bit RFC1624 checksum and store it at skb->data + offset */
+static int skb_rfc1624_csum(struct sk_buff *skb, int offset)
+{
+       __wsum csum;
+       int ret = 0;
+
+       csum = skb_checksum(skb, offset, skb->len - offset, 0);
+
+       offset += skb->csum_offset;
+       BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb));
+
+       if (skb_cloned(skb) &&
+           !skb_clone_writable(skb, offset + sizeof(__sum16))) {
+               ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+               if (ret)
+                       goto out;
+       }
+       *(__sum16 *)(skb->data + offset) = csum_fold(csum) ?: CSUM_MANGLED_0;
+out:
+       return ret;
+}
+
+/* Invalidate hardware checksum when packet is to be mangled, and
  * complete checksum manually on outgoing path.
+ *    @skb - buffer that needs checksum
+ *    @csum_algo(skb, offset) - function used to compute the checksum
  */
-int skb_checksum_help(struct sk_buff *skb)
+static int __skb_checksum_help(struct sk_buff *skb,
+                              int (*csum_algo)(struct sk_buff *, int))
 {
-       __wsum csum;
        int ret = 0, offset;
 
        if (skb->ip_summed == CHECKSUM_COMPLETE)
@@ -2560,24 +2583,20 @@ int skb_checksum_help(struct sk_buff *skb)
 
        offset = skb_checksum_start_offset(skb);
        BUG_ON(offset >= skb_headlen(skb));
-       csum = skb_checksum(skb, offset, skb->len - offset, 0);
-
-       offset += skb->csum_offset;
-       BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb));
-
-       if (skb_cloned(skb) &&
-           !skb_clone_writable(skb, offset + sizeof(__sum16))) {
-               ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-               if (ret)
-                       goto out;
-       }
 
-       *(__sum16 *)(skb->data + offset) = csum_fold(csum) ?: CSUM_MANGLED_0;
+       ret = csum_algo(skb, offset);
+       if (ret)
+               goto out;
 out_set_summed:
        skb->ip_summed = CHECKSUM_NONE;
 out:
        return ret;
 }
+
+int skb_checksum_help(struct sk_buff *skb)
+{
+       return __skb_checksum_help(skb, skb_rfc1624_csum);
+}
 EXPORT_SYMBOL(skb_checksum_help);
 
 __be16 skb_network_protocol(struct sk_buff *skb, int *depth)
-- 
2.7.4

Reply via email to