요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
==================
Kernel TLS offload
==================
Kernel TLS operation
====================
Linux kernel provides TLS connection offload infrastructure. Once a TCP
connection is in ``ESTABLISHED`` state user space can enable the TLS Upper
Layer Protocol (ULP) and install the cryptographic connection state.
For details regarding the user-facing interface refer to the TLS
documentation in :ref:`Documentation/networking/tls.rst <kernel_tls>`.
``ktls`` can operate in three modes:
* Software crypto mode (``TLS_SW``) - CPU handles the cryptography.
In most basic cases only crypto operations synchronous with the CPU
can be used, but depending on calling context CPU may utilize
asynchronous crypto accelerators. The use of accelerators introduces extra
latency on socket reads (decryption only starts when a read syscall
is made) and additional I/O load on the system.
* Packet-based NIC offload mode (``TLS_HW``) - the NIC handles crypto
on a packet by packet basis, provided the packets arrive in order.
This mode integrates best with the kernel stack and is described in detail
in the remaining part of this document
(``ethtool`` flags ``tls-hw-tx-offload`` and ``tls-hw-rx-offload``).
* Full TCP NIC offload mode (``TLS_HW_RECORD``) - mode of operation where
NIC driver and firmware replace the kernel networking stack
with its own TCP handling, it is not usable in production environments
making use of the Linux networking stack for example any firewalling
abilities or QoS and packet scheduling (``ethtool`` flag ``tls-hw-record``).
The operation mode is selected automatically based on device configuration,
offload opt-in or opt-out on per-connection basis is not currently supported.
TX
--
At a high level user write requests are turned into a scatter list, the TLS ULP
intercepts them, inserts record framing, performs encryption (in ``TLS_SW``
mode) and then hands the modified scatter list to the TCP layer. From this
point on the TCP stack proceeds as normal.
In ``TLS_HW`` mode the encryption is not performed in the TLS ULP.
Instead packets reach a device driver, the driver will mark the packets
for crypto offload based on the socket the packet is attached to,
and send them to the device for encryption and transmission.
RX
--
On the receive side, if the device handled decryption and authentication
successfully, the driver will set the decrypted bit in the associated
:c:type:`struct sk_buff <sk_buff>`. The packets reach the TCP stack and
are handled normally. ``ktls`` is informed when data is queued to the socket
and the ``strparser`` mechanism is used to delineate the records. Upon read
request, records are retrieved from the socket and passed to decryption routine.
If device decrypted all the segments of the record the decryption is skipped,
otherwise software path handles decryption.
.. kernel-figure:: tls-offload-layers.svg
:alt: TLS offload layers
:align: center
:figwidth: 28em
Layers of Kernel TLS stack
Device configuration
====================
During driver initialization device sets the ``NETIF_F_HW_TLS_RX`` and
``NETIF_F_HW_TLS_TX`` features and installs its
:c:type:`struct tlsdev_ops <tlsdev_ops>`
pointer in the :c:member:`tlsdev_ops` member of the
:c:type:`struct net_device <net_device>`.
When TLS cryptographic connection state is installed on a ``ktls`` socket
(note that it is done twice, once for RX and once for TX direction,
and the two are completely independent), the kernel checks if the underlying
network device is offload-capable and attempts the offload. In case offload
fails the connection is handled entirely in software using the same mechanism
as if the offload was never tried.
Offload request is performed via the :c:member:`tls_dev_add` callback of
:c:type:`struct tlsdev_ops <tlsdev_ops>`:
.. code-block:: c
int (*tls_dev_add)(struct net_device *netdev, struct sock *sk,
enum tls_offload_ctx_dir direction,
struct tls_crypto_info *crypto_info,
u32 start_offload_tcp_sn);
``direction`` indicates whether the cryptographic information is for
the received or transmitted packets. Driver uses the ``sk`` parameter
to retrieve the connection 5-tuple and socket family (IPv4 vs IPv6).
Cryptographic information in ``crypto_info`` includes the key, iv, salt
as well as TLS record sequence number. ``start_offload_tcp_sn`` indicates
which TCP sequence number corresponds to the beginning of the record with
sequence number from ``crypto_info``. The driver can add its state
at the end of kernel structures (see :c:member:`driver_state` members
in ``include/net/tls.h``) to avoid additional allocations and pointer
dereferences.
TX
--
After TX state is installed, the stack guarantees that the first segment
of the stream will start exactly at the ``start_offload_tcp_sn`` sequence
number, simplifying TCP sequence number matching.
TX offload being fully initialized does not imply that all segments passing
through the driver and which belong to the offloaded socket will be after
the expected sequence number and will have kernel record information.
In particular, already encrypted data may have been queued to the socket
before installing the connection state in the kernel.
RX
--
In the RX direction, the local networking stack has little control over
segmentation, so the initial records' TCP sequence number may be anywhere
inside the segment.
Normal operation
================
At the minimum the device maintains the following state for each connection, in
each direction:
* crypto secrets (key, iv, salt)
* crypto processing state (partial blocks, partial authentication tag, etc.)
* record metadata (sequence number, processing offset and length)
* expected TCP sequence number
There are no guarantees on record length or record segmentation. In particular
segments may start at any point of a record and contain any number of records.
Assuming segments are received in order, the device should be able to perform
crypto operations and authentication regardless of segmentation. For this
to be possible, the device has to keep a small amount of segment-to-segment
state. This includes at least:
* partial headers (if a segment carried only a part of the TLS header)
* partial data block
* partial authentication tag (all data had been seen but part of the
authentication tag has to be written or read from the subsequent segment)
Record reassembly is not necessary for TLS offload. If the packets arrive
in order the device should be able to handle them separately and make
forward progress.
TX
--
The kernel stack performs record framing reserving space for the authentication
tag and populating all other TLS header and tailer fields.
Both the device and the driver maintain expected TCP sequence numbers
due to the possibility of retransmissions and the lack of software fallback
once the packet reaches the device.
For segments passed in order, the driver marks the packets with
a connection identifier (note that a 5-tuple lookup is insufficient to identify
packets requiring HW offload, see the :ref:`5tuple_problems` section)
and hands them to the device. The device identifies the packet as requiring
TLS handling and confirms the sequence number matches its expectation.
The device performs encryption and authentication of the record data.
It replaces the authentication tag and TCP checksum with correct values.
RX
--
Before a packet is DMAed to the host (but after NIC's embedded switching
and packet transformation functions) the device validates the Layer 4
checksum and performs a 5-tuple lookup to find any TLS connection the packet
may belong to (technically a 4-tuple
lookup is sufficient - IP addresses and TCP port numbers, as the protocol
is always TCP). If the packet is matched to a connection, the device confirms
if the TCP sequence number is the expected one and proceeds to TLS handling
(record delineation, decryption, authentication for each record in the packet).
The device leaves the record framing unmodified, the stack takes care of record
decapsulation. Device indicates successful handling of TLS offload in the
per-packet context (descriptor) passed to the host.
Upon reception of a TLS offloaded packet, the driver sets
the :c:member:`decrypted` mark in :c:type:`struct sk_buff <sk_buff>`
corresponding to the segment. Networking stack makes sure decrypted
and non-decrypted segments do not get coalesced (e.g. by GRO or socket layer)
and takes care of partial decryption.
Resync handling
===============
In presence of packet drops or network packet reordering, the device may lose
synchronization with the TLS stream, and require a resync with the kernel's
TCP stack.
Note that resync is only attempted for connections which were successfully
added to the device table and are in TLS_HW mode. For example,
if the table was full when cryptographic state was installed in the kernel,
such connection will never get offloaded. Therefore the resync request
does not carry any cryptographic connection state.
TX
--
Segments transmitted from an offloaded socket can get out of sync
in similar ways to the receive side-retransmissions - local drops
are possible, though network reorders are not. There are currently
two mechanisms for dealing with out of order segments.
Crypto state rebuilding
~~~~~~~~~~~~~~~~~~~~~~~
Whenever an out of order segment is transmitted the driver provides
the device with enough information to perform cryptographic operations.
This means most likely that the part of the record preceding the current
segment has to be passed to the device as part of the packet context,
together with its TCP sequence number and TLS record number. The device
can then initialize its crypto state, process and discard the preceding
data (to be able to insert the authentication tag) and move onto handling
the actual packet.
In this mode depending on the implementation the driver can either ask
for a continuation with the crypto state and the new sequence number
(next expected segment is the one after the out of order one), or continue
with the previous stream state - assuming that the out of order segment
was just a retransmission. The former is simpler, and does not require
retransmission detection therefore it is the recommended method until
such time it is proven inefficient.
Next record sync
~~~~~~~~~~~~~~~~
Whenever an out of order segment is detected the driver requests
that the ``ktls`` software fallback code encrypt it. If the segment's
sequence number is lower than expected the driver assumes retransmission
and doesn't change device state. If the segment is in the future, it
may imply a local drop, the driver asks the stack to sync the device
to the next record state and falls back to software.
Resync request is indicated with:
.. code-block:: c
void tls_offload_tx_resync_request(struct sock *sk, u32 got_seq, u32 exp_seq)
Until resync is complete driver should not access its expected TCP
sequence number (as it will be updated from a different context).
Following helper should be used to test if resync is complete:
.. code-block:: c
bool tls_offload_tx_resync_pending(struct sock *sk)
Next time ``ktls`` pushes a record it will first send its TCP sequence number
and TLS record number to the driver. Stack will also make sure that
the new record will start on a segment boundary (like it does when
the connection is initially added).
RX
--
A small amount of RX reorder events may not require a full resynchronization.
In particular the device should not lose synchronization
when record boundary can be recovered:
.. kernel-figure:: tls-offload-reorder-good.svg
:alt: reorder of non-header segment
:align: center
Reorder of non-header segment
Green segments are successfully decrypted, blue ones are passed
as received on wire, red stripes mark start of new records.
In above case segment 1 is received and decrypted successfully.
Segment 2 was dropped so 3 arrives out of order. The device knows
the next record starts inside 3, based on record length in segment 1.
Segment 3 is passed untouched, because due to lack of data from segment 2
the remainder of the previous record inside segment 3 cannot be handled.
The device can, however, collect the authentication algorithm's state
and partial block from the new record in segment 3 and when 4 and 5
arrive continue decryption. Finally when 2 arrives it's completely outside
of expected window of the device so it's passed as is without special
handling. ``ktls`` software fallback handles the decryption of record
spanning segments 1, 2 and 3. The device did not get out of sync,
even though two segments did not get decrypted.
Kernel synchronization may be necessary if the lost segment contained
a record header and arrived after the next record header has already passed:
.. kernel-figure:: tls-offload-reorder-bad.svg
:alt: reorder of header segment
:align: center
Reorder of segment with a TLS header
In this example segment 2 gets dropped, and it contains a record header.
Device can only detect that segment 4 also contains a TLS header
if it knows the length of the previous record from segment 2. In this case
the device will lose synchronization with the stream.
Stream scan resynchronization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When the device gets out of sync and the stream reaches TCP sequence
numbers more than a max size record past the expected TCP sequence number,
the device starts scanning for a known header pattern. For example
for TLS 1.2 and TLS 1.3 subsequent bytes of value ``0x03 0x03`` occur
in the SSL/TLS version field of the header. Once pattern is matched
the device continues attempting parsing headers at expected locations
(based on the length fields at guessed locations).
Whenever the expected location does not contain a valid header the scan
is restarted.
When the header is matched the device sends a confirmation request
to the kernel, asking if the guessed location is correct (if a TLS record
really starts there), and which record sequence number the given header had.
The kernel confirms the guessed location was correct and tells the device
the record sequence number. Meanwhile, the device had been parsing
and counting all records since the just-confirmed one, it adds the number
of records it had seen to the record number provided by the kernel.
At this point the device is in sync and can resume decryption at next
segment boundary.
In a pathological case the device may latch onto a sequence of matching
headers and never hear back from the kernel (there is no negative
confirmation from the kernel). The implementation may choose to periodically
restart scan. Given how unlikely falsely-matching stream is, however,
periodic restart is not deemed necessary.
Special care has to be taken if the confirmation request is passed
asynchronously to the packet stream and record may get processed
by the kernel before the confirmation request.
Stack-driven resynchronization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The driver may also request the stack to perform resynchronization
whenever it sees the records are no longer getting decrypted.
If the connection is configured in this mode the stack automatically
schedules resynchronization after it has received two completely encrypted
records.
The stack waits for the socket to drain and informs the device about
the next expected record number and its TCP sequence number. If the
records continue to be received fully encrypted stack retries the
synchronization with an exponential back off (first after 2 encrypted
records, then after 4 records, after 8, after 16... up until every
128 records).
Error handling
==============
TX
--
Packets may be redirected or rerouted by the stack to a different
device than the selected TLS offload device. The stack will handle
such condition using the :c:func:`sk_validate_xmit_skb` helper
(TLS offload code installs :c:func:`tls_validate_xmit_skb` at this hook).
Offload maintains information about all records until the data is
fully acknowledged, so if skbs reach the wrong device they can be handled
by software fallback.
Any device TLS offload handling error on the transmission side must result
in the packet being dropped. For example if a packet got out of order
due to a bug in the stack or the device, reached the device and can't
be encrypted such packet must be dropped.
RX
--
If the device encounters any problems with TLS offload on the receive
side it should pass the packet to the host's networking stack as it was
received on the wire.
For example authentication failure for any record in the segment should
result in passing the unmodified packet to the software fallback. This means
packets should not be modified "in place". Splitting segments to handle partial
decryption is not advised. In other words either all records in the packet
had been handled successfully and authenticated or the packet has to be passed
to the host's stack as it was on the wire (recovering original packet in the
driver if device provides precise error is sufficient).
The Linux networking stack does not provide a way of reporting per-packet
decryption and authentication errors, packets with errors must simply not
have the :c:member:`decrypted` mark set.
A packet should also not be handled by the TLS offload if it contains
incorrect checksums.
Performance metrics
===================
TLS offload can be characterized by the following basic metrics:
* max connection count
* connection installation rate
* connection installation latency
* total cryptographic performance
Note that each TCP connection requires a TLS session in both directions,
the performance may be reported treating each direction separately.
Max connection count
--------------------
The number of connections device can support can be exposed via
``devlink resource`` API.
Total cryptographic performance
-------------------------------
Offload performance may depend on segment and record size.
Overload of the cryptographic subsystem of the device should not have
significant performance impact on non-offloaded streams.
Statistics
==========
Following minimum set of TLS-related statistics should be reported
by the driver:
* ``rx_tls_decrypted_packets`` - number of successfully decrypted RX packets
which were part of a TLS stream.
* ``rx_tls_decrypted_bytes`` - number of TLS payload bytes in RX packets
which were successfully decrypted.
* ``rx_tls_ctx`` - number of TLS RX HW offload contexts added to device for
decryption.
* ``rx_tls_del`` - number of TLS RX HW offload contexts deleted from device
(connection has finished).
* ``rx_tls_resync_req_pkt`` - number of received TLS packets with a resync
request.
* ``rx_tls_resync_req_start`` - number of times the TLS async resync request
was started.
* ``rx_tls_resync_req_end`` - number of times the TLS async resync request
properly ended with providing the HW tracked tcp-seq.
* ``rx_tls_resync_req_skip`` - number of times the TLS async resync request
procedure was started but not properly ended.
* ``rx_tls_resync_res_ok`` - number of times the TLS resync response call to
the driver was successfully handled.
* ``rx_tls_resync_res_skip`` - number of times the TLS resync response call to
the driver was terminated unsuccessfully.
* ``rx_tls_err`` - number of RX packets which were part of a TLS stream
but were not decrypted due to unexpected error in the state machine.
* ``tx_tls_encrypted_packets`` - number of TX packets passed to the device
for encryption of their TLS payload.
* ``tx_tls_encrypted_bytes`` - number of TLS payload bytes in TX packets
passed to the device for encryption.
* ``tx_tls_ctx`` - number of TLS TX HW offload contexts added to device for
encryption.
* ``tx_tls_ooo`` - number of TX packets which were part of a TLS stream
but did not arrive in the expected order.
* ``tx_tls_skip_no_sync_data`` - number of TX packets which were part of
a TLS stream and arrived out-of-order, but skipped the HW offload routine
and went to the regular transmit flow as they were retransmissions of the
connection handshake.
* ``tx_tls_drop_no_sync_data`` - number of TX packets which were part of
a TLS stream dropped, because they arrived out of order and associated
record could not be found.
* ``tx_tls_drop_bypass_req`` - number of TX packets which were part of a TLS
stream dropped, because they contain both data that has been encrypted by
software and data that expects hardware crypto offload.
Notable corner cases, exceptions and additional requirements
============================================================
.. _5tuple_problems:
5-tuple matching limitations
----------------------------
The device can only recognize received packets based on the 5-tuple
of the socket. Current ``ktls`` implementation will not offload sockets
routed through software interfaces such as those used for tunneling
or virtual networking. However, many packet transformations performed
by the networking stack (most notably any BPF logic) do not require
any intermediate software device, therefore a 5-tuple match may
consistently miss at the device level. In such cases the device
should still be able to perform TX offload (encryption) and should
fallback cleanly to software decryption (RX).
Out of order
------------
Introducing extra processing in NICs should not cause packets to be
transmitted or received out of order, for example pure ACK packets
should not be reordered with respect to data segments.
Ingress reorder
---------------
A device is permitted to perform packet reordering for consecutive
TCP segments (i.e. placing packets in the correct order) but any form
of additional buffering is disallowed.
Coexistence with standard networking offload features
-----------------------------------------------------
Offloaded ``ktls`` sockets should support standard TCP stack features
transparently. Enabling device TLS offload should not cause any difference
in packets as seen on the wire.
Transport layer transparency
----------------------------
For the purpose of simplifying TLS offload, the device should not modify any
packet headers.
The device should not depend on any packet headers beyond what is strictly
necessary for TLS offload.
Segment drops
-------------
Dropping packets is acceptable only in the event of catastrophic
system errors and should never be used as an error handling mechanism
in cases arising from normal operation. In other words, reliance
on TCP retransmissions to handle corner cases is not acceptable.
TLS device features
-------------------
Drivers should ignore the changes to the TLS device feature flags.
These flags will be acted upon accordingly by the core ``ktls`` code.
TLS device feature flags only control adding of new TLS connection
offloads, old connections will remain active after flags are cleared.
TLS encryption cannot be offloaded to devices without checksum calculation
offload. Hence, TLS TX device feature flag requires TX csum offload being set.
Disabling the latter implies clearing the former. Disabling TX checksum offload
should not affect old connections, and drivers should make sure checksum
calculation does not break for them.
Similarly, device-offloaded TLS decryption implies doing RXCSUM. If the user
does not want to enable RX csum offload, TLS RX device feature is disabled
as well.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
kTLS 동작 mode와 TX/RX path
1-69이 문서는 GPL-2.0-only 또는 BSD-2-Clause 라이선스를 따르며 kernel TLS device offload를 설명합니다.
TCP connection이 `ESTABLISHED` 상태가 되면 userspace는 TLS ULP를 enable하고 cryptographic connection state를 설치할 수 있습니다. User interface는 `Documentation/networking/tls.rst`를 참조합니다.
Crypto와 TCP 처리를 담당하는 위치가 다릅니다.
Mode는 device configuration으로 자동 선택되며 connection별 opt-in/opt-out은 현재 지원하지 않습니다.
TX에서 userspace write는 scatter list가 되고 TLS ULP가 intercept해 record framing을 넣습니다. `TLS_SW`는 여기서 encrypt한 뒤 TCP layer에 넘기며 이후 TCP stack은 정상 동작합니다. `TLS_HW`는 ULP가 encrypt하지 않고 driver가 packet의 socket을 기준으로 crypto offload mark를 붙여 device가 encrypt·transmit하게 합니다.
RX에서 device가 decrypt와 authenticate를 성공하면 driver가 관련 `sk_buff`의 `decrypted` bit를 설정합니다. TCP stack은 packet을 정상 처리하고 socket queue에 data가 쌓이면 kTLS가 통지받습니다. `strparser`가 record 경계를 정하며 read 때 record를 decryption routine으로 넘깁니다. Device가 record의 모든 segment를 decrypt했으면 skip하고 아니면 software path가 처리합니다.
Record framing과 crypto 위치를 mode별로 구분합니다.
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
==================
Kernel TLS offload
==================
Kernel TLS operation
====================
Linux kernel provides TLS connection offload infrastructure. Once a TCP
connection is in ``ESTABLISHED`` state user space can enable the TLS Upper
Layer Protocol (ULP) and install the cryptographic connection state.
For details regarding the user-facing interface refer to the TLS
documentation in :ref:`Documentation/networking/tls.rst <kernel_tls>`.
``ktls`` can operate in three modes:
* Software crypto mode (``TLS_SW``) - CPU handles the cryptography.
In most basic cases only crypto operations synchronous with the CPU
can be used, but depending on calling context CPU may utilize
asynchronous crypto accelerators. The use of accelerators introduces extra
latency on socket reads (decryption only starts when a read syscall
is made) and additional I/O load on the system.
* Packet-based NIC offload mode (``TLS_HW``) - the NIC handles crypto
on a packet by packet basis, provided the packets arrive in order.
This mode integrates best with the kernel stack and is described in detail
in the remaining part of this document
(``ethtool`` flags ``tls-hw-tx-offload`` and ``tls-hw-rx-offload``).
* Full TCP NIC offload mode (``TLS_HW_RECORD``) - mode of operation where
NIC driver and firmware replace the kernel networking stack
with its own TCP handling, it is not usable in production environments
making use of the Linux networking stack for example any firewalling
abilities or QoS and packet scheduling (``ethtool`` flag ``tls-hw-record``).
The operation mode is selected automatically based on device configuration,
offload opt-in or opt-out on per-connection basis is not currently supported.
TX
--
At a high level user write requests are turned into a scatter list, the TLS ULP
intercepts them, inserts record framing, performs encryption (in ``TLS_SW``
mode) and then hands the modified scatter list to the TCP layer. From this
point on the TCP stack proceeds as normal.
In ``TLS_HW`` mode the encryption is not performed in the TLS ULP.
Instead packets reach a device driver, the driver will mark the packets
for crypto offload based on the socket the packet is attached to,
and send them to the device for encryption and transmission.
RX
--
On the receive side, if the device handled decryption and authentication
successfully, the driver will set the decrypted bit in the associated
:c:type:`struct sk_buff <sk_buff>`. The packets reach the TCP stack and
are handled normally. ``ktls`` is informed when data is queued to the socket
and the ``strparser`` mechanism is used to delineate the records. Upon read
request, records are retrieved from the socket and passed to decryption routine.
If device decrypted all the segments of the record the decryption is skipped,
otherwise software path handles decryption.
.. kernel-figure:: tls-offload-layers.svg
:alt: TLS offload layers
:align: center
:figwidth: 28em
Layers of Kernel TLS stack
Device feature와 tls_dev_add
70-126Driver 초기화 때 device는 `NETIF_F_HW_TLS_RX`, `NETIF_F_HW_TLS_TX` feature를 설정하고 `net_device.tlsdev_ops`에 `struct tlsdev_ops` pointer를 설치합니다.
kTLS socket에 RX와 TX cryptographic state를 각각 독립적으로 설치할 때 kernel은 underlying device의 offload capability를 확인해 시도합니다. 실패하면 offload를 시도하지 않은 것과 같은 software mechanism으로 connection 전체를 처리합니다.
Offload request는 `tlsdev_ops.tls_dev_add(netdev, sk, direction, crypto_info, start_offload_tcp_sn)` callback입니다. `direction`은 RX/TX, `sk`는 connection 5-tuple과 IPv4/IPv6 family를 제공합니다. `crypto_info`에는 key, IV, salt, TLS record sequence가 있습니다. `start_offload_tcp_sn`은 그 record 시작에 해당하는 TCP sequence입니다.
Driver는 `include/net/tls.h`의 `driver_state` member처럼 kernel structure 끝에 state를 붙여 별도 allocation과 pointer dereference를 줄일 수 있습니다.
TX state 설치 뒤 stack은 첫 stream segment가 정확히 `start_offload_tcp_sn`에서 시작하게 보장합니다. 그러나 설치 전에 이미 encrypt된 data가 socket에 queue될 수 있으므로 이후 driver를 지나는 offloaded socket packet 모두가 기대 sequence 이후이거나 kernel record 정보를 가진다는 보장은 없습니다.
RX segmentation은 local stack이 거의 제어하지 못하므로 initial record 시작 TCP sequence는 segment 내부 어느 위치에나 있을 수 있습니다.
Connection crypto context를 device에 설치하는 정보입니다.
Device configuration
====================
During driver initialization device sets the ``NETIF_F_HW_TLS_RX`` and
``NETIF_F_HW_TLS_TX`` features and installs its
:c:type:`struct tlsdev_ops <tlsdev_ops>`
pointer in the :c:member:`tlsdev_ops` member of the
:c:type:`struct net_device <net_device>`.
When TLS cryptographic connection state is installed on a ``ktls`` socket
(note that it is done twice, once for RX and once for TX direction,
and the two are completely independent), the kernel checks if the underlying
network device is offload-capable and attempts the offload. In case offload
fails the connection is handled entirely in software using the same mechanism
as if the offload was never tried.
Offload request is performed via the :c:member:`tls_dev_add` callback of
:c:type:`struct tlsdev_ops <tlsdev_ops>`:
.. code-block:: c
int (*tls_dev_add)(struct net_device *netdev, struct sock *sk,
enum tls_offload_ctx_dir direction,
struct tls_crypto_info *crypto_info,
u32 start_offload_tcp_sn);
``direction`` indicates whether the cryptographic information is for
the received or transmitted packets. Driver uses the ``sk`` parameter
to retrieve the connection 5-tuple and socket family (IPv4 vs IPv6).
Cryptographic information in ``crypto_info`` includes the key, iv, salt
as well as TLS record sequence number. ``start_offload_tcp_sn`` indicates
which TCP sequence number corresponds to the beginning of the record with
sequence number from ``crypto_info``. The driver can add its state
at the end of kernel structures (see :c:member:`driver_state` members
in ``include/net/tls.h``) to avoid additional allocations and pointer
dereferences.
TX
--
After TX state is installed, the stack guarantees that the first segment
of the stream will start exactly at the ``start_offload_tcp_sn`` sequence
number, simplifying TCP sequence number matching.
TX offload being fully initialized does not imply that all segments passing
through the driver and which belong to the offloaded socket will be after
the expected sequence number and will have kernel record information.
In particular, already encrypted data may have been queued to the socket
before installing the connection state in the kernel.
RX
--
In the RX direction, the local networking stack has little control over
segmentation, so the initial records' TCP sequence number may be anywhere
inside the segment.
In-order 정상 동작과 connection state
127-191Device는 connection과 방향마다 최소한 crypto secret(key, IV, salt), partial block/tag 같은 processing state, sequence·offset·length의 record metadata, expected TCP sequence를 유지합니다.
Record 길이와 segmentation은 보장되지 않습니다. Segment는 record 어느 지점에서 시작해 여러 record를 포함할 수 있습니다. In-order라면 device는 segmentation과 무관하게 crypto/authenticate하고 partial header, data block, authentication tag를 segment 사이 state로 유지해야 합니다. Record reassembly 없이도 별도 처리하며 전진할 수 있어야 합니다.
TX에서는 kernel이 authentication tag 공간을 예약하고 TLS header와 trailer field를 채워 record framing을 수행합니다. Retransmission과 device 도달 뒤 software fallback 부재 때문에 driver와 device 모두 expected TCP sequence를 유지합니다.
In-order TX segment는 driver가 connection identifier를 붙여 device에 넘깁니다. 5-tuple만으로 offload 대상 packet을 충분히 식별할 수 없다는 점에 주의합니다. Device는 sequence를 확인하고 record data를 encrypt·authenticate해 authentication tag와 TCP checksum을 올바른 값으로 바꿉니다.
RX에서는 host DMA 전에, embedded switching과 packet transformation 뒤 device가 L4 checksum을 검증하고 5-tuple(실제로 TCP 고정이므로 IP/port 4-tuple이면 충분)로 TLS connection을 찾습니다. Sequence가 예상과 맞으면 record delineation·decrypt·authenticate를 수행하고 framing은 건드리지 않아 stack이 decapsulation하게 합니다.
Driver는 성공한 RX segment의 `sk_buff.decrypted`를 설정합니다. Stack은 decrypted와 non-decrypted segment가 GRO나 socket layer에서 합쳐지지 않게 하고 partial decryption을 처리합니다.
Segmentation을 넘겨 유지해야 하는 최소 상태입니다.
Normal operation
================
At the minimum the device maintains the following state for each connection, in
each direction:
* crypto secrets (key, iv, salt)
* crypto processing state (partial blocks, partial authentication tag, etc.)
* record metadata (sequence number, processing offset and length)
* expected TCP sequence number
There are no guarantees on record length or record segmentation. In particular
segments may start at any point of a record and contain any number of records.
Assuming segments are received in order, the device should be able to perform
crypto operations and authentication regardless of segmentation. For this
to be possible, the device has to keep a small amount of segment-to-segment
state. This includes at least:
* partial headers (if a segment carried only a part of the TLS header)
* partial data block
* partial authentication tag (all data had been seen but part of the
authentication tag has to be written or read from the subsequent segment)
Record reassembly is not necessary for TLS offload. If the packets arrive
in order the device should be able to handle them separately and make
forward progress.
TX
--
The kernel stack performs record framing reserving space for the authentication
tag and populating all other TLS header and tailer fields.
Both the device and the driver maintain expected TCP sequence numbers
due to the possibility of retransmissions and the lack of software fallback
once the packet reaches the device.
For segments passed in order, the driver marks the packets with
a connection identifier (note that a 5-tuple lookup is insufficient to identify
packets requiring HW offload, see the :ref:`5tuple_problems` section)
and hands them to the device. The device identifies the packet as requiring
TLS handling and confirms the sequence number matches its expectation.
The device performs encryption and authentication of the record data.
It replaces the authentication tag and TCP checksum with correct values.
RX
--
Before a packet is DMAed to the host (but after NIC's embedded switching
and packet transformation functions) the device validates the Layer 4
checksum and performs a 5-tuple lookup to find any TLS connection the packet
may belong to (technically a 4-tuple
lookup is sufficient - IP addresses and TCP port numbers, as the protocol
is always TCP). If the packet is matched to a connection, the device confirms
if the TCP sequence number is the expected one and proceeds to TLS handling
(record delineation, decryption, authentication for each record in the packet).
The device leaves the record framing unmodified, the stack takes care of record
decapsulation. Device indicates successful handling of TLS offload in the
per-packet context (descriptor) passed to the host.
Upon reception of a TLS offloaded packet, the driver sets
the :c:member:`decrypted` mark in :c:type:`struct sk_buff <sk_buff>`
corresponding to the segment. Networking stack makes sure decrypted
and non-decrypted segments do not get coalesced (e.g. by GRO or socket layer)
and takes care of partial decryption.
TX resync와 crypto state rebuilding
192-232Packet drop이나 network reordering이 있으면 device가 TLS stream과 synchronization을 잃어 kernel TCP stack과 resync해야 합니다. Resync는 device table에 성공적으로 추가되어 `TLS_HW`인 connection에만 시도합니다. 설치 때 table이 가득 차 offload되지 않은 connection에는 발생하지 않으므로 request는 crypto state를 싣지 않습니다.
TX도 retransmission이나 local drop으로 out-of-sync가 될 수 있지만 network reorder는 없습니다. Out-of-order segment마다 driver가 crypto에 충분한 정보를 device에 제공하는 state rebuilding 방식이 있습니다.
대개 current segment 앞의 record 부분, TCP sequence와 TLS record number를 packet context로 넘깁니다. Device는 crypto state를 초기화하고 preceding data를 처리·버려 tag 삽입 상태를 만든 뒤 실제 packet을 처리합니다.
이후 새 crypto state와 sequence로 계속하거나 out-of-order가 retransmission이라고 보고 이전 stream state를 유지할 수 있습니다. 전자는 단순하고 retransmission detection이 필요 없어 비효율이 입증되기 전까지 권장됩니다.
Out-of-order packet context로 device state를 재구성합니다.
Resync handling
===============
In presence of packet drops or network packet reordering, the device may lose
synchronization with the TLS stream, and require a resync with the kernel's
TCP stack.
Note that resync is only attempted for connections which were successfully
added to the device table and are in TLS_HW mode. For example,
if the table was full when cryptographic state was installed in the kernel,
such connection will never get offloaded. Therefore the resync request
does not carry any cryptographic connection state.
TX
--
Segments transmitted from an offloaded socket can get out of sync
in similar ways to the receive side-retransmissions - local drops
are possible, though network reorders are not. There are currently
two mechanisms for dealing with out of order segments.
Crypto state rebuilding
~~~~~~~~~~~~~~~~~~~~~~~
Whenever an out of order segment is transmitted the driver provides
the device with enough information to perform cryptographic operations.
This means most likely that the part of the record preceding the current
segment has to be passed to the device as part of the packet context,
together with its TCP sequence number and TLS record number. The device
can then initialize its crypto state, process and discard the preceding
data (to be able to insert the authentication tag) and move onto handling
the actual packet.
In this mode depending on the implementation the driver can either ask
for a continuation with the crypto state and the new sequence number
(next expected segment is the one after the out of order one), or continue
with the previous stream state - assuming that the out of order segment
was just a retransmission. The former is simpler, and does not require
retransmission detection therefore it is the recommended method until
such time it is proven inefficient.
Next-record software fallback sync
233-261Out-of-order를 감지하면 driver는 kTLS software fallback에 segment encryption을 요청합니다. Sequence가 expected보다 낮으면 retransmission으로 보고 device state를 바꾸지 않습니다. 미래 sequence면 local drop일 수 있으므로 다음 record state로 device sync를 요청하고 software로 fallback합니다.
`tls_offload_tx_resync_request(sk, got_seq, exp_seq)`로 request합니다. 완료 전에는 다른 context에서 갱신될 expected TCP sequence에 driver가 접근하면 안 되며 `tls_offload_tx_resync_pending(sk)`로 완료 여부를 검사합니다.
다음 kTLS record push 때 stack은 먼저 TCP sequence와 TLS record number를 driver에 보내고, 최초 connection 추가 때처럼 새 record가 segment boundary에서 시작하게 보장합니다.
Past retransmission과 future gap 처리를 나눕니다.
Next record sync
~~~~~~~~~~~~~~~~
Whenever an out of order segment is detected the driver requests
that the ``ktls`` software fallback code encrypt it. If the segment's
sequence number is lower than expected the driver assumes retransmission
and doesn't change device state. If the segment is in the future, it
may imply a local drop, the driver asks the stack to sync the device
to the next record state and falls back to software.
Resync request is indicated with:
.. code-block:: c
void tls_offload_tx_resync_request(struct sock *sk, u32 got_seq, u32 exp_seq)
Until resync is complete driver should not access its expected TCP
sequence number (as it will be updated from a different context).
Following helper should be used to test if resync is complete:
.. code-block:: c
bool tls_offload_tx_resync_pending(struct sock *sk)
Next time ``ktls`` pushes a record it will first send its TCP sequence number
and TLS record number to the driver. Stack will also make sure that
the new record will start on a segment boundary (like it does when
the connection is initially added).
RX reorder와 record header 손실
262-304소량의 RX reorder는 record boundary를 복구할 수 있으면 full resync가 필요하지 않습니다. 정상 예에서 segment 1을 decrypt한 뒤 segment 2가 drop되고 3이 먼저 와도, segment 1의 record length로 segment 3 내부의 다음 record 시작을 압니다.
Segment 3의 이전 record 나머지는 segment 2 data가 없어 처리할 수 있으므로 untouched로 넘깁니다. 하지만 새 record의 authentication state와 partial block은 수집해 4와 5에서 decrypt를 계속합니다. 나중에 온 2는 expected window 밖이라 그대로 보내고, kTLS software fallback이 1·2·3에 걸친 record를 decrypt합니다. 두 segment를 device가 decrypt하지 못했어도 sync는 유지됩니다.
반대로 drop된 segment 2가 record header를 담고 다음 header가 이미 지나갔다면, device는 segment 2의 previous record length가 없어서 segment 4의 header 위치를 알 수 없고 stream sync를 잃습니다.
Record header 정보 보존 여부가 resync 필요성을 결정합니다.
RX
--
A small amount of RX reorder events may not require a full resynchronization.
In particular the device should not lose synchronization
when record boundary can be recovered:
.. kernel-figure:: tls-offload-reorder-good.svg
:alt: reorder of non-header segment
:align: center
Reorder of non-header segment
Green segments are successfully decrypted, blue ones are passed
as received on wire, red stripes mark start of new records.
In above case segment 1 is received and decrypted successfully.
Segment 2 was dropped so 3 arrives out of order. The device knows
the next record starts inside 3, based on record length in segment 1.
Segment 3 is passed untouched, because due to lack of data from segment 2
the remainder of the previous record inside segment 3 cannot be handled.
The device can, however, collect the authentication algorithm's state
and partial block from the new record in segment 3 and when 4 and 5
arrive continue decryption. Finally when 2 arrives it's completely outside
of expected window of the device so it's passed as is without special
handling. ``ktls`` software fallback handles the decryption of record
spanning segments 1, 2 and 3. The device did not get out of sync,
even though two segments did not get decrypted.
Kernel synchronization may be necessary if the lost segment contained
a record header and arrived after the next record header has already passed:
.. kernel-figure:: tls-offload-reorder-bad.svg
:alt: reorder of header segment
:align: center
Reorder of segment with a TLS header
In this example segment 2 gets dropped, and it contains a record header.
Device can only detect that segment 4 also contains a TLS header
if it knows the length of the previous record from segment 2. In this case
the device will lose synchronization with the stream.
Stream scan과 stack-driven resync
305-353Device가 sync를 잃고 stream이 expected sequence보다 최대 record 크기 이상 진행하면 알려진 header pattern을 scan합니다. TLS 1.2/1.3은 header SSL/TLS version의 `0x03 0x03`을 예로 들 수 있습니다. Pattern을 찾으면 추정 header의 length를 따라 예상 위치를 parse하고 invalid header가 나오면 scan을 다시 시작합니다.
Header가 맞으면 device는 kernel에 추정 위치가 실제 record 시작인지와 record sequence number를 묻습니다. Kernel이 확인해 number를 주면 device가 그 이후 세어 둔 record 수를 더하고 다음 segment boundary부터 decrypt를 재개합니다.
거짓 pattern에 붙잡히고 kernel의 응답을 받지 못할 수 있으며 negative confirmation은 없습니다. 구현이 주기적으로 scan을 restart할 수 있지만 확률이 낮아 필수로 보지는 않습니다. Confirmation request가 packet stream과 비동기라 kernel이 먼저 record를 처리할 수 있는 race도 주의해야 합니다.
Driver는 record가 더 이상 decrypt되지 않을 때 stack-driven resync를 요청할 수도 있습니다. 이 mode에서는 완전히 encrypted된 record 두 개를 받은 뒤 stack이 자동 schedule합니다. Socket이 drain되기를 기다려 next expected record number와 TCP sequence를 device에 알립니다.
계속 full-encrypted record가 오면 2, 4, 8, 16개에서 시작해 최대 128 record마다 exponential backoff로 다시 sync합니다.
Pattern scan confirmation과 stack retry 두 경로입니다.
Stream scan resynchronization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When the device gets out of sync and the stream reaches TCP sequence
numbers more than a max size record past the expected TCP sequence number,
the device starts scanning for a known header pattern. For example
for TLS 1.2 and TLS 1.3 subsequent bytes of value ``0x03 0x03`` occur
in the SSL/TLS version field of the header. Once pattern is matched
the device continues attempting parsing headers at expected locations
(based on the length fields at guessed locations).
Whenever the expected location does not contain a valid header the scan
is restarted.
When the header is matched the device sends a confirmation request
to the kernel, asking if the guessed location is correct (if a TLS record
really starts there), and which record sequence number the given header had.
The kernel confirms the guessed location was correct and tells the device
the record sequence number. Meanwhile, the device had been parsing
and counting all records since the just-confirmed one, it adds the number
of records it had seen to the record number provided by the kernel.
At this point the device is in sync and can resume decryption at next
segment boundary.
In a pathological case the device may latch onto a sequence of matching
headers and never hear back from the kernel (there is no negative
confirmation from the kernel). The implementation may choose to periodically
restart scan. Given how unlikely falsely-matching stream is, however,
periodic restart is not deemed necessary.
Special care has to be taken if the confirmation request is passed
asynchronously to the packet stream and record may get processed
by the kernel before the confirmation request.
Stack-driven resynchronization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The driver may also request the stack to perform resynchronization
whenever it sees the records are no longer getting decrypted.
If the connection is configured in this mode the stack automatically
schedules resynchronization after it has received two completely encrypted
records.
The stack waits for the socket to drain and informs the device about
the next expected record number and its TCP sequence number. If the
records continue to be received fully encrypted stack retries the
synchronization with an exponential back off (first after 2 encrypted
records, then after 4 records, after 8, after 16... up until every
128 records).
TX drop와 RX wire-original fallback
354-394TX packet이 선택한 TLS offload device와 다른 device로 redirect/reroute될 수 있습니다. Stack은 `sk_validate_xmit_skb` hook에 설치된 `tls_validate_xmit_skb`로 처리합니다. Offload는 fully ACK될 때까지 record 정보를 유지하므로 잘못된 device에 간 skb도 software fallback할 수 있습니다.
Device TX offload handling error는 packet drop으로 이어져야 합니다. Stack/device bug로 out-of-order packet이 device에 도달해 encrypt할 수 없다면 drop합니다.
RX device가 문제를 만나면 wire에서 받은 그대로 host stack에 넘겨야 합니다. Segment 안 record 하나라도 authentication에 실패하면 unmodified packet 전체를 software fallback에 보냅니다. In-place 수정이나 partial decrypt를 위한 segment split은 권장하지 않습니다. 모든 record를 성공 처리·인증했거나 original packet 전체를 복구해 넘겨야 합니다.
Linux stack에는 per-packet decrypt/auth error 보고 방법이 없으므로 error packet은 `decrypted` mark를 설정하지 않습니다. Checksum이 잘못된 packet도 TLS offload로 처리하지 않습니다.
방향에 따라 안전한 실패 결과가 다릅니다.
Error handling
==============
TX
--
Packets may be redirected or rerouted by the stack to a different
device than the selected TLS offload device. The stack will handle
such condition using the :c:func:`sk_validate_xmit_skb` helper
(TLS offload code installs :c:func:`tls_validate_xmit_skb` at this hook).
Offload maintains information about all records until the data is
fully acknowledged, so if skbs reach the wrong device they can be handled
by software fallback.
Any device TLS offload handling error on the transmission side must result
in the packet being dropped. For example if a packet got out of order
due to a bug in the stack or the device, reached the device and can't
be encrypted such packet must be dropped.
RX
--
If the device encounters any problems with TLS offload on the receive
side it should pass the packet to the host's networking stack as it was
received on the wire.
For example authentication failure for any record in the segment should
result in passing the unmodified packet to the software fallback. This means
packets should not be modified "in place". Splitting segments to handle partial
decryption is not advised. In other words either all records in the packet
had been handled successfully and authenticated or the packet has to be passed
to the host's stack as it was on the wire (recovering original packet in the
driver if device provides precise error is sufficient).
The Linux networking stack does not provide a way of reporting per-packet
decryption and authentication errors, packets with errors must simply not
have the :c:member:`decrypted` mark set.
A packet should also not be handled by the TLS offload if it contains
incorrect checksums.
성능 지표와 resource
395-421TLS offload 기본 성능 지표는 최대 connection 수, connection 설치 rate, 설치 latency, 전체 cryptographic performance입니다. TCP connection 하나가 양방향 TLS session을 필요로 하므로 방향별로 따로 보고할 수 있습니다.
Device 지원 connection 수는 `devlink resource` API로 공개할 수 있습니다. 전체 crypto 성능은 segment와 record size에 따라 달라질 수 있습니다. Device crypto subsystem overload가 non-offloaded stream 성능에 큰 영향을 주면 안 됩니다.
Performance metrics
===================
TLS offload can be characterized by the following basic metrics:
* max connection count
* connection installation rate
* connection installation latency
* total cryptographic performance
Note that each TCP connection requires a TLS session in both directions,
the performance may be reported treating each direction separately.
Max connection count
--------------------
The number of connections device can support can be exposed via
``devlink resource`` API.
Total cryptographic performance
-------------------------------
Offload performance may depend on segment and record size.
Overload of the cryptographic subsystem of the device should not have
significant performance impact on non-offloaded streams.
Driver TLS statistic
422-468Driver는 최소한 다음 TLS statistic을 보고해야 합니다.
Decrypt context와 resync 상태를 셉니다.
Encrypt context와 out-of-order drop을 셉니다.
Statistics
==========
Following minimum set of TLS-related statistics should be reported
by the driver:
* ``rx_tls_decrypted_packets`` - number of successfully decrypted RX packets
which were part of a TLS stream.
* ``rx_tls_decrypted_bytes`` - number of TLS payload bytes in RX packets
which were successfully decrypted.
* ``rx_tls_ctx`` - number of TLS RX HW offload contexts added to device for
decryption.
* ``rx_tls_del`` - number of TLS RX HW offload contexts deleted from device
(connection has finished).
* ``rx_tls_resync_req_pkt`` - number of received TLS packets with a resync
request.
* ``rx_tls_resync_req_start`` - number of times the TLS async resync request
was started.
* ``rx_tls_resync_req_end`` - number of times the TLS async resync request
properly ended with providing the HW tracked tcp-seq.
* ``rx_tls_resync_req_skip`` - number of times the TLS async resync request
procedure was started but not properly ended.
* ``rx_tls_resync_res_ok`` - number of times the TLS resync response call to
the driver was successfully handled.
* ``rx_tls_resync_res_skip`` - number of times the TLS resync response call to
the driver was terminated unsuccessfully.
* ``rx_tls_err`` - number of RX packets which were part of a TLS stream
but were not decrypted due to unexpected error in the state machine.
* ``tx_tls_encrypted_packets`` - number of TX packets passed to the device
for encryption of their TLS payload.
* ``tx_tls_encrypted_bytes`` - number of TLS payload bytes in TX packets
passed to the device for encryption.
* ``tx_tls_ctx`` - number of TLS TX HW offload contexts added to device for
encryption.
* ``tx_tls_ooo`` - number of TX packets which were part of a TLS stream
but did not arrive in the expected order.
* ``tx_tls_skip_no_sync_data`` - number of TX packets which were part of
a TLS stream and arrived out-of-order, but skipped the HW offload routine
and went to the regular transmit flow as they were retransmissions of the
connection handshake.
* ``tx_tls_drop_no_sync_data`` - number of TX packets which were part of
a TLS stream dropped, because they arrived out of order and associated
record could not be found.
* ``tx_tls_drop_bypass_req`` - number of TX packets which were part of a TLS
stream dropped, because they contain both data that has been encrypted by
software and data that expects hardware crypto offload.
5-tuple matching 제한
469-486Device는 receive packet을 socket 5-tuple로만 인식합니다. 현재 kTLS는 tunnel이나 virtual networking 같은 software interface를 지나는 socket을 offload하지 않습니다.
그러나 BPF를 포함한 많은 stack packet transformation은 intermediate software device 없이 수행되므로 device의 5-tuple match가 일관되게 실패할 수 있습니다. 이 경우에도 TX encryption offload는 가능해야 하고 RX는 software decryption으로 깨끗하게 fallback해야 합니다.
Notable corner cases, exceptions and additional requirements
============================================================
.. _5tuple_problems:
5-tuple matching limitations
----------------------------
The device can only recognize received packets based on the 5-tuple
of the socket. Current ``ktls`` implementation will not offload sockets
routed through software interfaces such as those used for tunneling
or virtual networking. However, many packet transformations performed
by the networking stack (most notably any BPF logic) do not require
any intermediate software device, therefore a 5-tuple match may
consistently miss at the device level. In such cases the device
should still be able to perform TX offload (encryption) and should
fallback cleanly to software decryption (RX).
Reorder, transparency와 drop 제한
487-524NIC에 추가 processing을 넣어 pure ACK와 data segment 등이 TX/RX에서 reorder되면 안 됩니다. Device는 연속 TCP segment를 올바른 순서로 재배치할 수 있지만 추가 buffering은 허용되지 않습니다.
Offloaded kTLS socket은 표준 TCP stack feature를 투명하게 지원해야 하며 device TLS offload enable 전후 wire packet이 달라지면 안 됩니다.
TLS offload 단순화를 위해 device는 packet header를 수정하지 않아야 하고, 필요한 범위를 넘는 header에 의존하지 않아야 합니다.
Packet drop은 catastrophic system error에서만 허용되며 정상 동작의 corner case error handling mechanism으로 사용하면 안 됩니다. TCP retransmission에 기대어 corner case를 처리하는 것도 허용되지 않습니다.
Out of order
------------
Introducing extra processing in NICs should not cause packets to be
transmitted or received out of order, for example pure ACK packets
should not be reordered with respect to data segments.
Ingress reorder
---------------
A device is permitted to perform packet reordering for consecutive
TCP segments (i.e. placing packets in the correct order) but any form
of additional buffering is disallowed.
Coexistence with standard networking offload features
-----------------------------------------------------
Offloaded ``ktls`` sockets should support standard TCP stack features
transparently. Enabling device TLS offload should not cause any difference
in packets as seen on the wire.
Transport layer transparency
----------------------------
For the purpose of simplifying TLS offload, the device should not modify any
packet headers.
The device should not depend on any packet headers beyond what is strictly
necessary for TLS offload.
Segment drops
-------------
Dropping packets is acceptable only in the event of catastrophic
system errors and should never be used as an error handling mechanism
in cases arising from normal operation. In other words, reliance
on TCP retransmissions to handle corner cases is not acceptable.
TLS feature flag와 checksum dependency
525-540Driver는 TLS device feature flag 변경을 무시하고 core kTLS code가 처리하게 해야 합니다. Flag는 새 TLS connection offload 추가만 제어하며 clear 뒤에도 기존 connection은 active입니다.
Checksum calculation offload가 없는 device에는 TLS encryption을 offload할 수 없습니다. 따라서 TLS TX feature는 TX checksum offload가 필요하며 TX checksum을 끄면 TLS TX도 clear됩니다. 다만 기존 connection에는 영향을 주지 않아야 하고 driver는 그 connection의 checksum 계산이 깨지지 않게 해야 합니다.
Device TLS RX decryption도 `RXCSUM`을 전제로 합니다. 사용자가 RX checksum offload를 원하지 않으면 TLS RX device feature도 disable됩니다.
새 connection과 기존 connection의 동작을 구분합니다.
TLS device features
-------------------
Drivers should ignore the changes to the TLS device feature flags.
These flags will be acted upon accordingly by the core ``ktls`` code.
TLS device feature flags only control adding of new TLS connection
offloads, old connections will remain active after flags are cleared.
TLS encryption cannot be offloaded to devices without checksum calculation
offload. Hence, TLS TX device feature flag requires TX csum offload being set.
Disabling the latter implies clearing the former. Disabling TX checksum offload
should not affect old connections, and drivers should make sure checksum
calculation does not break for them.
Similarly, device-offloaded TLS decryption implies doing RXCSUM. If the user
does not want to enable RX csum offload, TLS RX device feature is disabled
as well.
요약·해설
tls-offload.rst:1-540Packet-based `TLS_HW` offload는 Linux TCP·record framing을 유지하면서 NIC가 crypto만 수행합니다. Driver와 device는 방향별 secret·record·expected TCP sequence를 유지하고 reorder나 drop 뒤 software fallback 또는 resync로 stream 상태를 복구합니다.
TX crypto error는 drop해야 하지만 RX 오류는 wire-original packet 전체를 `decrypted` mark 없이 software에 넘겨야 합니다. Feature flag는 새 connection만 제어하고 checksum offload dependency와 기존 connection 지속성을 보존해야 합니다.
Connection 설치부터 정상 crypto, resync와 fallback을 연결합니다.