KEMBAR78
Add support for kTLS zerocopy sendfile on Linux by nvmmax · Pull Request #18650 · openssl/openssl · GitHub
Skip to content

Conversation

nvmmax
Copy link
Contributor

@nvmmax nvmmax commented Jun 24, 2022

TLS device offload allows to perform zerocopy sendfile transmissions.
FreeBSD provides this feature by default, and Linux 5.19 introduced it
as an opt-in. Zerocopy improves the TX rate significantly, but has a
side effect: if the underlying file is changed while being transmitted,
and a TCP retransmission happens, the receiver may get a TLS record
containing both new and old data, which leads to an authentication
failure and termination of connection. This effect is the reason Linux
makes a copy on sendfile by default.

This commit adds support for TLS zerocopy sendfile on Linux and uses it
by default, aligning OpenSSL's behavior on Linux and FreeBSD. A new
option called KTLSTxNoZerocopySendfile is added to disable the new
behavior on Linux and revert to copying. This option should be used when
the application can't guarantee that the file is not modified, and it's
not desired to break the connection.

The related documentation is also added in this commit. The unit test is
not added, because testing this functionality requires specific hardware
and a non-local peer.

Signed-off-by: Maxim Mikityanskiy maximmi@nvidia.com
Reviewed-by: Tariq Toukan tariqt@nvidia.com
Reviewed-by: Boris Pismenny borisp@nvidia.com

Checklist
  • documentation is added or updated

@openssl-machine openssl-machine added the hold: cla required The contributor needs to submit a license agreement label Jun 24, 2022
@t8m t8m added branch: master Merge to master branch triaged: feature The issue/pr requests/adds a feature labels Jun 24, 2022
@openssl-machine
Copy link
Collaborator

This PR has the label 'hold: cla required' and is stale: it has not been updated in 30 days. Note that this PR may be automatically closed in the future if no CLA is provided. For CLA help see https://www.openssl.org/policies/cla.html

@hlandau
Copy link
Member

hlandau commented Jul 25, 2022

We need a CLA signed in order to be able to consider this PR:

https://www.openssl.org/policies/cla.html

@nvmmax
Copy link
Contributor Author

nvmmax commented Jul 25, 2022

Thanks for reminding me, I'm aware of that, but unfortunately it takes time for the authorized people to sign the corporate CLA.

@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch from 8ef18a9 to 7621af3 Compare August 19, 2022 09:33
@openssl-machine openssl-machine removed the hold: cla required The contributor needs to submit a license agreement label Aug 19, 2022
@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch from 7621af3 to d0747da Compare August 22, 2022 15:22
@github-actions github-actions bot added the severity: fips change The pull request changes FIPS provider sources label Aug 22, 2022
@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch from d0747da to d76d6ef Compare August 23, 2022 09:40
@nvmmax
Copy link
Contributor Author

nvmmax commented Aug 30, 2022

Can the CI be triggered for my pull request?

@mattcaswell
Copy link
Member

Can the CI be triggered for my pull request?

Done

@gal-pressman
Copy link

Hey, can someone please take a look at this patch?

@ttoukan
Copy link

ttoukan commented Sep 14, 2022

Hi, what's the status of this one? I see that all checks passed. Is there any blocker?

@t8m t8m added approval: review pending This pull request needs review by a committer approval: otc review pending labels Sep 14, 2022
Copy link
Member

@hlandau hlandau left a comment

Choose a reason for hiding this comment

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

One nit, otherwise looks good.

@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch from d76d6ef to 2f0bbf8 Compare September 16, 2022 14:44
Copy link
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

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

Seems like this PR justifies an entry in CHANGES.md

performance boost when used with kTLS device offload. Note that invalid TLS
records might be transmitted if the file is modified while being sent, so this
option can be used to disable zerocopy. This option is only valid when
B<-sendfile> is specified.
Copy link
Member

Choose a reason for hiding this comment

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

