Re: [PATCH net 0/2] tcp: make TCP-AO lookups more predictable
From: Eric Dumazet <edumazet@google.com>
Date: 2026-06-23 05:25:10
On Mon, Jun 22, 2026 at 6:13 PM Dmitry Safonov [off-list ref] wrote:
Hi Eric, On Mon, 22 Jun 2026 at 19:52, Eric Dumazet [off-list ref] wrote:quoted
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?
If intersecting keys are not yet allowed, I think we must return an error code at the insertion stage, instead of hoping the user will do "the right thing". Thanks.