diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-02 12:17:24 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-02 12:17:24 -0700 |
| commit | 3f1fe48a36b0b6722dc3fd421d93512bac138e9a (patch) | |
| tree | b767d7f6e26bc64334d3f14f8422d187239dc45d /Documentation/networking/xfrm | |
| download | linux-stable-3f1fe48a36b0b6722dc3fd421d93512bac138e9a.tar.gz linux-stable-3f1fe48a36b0b6722dc3fd421d93512bac138e9a.zip | |
Merge tag 'io_uring-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linuxgrafted
Pull io_uring fixes from Jens Axboe:
- Fix a task_work add use-after-free with SQPOLL.
The sqpoll thread could pop and complete the last request while
io_req_normal_work_add() was still looking at them after the mpscq
push.
Use the same approach as DEFER_TASKRUN to protect from that, holding
an RCU read lock across the add, and have exit wait for an RCU grace
period for SQPOLL rings as well.
- CQE32 ring fixes: correct the free entry check for 32b CQEs, zero the
big_cqe for aux CQEs, and only post the dummy skip CQE on CQE_MIXED
rings
- Mark the source filter table as COW when cloning bpf filters, so
registering another filter on the source doesn't modify the shared
table in place
- Initialize the task context before running the BPF loop
- Requeue zcrx multishot receives stopped by a local resource
- End a TX_TIMESTAMP multishot cmd when the CQ is full (lollipopkit)
* tag 'io_uring-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
io_uring: fix task_work add use-after-free with SQPOLL
io_uring/cmd_net: end TX_TIMESTAMP multishot when the CQ is full
io_uring/zcrx: requeue multishot receives stopped by a local resource
io_uring: initialize task context before running the BPF loop
io_uring: zero big_cqe for aux CQEs on CQE32 rings
io_uring: fix free entry check for 32b CQEs on CQE32 rings
io_uring: only post the dummy skip CQE on CQE_MIXED rings
io_uring/bpf_filter: mark source as COW when cloning filters
Diffstat (limited to 'Documentation/networking/xfrm')
| -rw-r--r-- | Documentation/networking/xfrm/index.rst | 14 | ||||
| -rw-r--r-- | Documentation/networking/xfrm/xfrm_device.rst | 206 | ||||
| -rw-r--r-- | Documentation/networking/xfrm/xfrm_migrate_state.rst | 274 | ||||
| -rw-r--r-- | Documentation/networking/xfrm/xfrm_proc.rst | 119 | ||||
| -rw-r--r-- | Documentation/networking/xfrm/xfrm_sync.rst | 192 | ||||
| -rw-r--r-- | Documentation/networking/xfrm/xfrm_sysctl.rst | 11 |
6 files changed, 816 insertions, 0 deletions
diff --git a/Documentation/networking/xfrm/index.rst b/Documentation/networking/xfrm/index.rst new file mode 100644 index 000000000..90191848f --- /dev/null +++ b/Documentation/networking/xfrm/index.rst @@ -0,0 +1,14 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============== +XFRM Framework +============== + +.. toctree:: + :maxdepth: 2 + + xfrm_device + xfrm_proc + xfrm_migrate_state + xfrm_sync + xfrm_sysctl diff --git a/Documentation/networking/xfrm/xfrm_device.rst b/Documentation/networking/xfrm/xfrm_device.rst new file mode 100644 index 000000000..b0d85a5f5 --- /dev/null +++ b/Documentation/networking/xfrm/xfrm_device.rst @@ -0,0 +1,206 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. _xfrm_device: + +=============================================== +XFRM device - offloading the IPsec computations +=============================================== + +Shannon Nelson <shannon.nelson@oracle.com> +Leon Romanovsky <leonro@nvidia.com> + + +Overview +======== + +IPsec is a useful feature for securing network traffic, but the +computational cost is high: a 10Gbps link can easily be brought down +to under 1Gbps, depending on the traffic and link configuration. +Luckily, there are NICs that offer a hardware based IPsec offload which +can radically increase throughput and decrease CPU utilization. The XFRM +Device interface allows NIC drivers to offer to the stack access to the +hardware offload. + +Right now, there are two types of hardware offload that kernel supports: + + * IPsec crypto offload: + + * NIC performs encrypt/decrypt + * Kernel does everything else + + * IPsec packet offload: + + * NIC performs encrypt/decrypt + * NIC does encapsulation + * Kernel and NIC have SA and policy in-sync + * NIC handles the SA and policies states + * The Kernel talks to the keymanager + +Userland access to the offload is typically through a system such as +libreswan or KAME/raccoon, but the iproute2 'ip xfrm' command set can +be handy when experimenting. An example command might look something +like this for crypto offload:: + + ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport \ + reqid 0x07 replay-window 32 \ + aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \ + sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp \ + offload dev eth4 dir in + +and for packet offload:: + + ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport \ + reqid 0x07 replay-window 32 \ + aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \ + sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp \ + offload packet dev eth4 dir in + + ip x p add src 14.0.0.70 dst 14.0.0.52 offload packet dev eth4 dir in + tmpl src 14.0.0.70 dst 14.0.0.52 proto esp reqid 10000 mode transport + +Yes, that's ugly, but that's what shell scripts and/or libreswan are for. + + + +Callbacks to implement +====================== + +:: + + /* from include/linux/netdevice.h */ + struct xfrmdev_ops { + /* Crypto and Packet offload callbacks */ + int (*xdo_dev_state_add)(struct net_device *dev, + struct xfrm_state *x, + struct netlink_ext_ack *extack); + void (*xdo_dev_state_delete)(struct net_device *dev, + struct xfrm_state *x); + void (*xdo_dev_state_free)(struct net_device *dev, + struct xfrm_state *x); + bool (*xdo_dev_offload_ok) (struct sk_buff *skb, + struct xfrm_state *x); + void (*xdo_dev_state_advance_esn) (struct xfrm_state *x); + void (*xdo_dev_state_update_stats) (struct xfrm_state *x); + + /* Solely packet offload callbacks */ + int (*xdo_dev_policy_add) (struct xfrm_policy *x, struct netlink_ext_ack *extack); + void (*xdo_dev_policy_delete) (struct xfrm_policy *x); + void (*xdo_dev_policy_free) (struct xfrm_policy *x); + }; + +The NIC driver offering ipsec offload will need to implement callbacks +relevant to supported offload to make the offload available to the network +stack's XFRM subsystem. Additionally, the feature bits NETIF_F_HW_ESP and +NETIF_F_HW_ESP_TX_CSUM will signal the availability of the offload. + + + +Flow +==== + +At probe time and before the call to register_netdev(), the driver should +set up local data structures and XFRM callbacks, and set the feature bits. +The XFRM code's listener will finish the setup on NETDEV_REGISTER. + +:: + + adapter->netdev->xfrmdev_ops = &ixgbe_xfrmdev_ops; + adapter->netdev->features |= NETIF_F_HW_ESP; + adapter->netdev->hw_enc_features |= NETIF_F_HW_ESP; + +When new SAs are set up with a request for "offload" feature, the +driver's xdo_dev_state_add() will be given the new SA to be offloaded +and an indication of whether it is for Rx or Tx. The driver should + + - verify the algorithm is supported for offloads + - store the SA information (key, salt, target-ip, protocol, etc) + - enable the HW offload of the SA + - return status value: + + =========== =================================== + 0 success + -EOPNETSUPP offload not supported, try SW IPsec, + not applicable for packet offload mode + other fail the request + =========== =================================== + +The driver can also set an offload_handle in the SA, an opaque void pointer +that can be used to convey context into the fast-path offload requests:: + + xs->xso.offload_handle = context; + + +When the network stack is preparing an IPsec packet for an SA that has +been setup for offload, it first calls into xdo_dev_offload_ok() with +the skb and the intended offload state to ask the driver if the offload +will serviceable. This can check the packet information to be sure the +offload can be supported (e.g. IPv4 or IPv6, no IPv4 options, etc) and +return true or false to signify its support. In case driver doesn't implement +this callback, the stack provides reasonable defaults. + +Crypto offload mode: +When ready to send, the driver needs to inspect the Tx packet for the +offload information, including the opaque context, and set up the packet +send accordingly:: + + xs = xfrm_input_state(skb); + context = xs->xso.offload_handle; + set up HW for send + +The stack has already inserted the appropriate IPsec headers in the +packet data, the offload just needs to do the encryption and fix up the +header values. + + +When a packet is received and the HW has indicated that it offloaded a +decryption, the driver needs to add a reference to the decoded SA into +the packet's skb. At this point the data should be decrypted but the +IPsec headers are still in the packet data; they are removed later up +the stack in xfrm_input(). + +1. Find and hold the SA that was used to the Rx skb:: + + /* get spi, protocol, and destination IP from packet headers */ + xs = find xs from (spi, protocol, dest_IP) + xfrm_state_hold(xs); + +2. Store the state information into the skb:: + + sp = secpath_set(skb); + if (!sp) return; + sp->xvec[sp->len++] = xs; + sp->olen++; + +3. Indicate the success and/or error status of the offload:: + + xo = xfrm_offload(skb); + xo->flags = CRYPTO_DONE; + xo->status = crypto_status; + +4. Hand the packet to napi_gro_receive() as usual. + +In ESN mode, xdo_dev_state_advance_esn() is called from +xfrm_replay_advance_esn() for RX, and xfrm_replay_overflow_offload_esn for TX. +Driver will check packet seq number and update HW ESN state machine if needed. + +Packet offload mode: +HW adds and deletes XFRM headers. So in RX path, XFRM stack is bypassed if HW +reported success. In TX path, the packet lefts kernel without extra header +and not encrypted, the HW is responsible to perform it. + +When the SA is removed by the user, the driver's xdo_dev_state_delete() +and xdo_dev_policy_delete() are asked to disable the offload. Later, +xdo_dev_state_free() and xdo_dev_policy_free() are called from a garbage +collection routine after all reference counts to the state and policy +have been removed and any remaining resources can be cleared for the +offload state. How these are used by the driver will depend on specific +hardware needs. + +As a netdev is set to DOWN the XFRM stack's netdev listener will call +xdo_dev_state_delete(), xdo_dev_policy_delete(), xdo_dev_state_free() and +xdo_dev_policy_free() on any remaining offloaded states. + +Outcome of HW handling packets, the XFRM core can't count hard, soft limits. +The HW/driver are responsible to perform it and provide accurate data when +xdo_dev_state_update_stats() is called. In case of one of these limits +occuried, the driver needs to call to xfrm_state_check_expire() to make sure +that XFRM performs rekeying sequence. diff --git a/Documentation/networking/xfrm/xfrm_migrate_state.rst b/Documentation/networking/xfrm/xfrm_migrate_state.rst new file mode 100644 index 000000000..9d53cb22b --- /dev/null +++ b/Documentation/networking/xfrm/xfrm_migrate_state.rst @@ -0,0 +1,274 @@ +.. SPDX-License-Identifier: GPL-2.0 + +===================== +XFRM SA Migrate State +===================== + +Overview +======== + +``XFRM_MSG_MIGRATE_STATE`` migrates a single SA, looked up using SPI and +mark, without involving policies. Unlike ``XFRM_MSG_MIGRATE``, which couples +SA and policy migration and allows migrating multiple SAs in one call, this +interface identifies the SA unambiguously via SPI and supports changing +the reqid, addresses, encapsulation, selector, and offload. + +Because IKE daemons can manage policies independently of +the kernel, this interface allows precise per-SA migration without +requiring policy involvement. Optional netlink attributes follow an +omit-to-inherit model: omitting an attribute preserves the value from +the old SA. The ``flags`` field controls two exceptions: hardware offload +is inherited by default and can be suppressed with +``XFRM_MIGRATE_STATE_CLEAR_OFFLOAD`` or overridden with ``XFRMA_OFFLOAD_DEV``; +the new selector is taken from ``new_sel`` by default and can instead be +derived from the new addresses with ``XFRM_MIGRATE_STATE_UPDATE_H2H_SEL``. + +SA Identification +================= + +The struct is defined in ``include/uapi/linux/xfrm.h``. The SA is looked +up using ``xfrm_state_lookup()`` with ``id.spi``, +``id.daddr``, ``id.proto``, ``id.family``, and +``old_mark.v & old_mark.m`` as the mark key:: + + struct xfrm_user_migrate_state { + struct xfrm_usersa_id id; /* spi, daddr, proto, family */ + xfrm_address_t new_daddr; + xfrm_address_t new_saddr; + struct xfrm_mark old_mark; /* SA lookup: key = v & m */ + struct xfrm_selector new_sel; /* new selector (see Flags) */ + __u32 new_reqid; + __u32 flags; /* XFRM_MIGRATE_STATE_* */ + __u16 new_family; + __u16 reserved; /* must be zero */ + }; + +The ``reserved`` field must be set to zero; the kernel rejects any +other value with ``-EINVAL``. + +Supported Attributes +==================== + +The following fields in ``xfrm_user_migrate_state`` are always explicit +and are not inherited from the existing SA. Passing zero is not equivalent +to "keep unchanged" — zero is used as-is: + +- ``new_daddr`` - new destination address +- ``new_saddr`` - new source address +- ``new_family`` - new address family +- ``new_reqid`` - new reqid (0 = no reqid) +- ``new_sel`` - new selector; used when ``XFRM_MIGRATE_STATE_UPDATE_H2H_SEL`` is + not set (see `Flags`_ below) +- ``flags`` - bitmask of ``XFRM_MIGRATE_STATE_*`` flags (see `Flags`_ below) + +The following netlink attributes are also accepted. Omitting an attribute +inherits the value from the existing SA (omit-to-inherit). + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Attribute + - Description + * - ``XFRMA_MARK`` + - Mark on the migrated SA (``struct xfrm_mark``). Absent inherits + ``old_mark``. To use no mark on the new SA, send ``XFRMA_MARK`` + with ``{0, 0}``. + * - ``XFRMA_ENCAP`` + - UDP encapsulation template; only ``UDP_ENCAP_ESPINUDP`` is supported. + Set ``encap_type=0`` to remove encap. + * - ``XFRMA_OFFLOAD_DEV`` + - Hardware offload configuration (``struct xfrm_user_offload``). Absent + copies offload from the existing SA. When + ``XFRM_MIGRATE_STATE_CLEAR_OFFLOAD`` is set in ``flags``, the new SA has + no offload; this flag is mutually exclusive with ``XFRMA_OFFLOAD_DEV`` + and sending both returns ``-EINVAL``. + * - ``XFRMA_SET_MARK`` + - Output mark on the migrated SA; pair with ``XFRMA_SET_MARK_MASK``. + Send 0 to clear. + * - ``XFRMA_NAT_KEEPALIVE_INTERVAL`` + - NAT keepalive interval in seconds. Requires encap. Send 0 to clear. + Automatically cleared when encap is removed; setting a non-zero + value without encap returns ``-EINVAL``. + * - ``XFRMA_MTIMER_THRESH`` + - Mapping maxage threshold. Only valid on input SAs; setting on an + output SA returns ``-EINVAL``. Requires encap. Send 0 to clear. + Automatically cleared when encap is removed; setting a non-zero + value without encap returns ``-EINVAL``. + +The following SA properties are immutable and cannot be changed via +``XFRM_MSG_MIGRATE_STATE``: algorithms (``XFRMA_ALG_*``), replay state, +direction (``XFRMA_SA_DIR``), and security context (``XFRMA_SEC_CTX``). + +Flags +===== + +The ``flags`` field in ``xfrm_user_migrate_state`` controls optional +migration behaviour. Unknown flag bits are rejected with ``-EINVAL``; the +extended ACK message identifies the unrecognised bits (e.g. ``"Unknown flags: +0x4"``). Userspace can use ``XFRM_MIGRATE_STATE_KNOWN_FLAGS`` (defined in +``<linux/xfrm.h>``) to validate flags before sending; note that this constant +reflects the flags known to the header version userspace was compiled against, +which may differ from what the running kernel accepts. + +.. list-table:: + :widths: 40 60 + :header-rows: 1 + + * - Flag + - Description + * - ``XFRM_MIGRATE_STATE_CLEAR_OFFLOAD`` + - When set, the new SA has no hardware offload even when + ``XFRMA_OFFLOAD_DEV`` is absent. Without this flag, omitting + ``XFRMA_OFFLOAD_DEV`` copies the existing offload to the new SA. + Mutually exclusive with ``XFRMA_OFFLOAD_DEV``; sending both + returns ``-EINVAL``. + * - ``XFRM_MIGRATE_STATE_UPDATE_H2H_SEL`` + - When set, the kernel validates that the existing SA selector is a + single-host entry matching the SA addresses (``prefixlen_s == + prefixlen_d`` equal to 32 for IPv4 or 128 for IPv6, and addresses + matching ``id.daddr`` and ``props.saddr``). If the check passes, + the new selector is derived from ``new_daddr`` and ``new_saddr`` + with the single-host mask for ``new_family``. A mismatch returns + ``-EINVAL``. When this flag is not set, ``new_sel`` is used as-is + for the migrated SA. + +Migration Steps +=============== + +Outgoing SA +----------- + +To prevent cleartext traffic leaks, install a block policy before +migrating: + +#. Install a block policy to drop traffic on the affected selector. +#. Remove the old policy. +#. Call ``XFRM_MSG_MIGRATE_STATE`` for each SA. +#. Reinstall the policies. +#. Remove the block policy. + +If AES-GCM is in use, the block policy also prevents IV reuse during +the migration window. For other AEADs this step is not required for +IV safety, but skipping it allows a brief cleartext window. + +Incoming SA +----------- + +No block policy is needed. ``XFRM_MSG_MIGRATE_STATE`` atomically +transfers the sequence number and replay window from the old SA to +the new SA, so the new SA continues replay protection without a gap. +Call ``XFRM_MSG_MIGRATE_STATE`` for each SA directly. + +When accepting incoming traffic, be liberal during the migration +window: packets sent by the remote peer before it completed its own +migration may arrive out of order or slightly late. Dropping them +unnecessarily causes packet loss. A generous replay window reduces +the impact of reordering during migration. + +Block Policy and IV Safety +-------------------------- + +AES-GCM IV uniqueness is critical: reusing a (key, IV) pair allows +an attacker to recover the authentication subkey and forge +authentication tags, breaking both confidentiality and integrity. +This concern applies to outgoing SAs only — the remote peer controls +IV generation on incoming traffic. + +``XFRM_MSG_MIGRATE_STATE`` atomically copies the sequence number and +replay window from the old SA to the new SA and deletes the old SA. +The block policy serves two purposes: it prevents cleartext traffic +leaks during the migration window, and for AES-GCM it prevents IV +reuse by ensuring no outgoing packets are sent under the same key. +The atomic copy of the sequence number and replay window complements +this — together they eliminate both risks during migration. +The atomic copy also serves incoming SAs, ensuring replay protection +continues without a gap across the migration. + +Feature Detection +================= + +Userspace can probe for kernel support by sending a minimal +``XFRM_MSG_MIGRATE_STATE`` message with a non-zero non-existent SPI: + +- ``-EINVAL``: kernel predates ``XFRM_MSG_MIGRATE_STATE``; message type + is out of range +- ``-ENOPROTOOPT``: message type is known but ``CONFIG_XFRM_MIGRATE`` + is not enabled +- ``-ESRCH``: supported (SPI not found) + +Userspace Notification on Success +================================= + +On successful migration the kernel multicasts an +``XFRM_MSG_MIGRATE_STATE`` message to the ``XFRMNLGRP_MIGRATE`` group. +The fixed header is ``struct xfrm_user_migrate_state`` copied from the +request, followed by the same set of netlink attributes that are +accepted as input, with the differences noted below. + +Differences from the request +----------------------------- + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Field / Attribute + - Difference + * - ``new_sel`` + - Contains the actual selector of the newly installed SA, not the + ``new_sel`` from the request. When + ``XFRM_MIGRATE_STATE_UPDATE_H2H_SEL`` is set the kernel derives the + selector from ``new_daddr`` / ``new_saddr``; the caller's + ``new_sel`` field is ignored in that case. The notification + always carries the real selector of the new SA. + * - ``XFRMA_SA_DIR`` + - Present in the notification (set from the direction of the new + SA) but **not accepted as input** — direction is immutable. + * - ``flags`` + - Echoed back as-is. ``XFRM_MIGRATE_STATE_CLEAR_OFFLOAD`` and + ``XFRM_MIGRATE_STATE_UPDATE_H2H_SEL`` describe the request that was + made, not a property of the resulting SA. + +Attributes in the notification +------------------------------- + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Attribute + - Description + * - ``XFRMA_ENCAP`` + - UDP encapsulation template, if configured on the new SA. + * - ``XFRMA_OFFLOAD_DEV`` + - Hardware offload configuration, if active on the new SA. + * - ``XFRMA_MARK`` + - Mark on the new SA, if set. + * - ``XFRMA_SET_MARK`` + - Output mark on the new SA, if set. + * - ``XFRMA_SET_MARK_MASK`` + - Output mark mask, present together with ``XFRMA_SET_MARK``. + * - ``XFRMA_MTIMER_THRESH`` + - Mapping maxage threshold, if non-zero. + * - ``XFRMA_NAT_KEEPALIVE_INTERVAL`` + - NAT keepalive interval, if non-zero. + * - ``XFRMA_SA_DIR`` + - Direction of the new SA. + +Error Handling +============== + +If the target SA tuple (new daddr, SPI, proto, new family) is already +occupied, the operation returns ``-EEXIST`` before the migration begins. +The old SA remains intact and the operation is safe to retry after +resolving the conflict. + +If the target SA is deleted before the migration completes, the operation +returns ``-ESRCH``. No new SA is installed. Userspace should verify the +current SA state before retrying. + +If the multicast notification (``XFRMNLGRP_MIGRATE``) fails to send, +the migration itself has already completed successfully and the new SA +is installed. The operation returns success, 0, with an extack warning, +but listeners will not receive the migration event. diff --git a/Documentation/networking/xfrm/xfrm_proc.rst b/Documentation/networking/xfrm/xfrm_proc.rst new file mode 100644 index 000000000..973d1571a --- /dev/null +++ b/Documentation/networking/xfrm/xfrm_proc.rst @@ -0,0 +1,119 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================================== +XFRM proc - /proc/net/xfrm_* files +================================== + +Masahide NAKAMURA <nakam@linux-ipv6.org> + + +Transformation Statistics +------------------------- + +The xfrm_proc code is a set of statistics showing numbers of packets +dropped by the transformation code and why. These counters are defined +as part of the linux private MIB. These counters can be viewed in +/proc/net/xfrm_stat. + + +Inbound errors +~~~~~~~~~~~~~~ + +XfrmInError: + All errors which is not matched others + +XfrmInBufferError: + No buffer is left + +XfrmInHdrError: + Header error + +XfrmInNoStates: + No state is found + i.e. Either inbound SPI, address, or IPsec protocol at SA is wrong + +XfrmInStateProtoError: + Transformation protocol specific error + e.g. SA key is wrong + +XfrmInStateModeError: + Transformation mode specific error + +XfrmInStateSeqError: + Sequence error + i.e. Sequence number is out of window + +XfrmInStateExpired: + State is expired + +XfrmInStateMismatch: + State has mismatch option + e.g. UDP encapsulation type is mismatch + +XfrmInStateInvalid: + State is invalid + +XfrmInTmplMismatch: + No matching template for states + e.g. Inbound SAs are correct but SP rule is wrong + +XfrmInNoPols: + No policy is found for states + e.g. Inbound SAs are correct but no SP is found + +XfrmInPolBlock: + Policy discards + +XfrmInPolError: + Policy error + +XfrmAcquireError: + State hasn't been fully acquired before use + +XfrmFwdHdrError: + Forward routing of a packet is not allowed + +XfrmInStateDirError: + State direction mismatch (lookup found an output state on the input path, expected input or no direction) + +Outbound errors +~~~~~~~~~~~~~~~ +XfrmOutError: + All errors which is not matched others + +XfrmOutBundleGenError: + Bundle generation error + +XfrmOutBundleCheckError: + Bundle check error + +XfrmOutNoStates: + No state is found + +XfrmOutStateProtoError: + Transformation protocol specific error + +XfrmOutStateModeError: + Transformation mode specific error + +XfrmOutStateSeqError: + Sequence error + i.e. Sequence number overflow + +XfrmOutStateExpired: + State is expired + +XfrmOutPolBlock: + Policy discards + +XfrmOutPolDead: + Policy is dead + +XfrmOutPolError: + Policy error + +XfrmOutStateInvalid: + State is invalid, perhaps expired + +XfrmOutStateDirError: + State direction mismatch (lookup found an input state on the output path, expected output or no direction) diff --git a/Documentation/networking/xfrm/xfrm_sync.rst b/Documentation/networking/xfrm/xfrm_sync.rst new file mode 100644 index 000000000..dfc2ec0df --- /dev/null +++ b/Documentation/networking/xfrm/xfrm_sync.rst @@ -0,0 +1,192 @@ +.. SPDX-License-Identifier: GPL-2.0 + +========= +XFRM sync +========= + +The sync patches work is based on initial patches from +Krisztian <hidden@balabit.hu> and others and additional patches +from Jamal <hadi@cyberus.ca>. + +The end goal for syncing is to be able to insert attributes + generate +events so that the SA can be safely moved from one machine to another +for HA purposes. +The idea is to synchronize the SA so that the takeover machine can do +the processing of the SA as accurate as possible if it has access to it. + +We already have the ability to generate SA add/del/upd events. +These patches add ability to sync and have accurate lifetime byte (to +ensure proper decay of SAs) and replay counters to avoid replay attacks +with as minimal loss at failover time. +This way a backup stays as closely up-to-date as an active member. + +Because the above items change for every packet the SA receives, +it is possible for a lot of the events to be generated. +For this reason, we also add a nagle-like algorithm to restrict +the events. i.e we are going to set thresholds to say "let me +know if the replay sequence threshold is reached or 10 secs have passed" +These thresholds are set system-wide via sysctls or can be updated +per SA. + +The identified items that need to be synchronized are: +- the lifetime byte counter +note that: lifetime time limit is not important if you assume the failover +machine is known ahead of time since the decay of the time countdown +is not driven by packet arrival. +- the replay sequence for both inbound and outbound + +1) Message Structure +-------------------- + +nlmsghdr:aevent_id:optional-TLVs. + +The netlink message types are: + +XFRM_MSG_NEWAE and XFRM_MSG_GETAE. + +A XFRM_MSG_GETAE does not have TLVs. + +A XFRM_MSG_NEWAE will have at least two TLVs (as is +discussed further below). + +aevent_id structure looks like:: + + struct xfrm_aevent_id { + struct xfrm_usersa_id sa_id; + xfrm_address_t saddr; + __u32 flags; + __u32 reqid; + }; + +The unique SA is identified by the combination of xfrm_usersa_id, +reqid and saddr. + +flags are used to indicate different things. The possible +flags are:: + + XFRM_AE_RTHR=1, /* replay threshold*/ + XFRM_AE_RVAL=2, /* replay value */ + XFRM_AE_LVAL=4, /* lifetime value */ + XFRM_AE_ETHR=8, /* expiry timer threshold */ + XFRM_AE_CR=16, /* Event cause is replay update */ + XFRM_AE_CE=32, /* Event cause is timer expiry */ + XFRM_AE_CU=64, /* Event cause is policy update */ + +How these flags are used is dependent on the direction of the +message (kernel<->user) as well the cause (config, query or event). +This is described below in the different messages. + +The pid will be set appropriately in netlink to recognize direction +(0 to the kernel and pid = processid that created the event +when going from kernel to user space) + +A program needs to subscribe to multicast group XFRMNLGRP_AEVENTS +to get notified of these events. + +2) TLVS reflect the different parameters +---------------------------------------- + +a) byte value (XFRMA_LTIME_VAL) + + This TLV carries the running/current counter for byte lifetime since + last event. + +b) replay value (XFRMA_REPLAY_VAL) + + This TLV carries the running/current counter for replay sequence since + last event. + +c) replay threshold (XFRMA_REPLAY_THRESH) + + This TLV carries the threshold being used by the kernel to trigger events + when the replay sequence is exceeded. + +d) expiry timer (XFRMA_ETIMER_THRESH) + + This is a timer value in milliseconds which is used as the nagle + value to rate limit the events. + +3) Default configurations for the parameters +-------------------------------------------- + +By default these events should be turned off unless there is +at least one listener registered to listen to the multicast +group XFRMNLGRP_AEVENTS. + +Programs installing SAs will need to specify the two thresholds, however, +in order to not change existing applications such as racoon +we also provide default threshold values for these different parameters +in case they are not specified. + +the two sysctls/proc entries are: + +a) /proc/sys/net/core/sysctl_xfrm_aevent_etime + + Used to provide default values for the XFRMA_ETIMER_THRESH in incremental + units of time of 100ms. The default is 10 (1 second) + +b) /proc/sys/net/core/sysctl_xfrm_aevent_rseqth + + Used to provide default values for XFRMA_REPLAY_THRESH parameter + in incremental packet count. The default is two packets. + +4) Message types +---------------- + +a) XFRM_MSG_GETAE issued by user-->kernel. + XFRM_MSG_GETAE does not carry any TLVs. + + The response is a XFRM_MSG_NEWAE which is formatted based on what + XFRM_MSG_GETAE queried for. + + The response will always have XFRMA_LTIME_VAL and XFRMA_REPLAY_VAL TLVs. + + * if XFRM_AE_RTHR flag is set, then XFRMA_REPLAY_THRESH is also retrieved + * if XFRM_AE_ETHR flag is set, then XFRMA_ETIMER_THRESH is also retrieved + +b) XFRM_MSG_NEWAE is issued by either user space to configure + or kernel to announce events or respond to a XFRM_MSG_GETAE. + + i) user --> kernel to configure a specific SA. + + any of the values or threshold parameters can be updated by passing the + appropriate TLV. + + A response is issued back to the sender in user space to indicate success + or failure. + + In the case of success, additionally an event with + XFRM_MSG_NEWAE is also issued to any listeners as described in iii). + + ii) kernel->user direction as a response to XFRM_MSG_GETAE + + The response will always have XFRMA_LTIME_VAL and XFRMA_REPLAY_VAL TLVs. + + The threshold TLVs will be included if explicitly requested in + the XFRM_MSG_GETAE message. + + iii) kernel->user to report as event if someone sets any values or + thresholds for an SA using XFRM_MSG_NEWAE (as described in #i above). + In such a case XFRM_AE_CU flag is set to inform the user that + the change happened as a result of an update. + The message will always have XFRMA_LTIME_VAL and XFRMA_REPLAY_VAL TLVs. + + iv) kernel->user to report event when replay threshold or a timeout + is exceeded. + +In such a case either XFRM_AE_CR (replay exceeded) or XFRM_AE_CE (timeout +happened) is set to inform the user what happened. +Note the two flags are mutually exclusive. +The message will always have XFRMA_LTIME_VAL and XFRMA_REPLAY_VAL TLVs. + +5) Exceptions to threshold settings +----------------------------------- + +If you have an SA that is getting hit by traffic in bursts such that +there is a period where the timer threshold expires with no packets +seen, then an odd behavior is seen as follows: +The first packet arrival after a timer expiry will trigger a timeout +event; i.e we don't wait for a timeout period or a packet threshold +to be reached. This is done for simplicity and efficiency reasons. + +-JHS diff --git a/Documentation/networking/xfrm/xfrm_sysctl.rst b/Documentation/networking/xfrm/xfrm_sysctl.rst new file mode 100644 index 000000000..7d0c4b17c --- /dev/null +++ b/Documentation/networking/xfrm/xfrm_sysctl.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============ +XFRM Syscall +============ + +/proc/sys/net/core/xfrm_* Variables +=================================== + +xfrm_acq_expires - INTEGER + default 30 - hard timeout in seconds for acquire requests |