It seems to me that by having this on by default you are introducing a breaking change. Stuff that worked before may no longer work. That's not allowed in a minor release, so it might be better to have it off by default and explicitly ask for it to be on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OpenSSL already supports zerocopy TLS sendfile on FreeBSD, and it's always active (i.e. there isn't even an option to disable it). The disclaimer that the file shouldn't be modified during sendfile already applies to FreeBSD to the same extent.

Since OpenSSL is a cross-platform library:

  • The behavior on different platforms should be as close as possible, i.e. if OpenSSL on FreeBSD uses zerocopy by default, OpenSSL on Linux should use it too.
  • I would assume that applications using a cross-platform library do not rely on implicit platform-specific behaviors, but stick to the strictest limitations among all platforms. As FreeBSD may corrupt TLS records if the application modifies the file during sendfile, applications using OpenSSL shouldn't modify the file if they care about this corruption. That means, it's safe to turn on the similar feature for Linux.

So, it's a breaking change only for the applications that are already broken (ones that modify the file during sendfile and don't want the corruption to happen, but when they are compiled on FreeBSD, they already suffer from it).

Having it off by default on Linux and always on on FreeBSD means introducing platform-specific behaviors exposed to the users of a cross-platform library, who expect it to behave the same way on all platforms.

Copy link
Member

Choose a reason for hiding this comment

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

I would assume that applications using a cross-platform library do not rely on implicit platform-specific behaviors,

I don't think this is a safe assumption. Although OpenSSL is a cross-platform library, not all users of OpenSSL care about its cross-platform capabilities.

As FreeBSD may corrupt TLS records if the application modifies the file during sendfile, applications using OpenSSL shouldn't modify the file if they care about this corruption.

Users on Linux are unlikely to be aware of this if their application does not run on FreeBSD.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's not allowed in a minor release

What about merging it to the next major release? Is that allowed?

Copy link
Member

Choose a reason for hiding this comment

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

What about merging it to the next major release? Is that allowed?

In principle yes - but in practice there is no branch for it as yet. master is being used for 3.1.

We could choose to take this to OTC to determine whether this is sufficiently breaking to justify requiring that this is "off" by default.

@mattcaswell
Copy link
Member

mattcaswell commented Sep 20, 2022

OTC Question: Should zero-copy sendfile be the default on Linux? This is already the default on FreeBSD but isn't currently on Linux - so there is an inconsistency. Changing this could theoretically break some Linux users

@mattcaswell mattcaswell added the hold: discussion The community needs to establish a consensus how to move forward with the issue or PR label Sep 20, 2022
@MILASTARX84

This comment was marked as abuse.

@mattcaswell
Copy link
Member

OTC: We should not change the default for Linux in 3.x. We might reconsider for 4.0. This PR would be ok if it was an opt-in runtime configuration.

@mattcaswell mattcaswell removed the hold: discussion The community needs to establish a consensus how to move forward with the issue or PR label Sep 20, 2022
@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch 3 times, most recently from 263d8d1 to b085b93 Compare September 20, 2022 13:37
@nvmmax nvmmax requested review from hlandau and removed request for hlandau September 23, 2022 13:21
@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch from d694ff2 to 41a2698 Compare October 15, 2022 12:01
@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch from 41a2698 to d8e095e Compare October 25, 2022 15:48
@gal-pressman
Copy link

@tmshort thanks for the review!
Is anything else needed to get this merged?

Copy link
Contributor

@tmshort tmshort left a comment

Choose a reason for hiding this comment

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

Still not a fan of some of the documentation and s_server output.

I will say this, that just because it's done in a certain way in one place, doesn't mean it's necessarily the right thing to do, or the only way to do it.

The documentation is technically incorrect because the options are not really "required" if the option is automatically turned on. If that documentation is given to QA/DevTest, they will write up a bug on it.

In other words, the documentation and the behavior/message don't really match, and I'd like to see one or the other fixed, even the existing code.


