-
Notifications
You must be signed in to change notification settings - Fork 234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gk: fix checksum issue #425
Conversation
Notice that the given example actually implements equation 3 of RFC1624. Moreover, one's complement sum and one's complement (i.e. C's operator We have assumed that the two's complement subtraction, which is currently being used, is the same as "subtracting complements with borrow" under one's complement as required in RFC1624. While these two operations often come up with the same result, they are often not equal too. And this is the bug we are facing. In addition, the two's complement subtraction is not endianness preserving! The solution is to fix the current code using the following functions: /*
* One's complement sum.
*
* Notice that if @a and @b are little-endian, the result is also
* little-endian. The same is true for big-endian. In order words,
* this function preserves endianness.
*
* The endianness preservation is independent of the endianness of the host.
*/
static inline uint16_t
onec_add(uint16_t a, uint16_t b)
{
uint16_t res = a + b;
return res + (res < b);
}
/*
* The result has the same endianness of the inputs as long as
* all inputs have the same endianness.
* The endianness preservation is independent of the endianness of the host.
*/
static inline uint16_t
new_ip_csum(uint16_t old_csum, uint16_t old16, uint16_t new16)
{
/* According to RFC1624 [Eqn. 3]. */
return ~onec_add(onec_add(~old_csum, ~old16), new16);
} Don't forget to update the description of the patch with a better text, for example, explain when the bug happens. |
0cfefaa
to
d828a54
Compare
Thanks so much @AltraMayor ! This rebase is ready for another review. |
e746d6d
to
6edb33d
Compare
The code is ready for merge, but please drop the whole parenthesis in this section of the patch comment: |
The checksum bug discussed in AltraMayor#417 (comment) is because we have assumed that the two's complement subtraction, which is currently being used, is the same as "subtracting complements with borrow" under one's complement as required in RFC1624. While these two operations often come up with the same result, they are often not equal too. In addition, the two's complement subtraction is not endianness preserving! To solve this issue, we followed the example implmentation of RFC1624 [Eqn. 3] in Linux kernel: https://elixir.bootlin.com/linux/latest/source/net/ipv4/netfilter/ipt_ECN.c#L38
6edb33d
to
ee30550
Compare
This rebase is ready for another review. |
Some examples that implement the RFC1624 [Eqn. 4] use the network order:
https://elixir.bootlin.com/linux/latest/source/net/ipv4/netfilter/ipt_ECN.c#L38
This patch removes the byte-order convertion for checksum.