X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fcsum.c;h=33ec28b646fad4140910a5f6f0219560999f7f92;hb=54ae6fa8f1ae7401652d282609848605fc283104;hp=6f044473e2f87607ccdd071e87f28540b25a048d;hpb=34e63086edddcae06d7c1a4fa84fec0861e50758;p=openvswitch diff --git a/lib/csum.c b/lib/csum.c index 6f044473..33ec28b6 100644 --- a/lib/csum.c +++ b/lib/csum.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009 Nicira Networks. + * Copyright (c) 2008, 2009, 2010 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ #include #include "csum.h" +#include "unaligned.h" /* Returns the IP checksum of the 'n' bytes in 'data'. * @@ -57,8 +58,8 @@ csum_continue(uint32_t partial, const void *data_, size_t n) { const uint16_t *data = data_; - for (; n > 1; n -= 2) { - partial = csum_add16(partial, *data++); + for (; n > 1; n -= 2, data++) { + partial = csum_add16(partial, get_unaligned_u16(data)); } if (n) { partial += *(uint8_t *) data; @@ -76,7 +77,10 @@ csum_continue(uint32_t partial, const void *data_, size_t n) uint16_t csum_finish(uint32_t partial) { - return ~((partial & 0xffff) + (partial >> 16)); + while (partial >> 16) { + partial = (partial & 0xffff) + (partial >> 16); + } + return ~partial; } /* Returns the new checksum for a packet in which the checksum field previously @@ -93,8 +97,7 @@ recalc_csum16(uint16_t old_csum, uint16_t old_u16, uint16_t new_u16) uint16_t m_complement = ~old_u16; uint16_t m_prime = new_u16; uint32_t sum = hc_complement + m_complement + m_prime; - uint16_t hc_prime_complement = sum + (sum >> 16); - return ~hc_prime_complement; + return csum_finish(sum); } /* Returns the new checksum for a packet in which the checksum field previously