B<KTLSTxZerocopySendfile>: use the zerocopy TX mode of sendfile(), which gives
a performance boost when used with kTLS hardware offload. Note that invalid TLS
records might be transmitted if the file is changed while being sent. This
Copy link
Contributor

Choose a reason for hiding this comment

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

This still hasn't been addressed. I will also note that the phrasing below "This option only makes on Linux", is probably better as "This option only applies to Linux."

@tmshort
Copy link
Contributor

tmshort commented Nov 7, 2022

In addition, @hlandau would have to approve, and @mattcaswell would have to re-approve, as changes were made after his initial approval.
EDIT: And there's a CI failure, which may or may not be relevant.

@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch from d8e095e to 1809693 Compare November 9, 2022 09:46
@nvmmax
Copy link
Contributor Author

nvmmax commented Nov 9, 2022

The documentation is technically incorrect because the options are not really "required" if the option is automatically turned on.

I don't seem to get it... Are you looking at the latest version? Where did you see the word "required"?

The documentation says:

This option depends on B<-sendfile>; when used alone, B<-sendfile> is implied,
and a warning is shown.

which matches the code:

    if (use_zc_sendfile && !use_sendfile) {
        BIO_printf(bio_out, "Warning: -zerocopy_sendfile depends on -sendfile, enabling -sendfile now.\n");
        use_sendfile = 1;
    }

What exactly looks "incorrect" to you? If I missed something elsewhere, please point me at it.

And there's a CI failure, which may or may not be relevant.

I don't think the CI failure on macOS is relevant for a Linux-specific change.

@t8m
Copy link
Member

t8m commented Nov 9, 2022

And there's a CI failure, which may or may not be relevant.

I don't think the CI failure on macOS is relevant for a Linux-specific change.

The MacOS buildbot worker is broken currently. So that failure is not relevant.

@slontis
Copy link
Member

slontis commented Nov 9, 2022

The MacOS buildbot worker is broken currently. So that failure is not relevant.

Is someone actually responsible for buildbot? It gets a bit annoying when its broken for this long.

@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch from 1809693 to c406f68 Compare November 9, 2022 10:31
=item B<-zerocopy_sendfile>

If this option is set, SSL_sendfile() will use the zerocopy TX mode, which gives
a performance boost when used with kTLS hardware offload. Note that invalid
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not seeing "kTLS" (note capitalization) anywhere else in the documentation, except this PR.

Please change here, and elsewhere, to "Kernel TLS" or "KTLS" (all caps).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

# define BIO_FLAGS_KTLS_TX_CTRL_MSG 0x1000
# define BIO_FLAGS_KTLS_RX 0x2000
# define BIO_FLAGS_KTLS_TX 0x4000
# define BIO_FLAGS_KTLS_TX_ZEROCOPY_SENDFILE 0x8000
Copy link
Member

Choose a reason for hiding this comment

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

This internal flag needs to be reflected (as comment) in the openssl/bio.h as well. Otherwise we risk reusing the flag value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Modified the relevant comment.

TLS device offload allows to perform zerocopy sendfile transmissions.
FreeBSD provides this feature by default, and Linux 5.19 introduced it
as an opt-in. Zerocopy improves the TX rate significantly, but has a
side effect: if the underlying file is changed while being transmitted,
and a TCP retransmission happens, the receiver may get a TLS record
containing both new and old data, which leads to an authentication
failure and termination of connection. This effect is the reason Linux
makes a copy on sendfile by default.

This commit adds support for TLS zerocopy sendfile on Linux disabled by
default to avoid any unlikely backward compatibility issues on Linux,
although sacrificing consistency in OpenSSL's behavior on Linux and
FreeBSD. A new option called KTLSTxZerocopySendfile is added to enable
the new zerocopy behavior on Linux. This option should be used when the
the application guarantees that the file is not modified during
transmission, or it doesn't care about breaking the connection.

