X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=lib%2Fcsum.c;h=a0e9967167ea49ed65f17ed95990daa0dba4f925;hb=HEAD;hp=fb32a530dfce8d9935b78cb24906dfc7df2ce2c8;hpb=bc7a5acdff087b7e7a162da42ae608a83f3cf902;p=cascardo%2Fovs.git diff --git a/lib/csum.c b/lib/csum.c index fb32a530d..a0e996716 100644 --- a/lib/csum.c +++ b/lib/csum.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2013, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ #include "unaligned.h" #ifndef __CHECKER__ - /* Returns the IP checksum of the 'n' bytes in 'data'. * * The return value has the same endianness as the data. That is, if 'data' @@ -32,25 +31,6 @@ csum(const void *data, size_t n) return csum_finish(csum_continue(0, data, n)); } -/* Adds the 16 bits in 'new' to the partial IP checksum 'partial' and returns - * the updated checksum. (To start a new checksum, pass 0 for 'partial'. To - * obtain the finished checksum, pass the return value to csum_finish().) */ -uint32_t -csum_add16(uint32_t partial, ovs_be16 new) -{ - return partial + new; -} - -/* Adds the 32 bits in 'new' to the partial IP checksum 'partial' and returns - * the updated checksum. (To start a new checksum, pass 0 for 'partial'. To - * obtain the finished checksum, pass the return value to csum_finish().) */ -uint32_t -csum_add32(uint32_t partial, ovs_be32 new) -{ - return partial + (new >> 16) + (new & 0xffff); -} - - /* Adds the 'n' bytes in 'data' to the partial IP checksum 'partial' and * returns the updated checksum. (To start a new checksum, pass 0 for * 'partial'. To obtain the finished checksum, pass the return value to @@ -112,18 +92,35 @@ recalc_csum32(ovs_be16 old_csum, ovs_be32 old_u32, ovs_be32 new_u32) old_u32 >> 16, new_u32 >> 16); } +/* Returns the new checksum for a packet in which the checksum field previously + * contained 'old_csum' and in which a field that contained the 6 bytes at + * 'old_mac' was changed to contain the 6 bytes at 'new_mac'. */ +ovs_be16 +recalc_csum48(ovs_be16 old_csum, const struct eth_addr old_mac, + const struct eth_addr new_mac) +{ + ovs_be16 new_csum = old_csum; + + for (int i = 0; i < 3; ++i) { + new_csum = recalc_csum16(new_csum, old_mac.be16[i], new_mac.be16[i]); + } + + return new_csum; +} + /* Returns the new checksum for a packet in which the checksum field previously * contained 'old_csum' and in which a field that contained 'old_u32[4]' was * changed to contain 'new_u32[4]'. */ ovs_be16 -recalc_csum128(ovs_be16 old_csum, ovs_be32 old_u32[4], +recalc_csum128(ovs_be16 old_csum, ovs_16aligned_be32 old_u32[4], const ovs_be32 new_u32[4]) { ovs_be16 new_csum = old_csum; int i; for (i = 0; i < 4; ++i) { - new_csum = recalc_csum32(new_csum, old_u32[i], new_u32[i]); + new_csum = recalc_csum32(new_csum, + get_16aligned_be32(&old_u32[i]), new_u32[i]); } return new_csum; }