[PATCH] ipsum_calc_block: Optimize size and speed
Joakim Tjernlund
joakim.tjernlund at transmode.se
Fri Apr 23 10:12:32 CEST 2010
Joakim Tjernlund <Joakim.Tjernlund at transmode.se> wrote on 2010/04/23 10:02:54:
>
> 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 */
Possibly the "sum = ~tmp;" line should be removed. Looks like it is
performed by the calling routines.
Jocke
More information about the Bird-users
mailing list