The related documentation is also added in this commit. The unit test
added doesn't test the actual functionality (it would require specific
hardware and a non-local peer), but solely checks that it's possible to
set the new option flag.

Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Boris Pismenny <borisp@nvidia.com>
@nvmmax nvmmax force-pushed the tls-zerocopy-sendfile-linux branch from c406f68 to 8c8b3e3 Compare November 23, 2022 11:06
@nvmmax nvmmax requested review from t8m and tmshort and removed request for tmshort November 23, 2022 11:07
@t8m t8m added the tests: present The PR has suitable tests present label Nov 23, 2022
@t8m t8m requested a review from mattcaswell November 23, 2022 11:20
@mattcaswell mattcaswell added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Nov 23, 2022
Copy link
Contributor

@tmshort tmshort left a comment

Choose a reason for hiding this comment

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

Fine by me

@openssl-machine
Copy link
Collaborator

24 hours has passed since 'approval: done' was set, but this PR has failing CI tests. Once the tests pass it will get moved to 'approval: ready to merge' automatically, alternatively please review and set the label manually.

@t8m
Copy link
Member

t8m commented Nov 24, 2022

Merged to master branch. Thank you for your contribution.

@t8m t8m closed this Nov 24, 2022
openssl-machine pushed a commit that referenced this pull request Nov 24, 2022
TLS device offload allows to perform zerocopy sendfile transmissions.
FreeBSD provides this feature by default, and Linux 5.19 introduced it
as an opt-in. Zerocopy improves the TX rate significantly, but has a
side effect: if the underlying file is changed while being transmitted,
and a TCP retransmission happens, the receiver may get a TLS record
containing both new and old data, which leads to an authentication
failure and termination of connection. This effect is the reason Linux
makes a copy on sendfile by default.

This commit adds support for TLS zerocopy sendfile on Linux disabled by
default to avoid any unlikely backward compatibility issues on Linux,
although sacrificing consistency in OpenSSL's behavior on Linux and
FreeBSD. A new option called KTLSTxZerocopySendfile is added to enable
the new zerocopy behavior on Linux. This option should be used when the
the application guarantees that the file is not modified during
transmission, or it doesn't care about breaking the connection.

The related documentation is also added in this commit. The unit test
added doesn't test the actual functionality (it would require specific
hardware and a non-local peer), but solely checks that it's possible to
set the new option flag.

Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Boris Pismenny <borisp@nvidia.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Todd Short <todd.short@me.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #18650)
beldmit pushed a commit to beldmit/openssl that referenced this pull request Dec 26, 2022
TLS device offload allows to perform zerocopy sendfile transmissions.
FreeBSD provides this feature by default, and Linux 5.19 introduced it
as an opt-in. Zerocopy improves the TX rate significantly, but has a
side effect: if the underlying file is changed while being transmitted,
and a TCP retransmission happens, the receiver may get a TLS record
containing both new and old data, which leads to an authentication
failure and termination of connection. This effect is the reason Linux
makes a copy on sendfile by default.

This commit adds support for TLS zerocopy sendfile on Linux disabled by
default to avoid any unlikely backward compatibility issues on Linux,
although sacrificing consistency in OpenSSL's behavior on Linux and
FreeBSD. A new option called KTLSTxZerocopySendfile is added to enable
the new zerocopy behavior on Linux. This option should be used when the
the application guarantees that the file is not modified during
transmission, or it doesn't care about breaking the connection.

The related documentation is also added in this commit. The unit test
added doesn't test the actual functionality (it would require specific
hardware and a non-local peer), but solely checks that it's possible to
set the new option flag.

Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Boris Pismenny <borisp@nvidia.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Todd Short <todd.short@me.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#18650)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: done This pull request has the required number of approvals branch: master Merge to master branch severity: fips change The pull request changes FIPS provider sources tests: present The PR has suitable tests present triaged: feature The issue/pr requests/adds a feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants