Skip to content
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

Improve zero checksum handling #46

Closed
wants to merge 1 commit into from
Closed

Conversation

angus19
Copy link
Contributor

@angus19 angus19 commented Oct 29, 2024

As per the suggestion by @ayourtch:

Well setting zero_csum_pass to 1 is not much of a fix, is it - it rather masks the problem in the code. Also it is a change of defaults, which i would be a bit hesitant to do…

Here’s an idea, what if we rewrite that bit as follows:

if (!udp->check) {
if (zero_csum_pass) {
// do nothing
break;
}
// recalculate the IPv6 checksum before adjusting
ip6_update_csum(…)
}
// here we will have nonzero checksum, unmagic + remagic

so, if it’s UDP and the checksum is zero and we don’t pass the zero checksum, recalculate it ?

It will still be broken if we don’t have full payload since we can’t do the full calculation in this case, but should take care of other cases ?

what do you think ?

As per the suggestion by @ayourtch:

Well setting zero_csum_pass to 1 is not much of a fix, is it - it rather masks the problem in the code. Also it is a change of defaults, which i would be a bit hesitant to do…

Here’s an idea, what if we rewrite that bit as follows:

if (!udp->check) {
if (zero_csum_pass) {
// do nothing
break;
}
// recalculate the IPv6 checksum before adjusting
ip6_update_csum(…)
}
// here we will have nonzero checksum, unmagic + remagic

so, if it’s UDP and the checksum is zero and we don’t pass the zero checksum, recalculate it ?

It will still be broken if we don’t have full payload since we can’t do the full calculation in this case, but should take care of other cases ?

what do you think ?
@angus19
Copy link
Contributor Author

angus19 commented Oct 29, 2024

@ayourtch Please review the change. Thanks.

Copy link
Owner

@ayourtch ayourtch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of nits/questions…

if ((udp->check == 0) && !zero_csum_pass) {
/*
* Checksum will still be broken if we don't have full payload
* since we can't do the full calculation in this case.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new conditional seems to be a no-op ? Why adding it ?

Copy link
Contributor Author

@angus19 angus19 Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put UDP reassembly aside. So UDP fragments associated with zero checksum, the corner case, will not be well handled even if we do recalculate checksum before adjusting via the ip6_update_csum method. I therefore drop a comment in the ip6_update_csum to mark such condition. Both csum_partial and csum_ipv6_magic methods are still serviced for an UDP fragment with zero checksum. But the result is incorrect.

@@ -1007,6 +1007,7 @@ int xlate_payload6_to4(nat46_instance_t *nat46, void *pv6, void *ptrans_hdr, int
/* zero checksum and the config to pass it is set - do nothing with it */
break;
}
/* pretend checksum is correct not null */
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add a logic to recalculate the checksum here if it is zero ? (Reviewing on the phone, so might be wrong).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think recalculation over here is required. In the xlate_payload6_to4 method, we care about translation of a payload inside an ICMPv6. Although this payload is structured by an inner packet which has its own IPv6 header + L4 header + payload. But it is usually truncated. So checksum recalculation happens to the inner L4 header is also usually not possible.

@angus19
Copy link
Contributor Author

angus19 commented Oct 30, 2024

@ayourtch Good to see you fix the change in no matter the wording/comment or any others.
e.g.
/*
* Checksum will still be broken if we don't have full payload
* since we can't do the full calculation in this case.
*/
is changed to
/*
* Checksum will still be broken in this case since we don't
* have full payload to properly do the full calculation.
*/
Thank you.

@angus19 angus19 closed this Nov 4, 2024
@angus19
Copy link
Contributor Author

angus19 commented Nov 4, 2024

Closing as the change is still buggy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants