net: fix IP checksum overflow during reduction

When reducing the checksum from a 32-bit or 64-bit intermediate,
we can get an overflow after the first overflow handling step:

0000_8000_8000_ffff
-> 10_ffff
->  1_000f
->    0010

Since we lacked the second step, we got an off-by-one in the checksum.
This commit is contained in:
Avi Kivity
2014-09-14 16:58:27 +03:00
parent 752b12738c
commit 89ec8f2ae7

View File

@@ -41,7 +41,8 @@ uint16_t ip_checksum(const void* data, size_t len) {
len -= 1;
}
csum = (csum & 0xffff) + ((csum >> 16) & 0xffff) + ((csum >> 32) & 0xffff) + (csum >> 48);
csum += csum >> 16;
csum = (csum & 0xffff) + (csum >> 16);
csum = (csum & 0xffff) + (csum >> 16);
return htons(~csum);
}
@@ -144,7 +145,8 @@ void checksummer::sum(const packet& p) {
}
uint16_t checksummer::get() const {
return partial + (partial >> 16);
auto tmp = (partial & 0xffff) + (partial >> 16);
return tmp + (tmp >> 16);
}
}