Thread (8 messages) 8 messages, 3 authors, 22d ago

Re: [PATCH net 0/2] tcp: make TCP-AO lookups more predictable

From: Dmitry Safonov <hidden>
Date: 2026-06-23 01:13:00

Hi Eric,

On Mon, 22 Jun 2026 at 19:52, Eric Dumazet [off-list ref] wrote:
This series fixes a TCP-AO key lookup precedence bug.

TCP-AO stores MKTs in an unsorted list and returns the first match. This
allows newer, less-specific keys (wildcard VRF or shorter prefixes) to
shadow older, more-specific keys if inserted later.
Yeah, at this moment, TCP-AO doesn't allow any intersection of the keys:
If you have matching VRFs, matching keyids for matching peer/masks –
then when the userspace tries to add the second key, setsockopt() is
going to return -EKEYREJECTED/-EEXIST. This is quite different from
TCP-MD5, where the most matching key is the one that's going to be
used by the kernel.

This simplification (not allowing any key intersects) is mostly from a
very permissive RFC5925, where MKT matches can be: ip-addr/mask; ip
address ranges; wildcards of addresses; tcp ports. So, this part was
intentionally simplified until there is a user who requires one of
these things. And based on their requirements, a better data structure
than a simple list could be used. Basically, the longest prefix match
is like adding power-of-two ip ranges. Also, that's another reason why
I wanted an extendable setsockopt(), where one can add new
flags/fields to uAPI without breaking the existing users.

Anyways, if you have the requirement to have intersecting keys with
bigger mask matching (imitating TCP-MD5 behaviour), we can do that,
but I think that needs a new TCP_AO_KEYF_PREFIX_MATCH (or something of
a kind). Then the keys with everything matching, but a prefix could be
added to the socket, and the longest prefix match will be used.

I think one API decision should be documented straight away (besides
the key flag) – how this flag works with multiple keys.
Say there are 4 keys on a socket, all match the peer being connected:
keyA: ip 10.0.0.0 /8 (keyid = 100)
keyB: ip 10.0.0.0 /16 (keyid = 100)
keyC: ip 10.0.0.0 /8 (keyid = 101)
keyD: ip 10.0.0.0 /16 (keyid = 102)

So, keyA and keyB obviously will have to use this new
TCP_AO_KEYF_PREFIX_MATCH. Should keyC or keyD be copied to the
established connection socket or not?
I'd think the presence of TCP_AO_KEYF_PREFIX_MATCH flag on keyC&keyD
should also affect whether they are copied or not. If the flag is not
on keyC&keyD –  they should be copied to the established socket
(together with keyB, preserving the previous behaviour).

Otherwise, if they have the flag, what should happen?
1. keyB + keyC + keyD
2. keyB + keyD
If we go with (2), then if a user wants keyC on a socket, they could
either remove TCP_AO_KEYF_PREFIX_MATCH from keyC or add keyC1 with
mask /16 and the same password as keyC – slightly inconvenient, but
quite flexible.

What do you think?
Fix this by implementing sorted insertion in tcp_ao_link_mkt() based on
key specificity (VRF binding, then prefix length). This keeps the RX
lookup path fast while ensuring correctness.

The second patch adds a selftest to verify this behavior.

Eric Dumazet (2):
  tcp: fix TCP-AO key lookup precedence (shadowing)
  selftests/net: Add TCP-AO key shadowing test

 net/ipv4/tcp_ao.c                             | 27 +++++-
 tools/testing/selftests/net/tcp_ao/Makefile   |  1 +
 .../testing/selftests/net/tcp_ao/shadowing.c  | 93 +++++++++++++++++++
 3 files changed, 120 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/net/tcp_ao/shadowing.c

--
2.55.0.rc0.799.gd6f94ed593-goog
-- 
             Dmitry
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help