[PATCH] ipsum_calc_block: Optimize size and speed
Joakim Tjernlund
Joakim.Tjernlund at transmode.se
Fri Apr 23 10:02:54 CEST 2010
This is a much simpler and efficent impl. of the IP checksum.
It is a dry port from Quagga and I have not tested it.
---
lib/checksum.c | 44 +++++++++++---------------------------------
1 files changed, 11 insertions(+), 33 deletions(-)
diff --git a/lib/checksum.c b/lib/checksum.c
index 33cb386..b836bdb 100644
--- a/lib/checksum.c
+++ b/lib/checksum.c
@@ -15,25 +15,10 @@
#include "nest/bird.h"
#include "checksum.h"
-static u16 /* One-complement addition */
-add16(u16 sum, u16 x)
-{
- u16 z = sum + x;
- return z + (z < sum);
-}
-
-static u32
-add32(u32 sum, u32 x)
-{
- u32 z = sum + x;
- return z + (z < sum);
-}
-
static u16
ipsum_calc_block(u16 *x, unsigned len, u16 sum)
{
- int rest;
- u32 tmp, *xx;
+ u32 tmp;
/*
* A few simple facts about the IP checksum (see RFC 1071 for detailed
@@ -51,23 +36,16 @@ ipsum_calc_block(u16 *x, unsigned len, u16 sum)
if (!len)
return sum;
len >>= 1;
- if ((unsigned long) x & 2) /* Align to 32-bit boundary */
- {
- sum = add16(sum, *x++);
- len--;
- }
- rest = len & 1;
- len >>= 1;
- tmp = 0;
- xx = (u32 *) x;
- while (len)
- {
- tmp = add32(tmp, *xx++);
- len--;
- }
- sum = add16(sum, add16(tmp & 0xffff, tmp >> 16U));
- if (rest)
- sum = add16(sum, *(u16 *) xx);
+ tmp = sum;
+ for(x--; len; --len)
+ tmp += *++x;
+ /*
+ * Add back carry outs from top 16 bits to low 16 bits.
+ */
+ tmp = (tmp >> 16) + (tmp & 0xffff); /* add high-16 to low-16 */
+ tmp += (tmp >> 16); /* add carry */
+ sum = ~tmp; /* ones-complement, then truncate to 16 bits */
+
return sum;
}
--
1.6.4.4
More information about the Bird-users
mailing list