sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget%/translations/zh_CN/networking/tcp_aomodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/zh_TW/networking/tcp_aomodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/it_IT/networking/tcp_aomodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ja_JP/networking/tcp_aomodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ko_KR/networking/tcp_aomodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/sp_SP/networking/tcp_aomodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh?/var/lib/git/docbuild/linux/Documentation/networking/tcp_ao.rsthKubhsection)}(hhh](htitle)}(h8TCP Authentication Option Linux implementation (RFC5925)h]h8TCP Authentication Option Linux implementation (RFC5925)}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hXTCP Authentication Option (TCP-AO) provides a TCP extension aimed at verifying segments between trusted peers. It adds a new TCP header option with a Message Authentication Code (MAC). MACs are produced from the content of a TCP segment using a hashing function with a password known to both peers. The intent of TCP-AO is to deprecate TCP-MD5 providing better security, key rotation and support for a variety of hashing algorithms.h]hXTCP Authentication Option (TCP-AO) provides a TCP extension aimed at verifying segments between trusted peers. It adds a new TCP header option with a Message Authentication Code (MAC). MACs are produced from the content of a TCP segment using a hashing function with a password known to both peers. The intent of TCP-AO is to deprecate TCP-MD5 providing better security, key rotation and support for a variety of hashing algorithms.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h1. Introductionh]h1. Introduction}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhtable)}(hhh](h)}(h2Short and Limited Comparison of TCP-AO and TCP-MD5h]h2Short and Limited Comparison of TCP-AO and TCP-MD5}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubhtgroup)}(hhh](hcolspec)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhhubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhhubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhhubhthead)}(hhh]hrow)}(hhh](hentry)}(hhh]h}(h]h ]h"]h$]h&]uh1j,hj)ubj-)}(hhh]h)}(hTCP-MD5h]hTCP-MD5}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj7ubah}(h]h ]h"]h$]h&]uh1j,hj)ubj-)}(hhh]h)}(hTCP-AOh]hTCP-AO}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjNubah}(h]h ]h"]h$]h&]uh1j,hj)ubeh}(h]h ]h"]h$]h&]uh1j'hj$ubah}(h]h ]h"]h$]h&]uh1j"hhubhtbody)}(hhh](j()}(hhh](j-)}(hhh]h)}(hSupported hashing algorithmsh]hSupported hashing algorithms}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjyubah}(h]h ]h"]h$]h&]uh1j,hjvubj-)}(hhh]h)}(hMD5 (cryptographically weak)h]hMD5 (cryptographically weak)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j,hjvubj-)}(hhh]h)}(hMust support HMAC-SHA1 (chosen-prefix attacks) and CMAC-AES-128 (only side-channel attacks). May support any hashing algorithm.h]hMust support HMAC-SHA1 (chosen-prefix attacks) and CMAC-AES-128 (only side-channel attacks). May support any hashing algorithm.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j,hjvubeh}(h]h ]h"]h$]h&]uh1j'hjsubj()}(hhh](j-)}(hhh]h)}(hLength of MACs (bytes)h]hLength of MACs (bytes)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h16h]h16}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h>Typically 12-16. Other variants that fit TCP header permitted.h]h>Typically 12-16. Other variants that fit TCP header permitted.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j,hjubeh}(h]h ]h"]h$]h&]uh1j'hjsubj()}(hhh](j-)}(hhh]h)}(h!Number of keys per TCP connectionh]h!Number of keys per TCP connection}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h1h]h1}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hj,ubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(hManyh]hMany}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hjCubah}(h]h ]h"]h$]h&]uh1j,hjubeh}(h]h ]h"]h$]h&]uh1j'hjsubj()}(hhh](j-)}(hhh]h)}(h#Possibility to change an active keyh]h#Possibility to change an active key}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hjcubah}(h]h ]h"]h$]h&]uh1j,hj`ubj-)}(hhh]h)}(h9Non-practical (both peers have to change them during MSL)h]h9Non-practical (both peers have to change them during MSL)}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hjzubah}(h]h ]h"]h$]h&]uh1j,hj`ubj-)}(hhh]h)}(hSupported by protocolh]hSupported by protocol}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hjubah}(h]h ]h"]h$]h&]uh1j,hj`ubeh}(h]h ]h"]h$]h&]uh1j'hjsubj()}(hhh](j-)}(hhh]h)}(h%Protection against ICMP 'hard errors'h]h)Protection against ICMP ‘hard errors’}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK(hjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(hNoh]hNo}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK(hjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h8Yes: ignoring them by default on established connectionsh]h8Yes: ignoring them by default on established connections}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK(hjubah}(h]h ]h"]h$]h&]uh1j,hjubeh}(h]h ]h"]h$]h&]uh1j'hjsubj()}(hhh](j-)}(hhh]h)}(h*Protection against traffic-crossing attackh]h*Protection against traffic-crossing attack}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(hNoh]hNo}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h&Yes: pseudo-header includes TCP ports.h]h&Yes: pseudo-header includes TCP ports.}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hj-ubah}(h]h ]h"]h$]h&]uh1j,hjubeh}(h]h ]h"]h$]h&]uh1j'hjsubj()}(hhh](j-)}(hhh]h)}(h(Protection against replayed TCP segmentsh]h(Protection against replayed TCP segments}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hjMubah}(h]h ]h"]h$]h&]uh1j,hjJubj-)}(hhh]h)}(hNoh]hNo}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hjdubah}(h]h ]h"]h$]h&]uh1j,hjJubj-)}(hhh]h)}(hCSequence Number Extension (SNE) and Initial Sequence Numbers (ISNs)h]hCSequence Number Extension (SNE) and Initial Sequence Numbers (ISNs)}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hj{ubah}(h]h ]h"]h$]h&]uh1j,hjJubeh}(h]h ]h"]h$]h&]uh1j'hjsubj()}(hhh](j-)}(hhh]h)}(hSupports Connectionless Resetsh]hSupports Connectionless Resets}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK5hjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(hYesh]hYes}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK5hjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h.No. ISNs+SNE are needed to correctly sign RST.h]h.No. ISNs+SNE are needed to correctly sign RST.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK5hjubah}(h]h ]h"]h$]h&]uh1j,hjubeh}(h]h ]h"]h$]h&]uh1j'hjsubj()}(hhh](j-)}(hhh]h)}(h Standardsh]h Standards}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(hRFC 2385h]hRFC 2385}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(hRFC 5925, RFC 5926h]hRFC 5925, RFC 5926}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjubah}(h]h ]h"]h$]h&]uh1j,hjubeh}(h]h ]h"]h$]h&]uh1j'hjsubeh}(h]h ]h"]h$]h&]uh1jqhhubeh}(h]h ]h"]h$]h&]colsKuh1hhhubeh}(h]id1ah ]h"]h$]h&]uh1hhhhhhhhNubh)}(hhh](h)}(h@1.1 Frequently Asked Questions (FAQ) with references to RFC 5925h]h@1.1 Frequently Asked Questions (FAQ) with references to RFC 5925}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjHhhhhhK=ubh)}(hgQ: Can either SendID or RecvID be non-unique for the same 4-tuple (srcaddr, srcport, dstaddr, dstport)?h]hgQ: Can either SendID or RecvID be non-unique for the same 4-tuple (srcaddr, srcport, dstaddr, dstport)?}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK?hjHhhubh)}(h A: No [3.1]::h]h A: No [3.1]:}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKBhjHhhubh literal_block)}(hS>> The IDs of MKTs MUST NOT overlap where their TCP connection identifiers overlap.h]hS>> The IDs of MKTs MUST NOT overlap where their TCP connection identifiers overlap.}hjwsbah}(h]h ]h"]h$]h&]hhuh1juhhhKDhjHhhubh)}(hBQ: Can Master Key Tuple (MKT) for an active connection be removed?h]hBQ: Can Master Key Tuple (MKT) for an active connection be removed?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKGhjHhhubh)}(hBA: No, unless it's copied to Transport Control Block (TCB) [3.1]::h]hCA: No, unless it’s copied to Transport Control Block (TCB) [3.1]:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKIhjHhhubjv)}(hX It is presumed that an MKT affecting a particular connection cannot be destroyed during an active connection -- or, equivalently, that its parameters are copied to an area local to the connection (i.e., instantiated) and so changes would affect only new connections.h]hX It is presumed that an MKT affecting a particular connection cannot be destroyed during an active connection -- or, equivalently, that its parameters are copied to an area local to the connection (i.e., instantiated) and so changes would affect only new connections.}hjsbah}(h]h ]h"]h$]h&]hhuh1juhhhKKhjHhhubh)}(hQ: If an old MKT needs to be deleted, how should it be done in order to not remove it for an active connection? (As it can be still in use at any moment later)h]hQ: If an old MKT needs to be deleted, how should it be done in order to not remove it for an active connection? (As it can be still in use at any moment later)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKPhjHhhubh)}(hA: Not specified by RFC 5925, seems to be a problem for key management to ensure that no one uses such MKT before trying to remove it.h]hA: Not specified by RFC 5925, seems to be a problem for key management to ensure that no one uses such MKT before trying to remove it.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKThjHhhubh)}(h> A TCP-AO implementation MUST allow for configuration of the behavior of segments with TCP-AO but that do not match an MKT. The initial default of this configuration SHOULD be to silently accept such connections. If this is not the desired case, an MKT can be included to match such connections, or the connection can indicate that TCP-AO is required. Alternately, the configuration can be changed to discard segments with the AO option not matching an MKT.h]hX>> A TCP-AO implementation MUST allow for configuration of the behavior of segments with TCP-AO but that do not match an MKT. The initial default of this configuration SHOULD be to silently accept such connections. If this is not the desired case, an MKT can be included to match such connections, or the connection can indicate that TCP-AO is required. Alternately, the configuration can be changed to discard segments with the AO option not matching an MKT.}hjWsbah}(h]h ]h"]h$]h&]hhuh1juhhhKhjHhhubh)}(h [10.2.b]::h]h [10.2.b]:}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubjv)}(hConnections not matching any MKT do not require TCP-AO. Further, incoming segments with TCP-AO are not discarded solely because they include the option, provided they do not match any MKT.h]hConnections not matching any MKT do not require TCP-AO. Further, incoming segments with TCP-AO are not discarded solely because they include the option, provided they do not match any MKT.}hjssbah}(h]h ]h"]h$]h&]hhuh1juhhhKhjHhhubh)}(hNote that Linux TCP-AO implementation differs in this aspect. Currently, TCP-AO segments with unknown key signatures are discarded with warnings logged.h]hNote that Linux TCP-AO implementation differs in this aspect. Currently, TCP-AO segments with unknown key signatures are discarded with warnings logged.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubh)}(hQ: Does the RFC imply centralized kernel key management in any way? (i.e. that a key on all connections MUST be rotated at the same time?)h]hQ: Does the RFC imply centralized kernel key management in any way? (i.e. that a key on all connections MUST be rotated at the same time?)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubh)}(hdA: Not specified. MKTs can be managed in userspace, the only relevant part to key changes is [7.3]::h]hcA: Not specified. MKTs can be managed in userspace, the only relevant part to key changes is [7.3]:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubjv)}(hd>> All TCP segments MUST be checked against the set of MKTs for matching TCP connection identifiers.h]hd>> All TCP segments MUST be checked against the set of MKTs for matching TCP connection identifiers.}hjsbah}(h]h ]h"]h$]h&]hhuh1juhhhKhjHhhubh)}(h_Q: What happens when RNextKeyID requested by a peer is unknown? Should the connection be reset?h]h_Q: What happens when RNextKeyID requested by a peer is unknown? Should the connection be reset?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubh)}(h=A: It should not, no action needs to be performed [7.5.2.e]::h]h> An outgoing TCP segment MUST match at most one desired MKT, indicated by the segment’s socket pair. The segment MAY match multiple MKTs, provided that exactly one MKT is indicated as desired. Other information in the segment MAY be used to determine the desired MKT when multiple MKTs match; such information MUST NOT include values in any TCP option fields.h]hXSMultiple MKTs may match a single outgoing segment, e.g., when MKTs are being changed. Those MKTs cannot have conflicting IDs (as noted elsewhere), and some mechanism must determine which MKT to use for each given outgoing segment. >> An outgoing TCP segment MUST match at most one desired MKT, indicated by the segment’s socket pair. The segment MAY match multiple MKTs, provided that exactly one MKT is indicated as desired. Other information in the segment MAY be used to determine the desired MKT when multiple MKTs match; such information MUST NOT include values in any TCP option fields.}hjEsbah}(h]h ]h"]h$]h&]hhuh1juhhhKhjHhhubh)}(h=Q: Can TCP-MD5 connection migrate to TCP-AO (and vice-versa):h]h=Q: Can TCP-MD5 connection migrate to TCP-AO (and vice-versa):}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubh)}(h A: No [1]::h]h A: No [1]:}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubjv)}(hTCP MD5-protected connections cannot be migrated to TCP-AO because TCP MD5 does not support any changes to a connection’s security algorithm once established.h]hTCP MD5-protected connections cannot be migrated to TCP-AO because TCP MD5 does not support any changes to a connection’s security algorithm once established.}hjosbah}(h]h ]h"]h$]h&]hhuh1juhhhKhjHhhubh)}(hYQ: If all MKTs are removed on a connection, can it become a non-TCP-AO signed connection?h]hYQ: If all MKTs are removed on a connection, can it become a non-TCP-AO signed connection?}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubh)}(hXUA: [7.5.2] doesn't have the same choice as SYN packet handling in [7.5.1.i] that would allow accepting segments without a sign (which would be insecure). While switching to non-TCP-AO connection is not prohibited directly, it seems what the RFC means. Also, there's a requirement for TCP-AO connections to always have one current_key [3.3]::h]hXXA: [7.5.2] doesn’t have the same choice as SYN packet handling in [7.5.1.i] that would allow accepting segments without a sign (which would be insecure). While switching to non-TCP-AO connection is not prohibited directly, it seems what the RFC means. Also, there’s a requirement for TCP-AO connections to always have one current_key [3.3]:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubjv)}(hGTCP-AO requires that every protected TCP segment match exactly one MKT.h]hGTCP-AO requires that every protected TCP segment match exactly one MKT.}hjsbah}(h]h ]h"]h$]h&]hhuh1juhhhKhjHhhubh)}(h[3.3]::h]h[3.3]:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubjv)}(h>> An incoming TCP segment including TCP-AO MUST match exactly one MKT, indicated solely by the segment’s socket pair and its TCP-AO KeyID.h]h>> An incoming TCP segment including TCP-AO MUST match exactly one MKT, indicated solely by the segment’s socket pair and its TCP-AO KeyID.}hjsbah}(h]h ]h"]h$]h&]hhuh1juhhhKhjHhhubh)}(h[4.4]::h]h[4.4]:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubjv)}(hPOne or more MKTs. These are the MKTs that match this connection’s socket pair.h]hPOne or more MKTs. These are the MKTs that match this connection’s socket pair.}hjsbah}(h]h ]h"]h$]h&]hhuh1juhhhKhjHhhubh)}(h;Q: Can a non-TCP-AO connection become a TCP-AO-enabled one?h]h;Q: Can a non-TCP-AO connection become a TCP-AO-enabled one?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubh)}(hXA: No: for an already established non-TCP-AO connection it would be impossible to switch to using TCP-AO, as the traffic key generation requires the initial sequence numbers. Paraphrasing, starting using TCP-AO would require re-establishing the TCP connection.h]hXA: No: for an already established non-TCP-AO connection it would be impossible to switch to using TCP-AO, as the traffic key generation requires the initial sequence numbers. Paraphrasing, starting using TCP-AO would require re-establishing the TCP connection.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjHhhubeh}(h]:frequently-asked-questions-faq-with-references-to-rfc-5925ah ]h"]@1.1 frequently asked questions (faq) with references to rfc 5925ah$]h&]uh1hhhhhhhhK=ubeh}(h] introductionah ]h"]1. introductionah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h32. In-kernel MKTs database vs database in userspaceh]h32. In-kernel MKTs database vs database in userspace}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hXSLinux TCP-AO support is implemented using ``setsockopt()s``, in a similar way to TCP-MD5. It means that a userspace application that wants to use TCP-AO should perform ``setsockopt()`` on a TCP socket when it wants to add, remove or rotate MKTs. This approach moves the key management responsibility to userspace as well as decisions on corner cases, i.e. what to do if the peer doesn't respect RNextKeyID; moving more code to userspace, especially responsible for the policy decisions. Besides, it's flexible and scales well (with less locking needed than in the case of an in-kernel database). One also should keep in mind that mainly intended users are BGP processes, not any random applications, which means that compared to IPsec tunnels, no transparency is really needed and modern BGP daemons already have ``setsockopt()s`` for TCP-MD5 support.h](h*Linux TCP-AO support is implemented using }(hjhhhNhNubhliteral)}(h``setsockopt()s``h]h setsockopt()s}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubhm, in a similar way to TCP-MD5. It means that a userspace application that wants to use TCP-AO should perform }(hjhhhNhNubj%)}(h``setsockopt()``h]h setsockopt()}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubhXy on a TCP socket when it wants to add, remove or rotate MKTs. This approach moves the key management responsibility to userspace as well as decisions on corner cases, i.e. what to do if the peer doesn’t respect RNextKeyID; moving more code to userspace, especially responsible for the policy decisions. Besides, it’s flexible and scales well (with less locking needed than in the case of an in-kernel database). One also should keep in mind that mainly intended users are BGP processes, not any random applications, which means that compared to IPsec tunnels, no transparency is really needed and modern BGP daemons already have }(hjhhhNhNubj%)}(h``setsockopt()s``h]h setsockopt()s}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubh for TCP-MD5 support.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hhh](h)}(h*Considered pros and cons of the approachesh]h*Considered pros and cons of the approaches}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjbubh)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjsubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjsubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjsubj#)}(hhh]j()}(hhh](j-)}(hhh]h}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h``setsockopt()``h]j%)}(hjh]h setsockopt()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h in-kernel DBh]h in-kernel DB}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j,hjubeh}(h]h ]h"]h$]h&]uh1j'hjubah}(h]h ]h"]h$]h&]uh1j"hjsubjr)}(hhh](j()}(hhh](j-)}(hhh]h)}(h Extendabilityh]h Extendability}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h7``setsockopt()`` commands should be extendable syscallsh](j%)}(h``setsockopt()``h]h setsockopt()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubh' commands should be extendable syscalls}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(h*Netlink messages are simple and extendableh]h*Netlink messages are simple and extendable}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj(ubah}(h]h ]h"]h$]h&]uh1j,hjubeh}(h]h ]h"]h$]h&]uh1j'hjubj()}(hhh](j-)}(hhh]h)}(hRequired userspace changesh]hRequired userspace changes}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjHubah}(h]h ]h"]h$]h&]uh1j,hjEubj-)}(hhh]h)}(haBGP or any application that wants TCP-AO needs to perform ``setsockopt()s`` and do key managementh](h:BGP or any application that wants TCP-AO needs to perform }(hjbhhhNhNubj%)}(h``setsockopt()s``h]h setsockopt()s}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjbubh and do key management}(hjbhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hj_ubah}(h]h ]h"]h$]h&]uh1j,hjEubj-)}(hhh]h)}(hccould be transparent as tunnels, providing something like ``ip tcpao add key`` (delete/show/rotate)h](h:could be transparent as tunnels, providing something like }(hjhhhNhNubj%)}(h``ip tcpao add key``h]hip tcpao add key}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubh (delete/show/rotate)}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hjubah}(h]h ]h"]h$]h&]uh1j,hjEubeh}(h]h ]h"]h$]h&]uh1j'hjubj()}(hhh](j-)}(hhh]h)}(hMKTs removal or addingh]hMKTs removal or adding}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(hharder for userspaceh]hharder for userspace}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j,hjubj-)}(hhh]h)}(hharder for kernelh]hharder for kernel}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j,hjubeh}(h]h ]h"]h$]h&]uh1j'hjubj()}(hhh](j-)}(hhh]h)}(h Dump-abilityh]h Dump-ability}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j,hj ubj-)}(hhh]h)}(h``getsockopt()``h]j%)}(hj$ h]h getsockopt()}(hj& hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj" ubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j,hj ubj-)}(hhh]h)}(hNetlink .dump() callbackh]hNetlink .dump() callback}(hjB hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj? ubah}(h]h ]h"]h$]h&]uh1j,hj ubeh}(h]h ]h"]h$]h&]uh1j'hjubj()}(hhh](j-)}(hhh]h)}(h!Limits on kernel resources/memoryh]h!Limits on kernel resources/memory}(hjb hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj_ ubah}(h]h ]h"]h$]h&]uh1j,hj\ ubj-)}(hhh]h)}(hequalh]hequal}(hjy hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjv ubah}(h]h ]h"]h$]h&]morecolsKuh1j,hj\ ubeh}(h]h ]h"]h$]h&]uh1j'hjubj()}(hhh](j-)}(hhh]h)}(h Scalabilityh]h Scalability}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j,hj ubj-)}(hhh]h)}(h$contention on ``TCP_LISTEN`` socketsh](hcontention on }(hj hhhNhNubj%)}(h``TCP_LISTEN``h]h TCP_LISTEN}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh sockets}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j,hj ubj-)}(hhh]h)}(h contention on the whole databaseh]h contention on the whole database}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j,hj ubeh}(h]h ]h"]h$]h&]uh1j'hjubj()}(hhh](j-)}(hhh]h)}(hMonitoring & warningsh]hMonitoring & warnings}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j,hj ubj-)}(hhh]h)}(h ``TCP_DIAG``h]j%)}(hj h]hTCP_DIAG}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j,hj ubj-)}(hhh]h)}(hsame Netlink socketh]hsame Netlink socket}(hj1 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj. ubah}(h]h ]h"]h$]h&]uh1j,hj ubeh}(h]h ]h"]h$]h&]uh1j'hjubj()}(hhh](j-)}(hhh]h)}(hMatching of MKTsh]hMatching of MKTs}(hjQ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjN ubah}(h]h ]h"]h$]h&]uh1j,hjK ubj-)}(hhh]h)}(h!half-problem: only listen socketsh]h!half-problem: only listen sockets}(hjh hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhje ubah}(h]h ]h"]h$]h&]uh1j,hjK ubj-)}(hhh]h)}(hhardh]hhard}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj| ubah}(h]h ]h"]h$]h&]uh1j,hjK ubeh}(h]h ]h"]h$]h&]uh1j'hjubeh}(h]h ]h"]h$]h&]uh1jqhjsubeh}(h]h ]h"]h$]h&]colsKuh1hhjbubeh}(h]id2ah ]h"]h$]h&]uh1hhj hhhhhNubeh}(h]0in-kernel-mkts-database-vs-database-in-userspaceah ]h"]32. in-kernel mkts database vs database in userspaceah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h3. uAPIh]h3. uAPI}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhM#ubh)}(hX_Linux provides a set of ``setsockopt()s`` and ``getsockopt()s`` that let userspace manage TCP-AO on a per-socket basis. In order to add/delete MKTs ``TCP_AO_ADD_KEY`` and ``TCP_AO_DEL_KEY`` TCP socket options must be used. It is not allowed to add a key on an established non-TCP-AO connection as well as to remove the last key from TCP-AO connection.h](hLinux provides a set of }(hj hhhNhNubj%)}(h``setsockopt()s``h]h setsockopt()s}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh and }(hj hhhNhNubj%)}(h``getsockopt()s``h]h getsockopt()s}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubhU that let userspace manage TCP-AO on a per-socket basis. In order to add/delete MKTs }(hj hhhNhNubj%)}(h``TCP_AO_ADD_KEY``h]hTCP_AO_ADD_KEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh and }hj sbj%)}(h``TCP_AO_DEL_KEY``h]hTCP_AO_DEL_KEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh TCP socket options must be used. It is not allowed to add a key on an established non-TCP-AO connection as well as to remove the last key from TCP-AO connection.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM%hj hhubh)}(hX``setsockopt(TCP_AO_DEL_KEY)`` command may specify ``tcp_ao_del::current_key`` + ``tcp_ao_del::set_current`` and/or ``tcp_ao_del::rnext`` + ``tcp_ao_del::set_rnext`` which makes such delete "forced": it provides userspace a way to delete a key that's being used and atomically set another one instead. This is not intended for normal use and should be used only when the peer ignores RNextKeyID and keeps requesting/using an old key. It provides a way to force-delete a key that's not trusted but may break the TCP-AO connection.h](j%)}(h``setsockopt(TCP_AO_DEL_KEY)``h]hsetsockopt(TCP_AO_DEL_KEY)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh command may specify }(hj hhhNhNubj%)}(h``tcp_ao_del::current_key``h]htcp_ao_del::current_key}(hj2 hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh + }(hj hhhNhNubj%)}(h``tcp_ao_del::set_current``h]htcp_ao_del::set_current}(hjD hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh and/or }(hj hhhNhNubj%)}(h``tcp_ao_del::rnext``h]htcp_ao_del::rnext}(hjV hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh + }hj sbj%)}(h``tcp_ao_del::set_rnext``h]htcp_ao_del::set_rnext}(hjh hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubhXt which makes such delete “forced”: it provides userspace a way to delete a key that’s being used and atomically set another one instead. This is not intended for normal use and should be used only when the peer ignores RNextKeyID and keeps requesting/using an old key. It provides a way to force-delete a key that’s not trusted but may break the TCP-AO connection.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM+hj hhubh)}(hX=The usual/normal key-rotation can be performed with ``setsockopt(TCP_AO_INFO)``. It also provides a uAPI to change per-socket TCP-AO settings, such as ignoring ICMPs, as well as clear per-socket TCP-AO packet counters. The corresponding ``getsockopt(TCP_AO_INFO)`` can be used to get those per-socket TCP-AO settings.h](h4The usual/normal key-rotation can be performed with }(hj hhhNhNubj%)}(h``setsockopt(TCP_AO_INFO)``h]hsetsockopt(TCP_AO_INFO)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh. It also provides a uAPI to change per-socket TCP-AO settings, such as ignoring ICMPs, as well as clear per-socket TCP-AO packet counters. The corresponding }(hj hhhNhNubj%)}(h``getsockopt(TCP_AO_INFO)``h]hgetsockopt(TCP_AO_INFO)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh5 can be used to get those per-socket TCP-AO settings.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM4hj hhubh)}(hAnother useful command is ``getsockopt(TCP_AO_GET_KEYS)``. One can use it to list all MKTs on a TCP socket or use a filter to get keys for a specific peer and/or sndid/rcvid, VRF L3 interface or get current_key/rnext_key.h](hAnother useful command is }(hj hhhNhNubj%)}(h``getsockopt(TCP_AO_GET_KEYS)``h]hgetsockopt(TCP_AO_GET_KEYS)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh. One can use it to list all MKTs on a TCP socket or use a filter to get keys for a specific peer and/or sndid/rcvid, VRF L3 interface or get current_key/rnext_key.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM:hj hhubh)}(hTo repair TCP-AO connections ``setsockopt(TCP_AO_REPAIR)`` is available, provided that the user previously has checkpointed/dumped the socket with ``getsockopt(TCP_AO_REPAIR)``.h](hTo repair TCP-AO connections }(hj hhhNhNubj%)}(h``setsockopt(TCP_AO_REPAIR)``h]hsetsockopt(TCP_AO_REPAIR)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubhY is available, provided that the user previously has checkpointed/dumped the socket with }(hj hhhNhNubj%)}(h``getsockopt(TCP_AO_REPAIR)``h]hgetsockopt(TCP_AO_REPAIR)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM>hj hhubh)}(hA tip here for scaled TCP_LISTEN sockets, that may have some thousands TCP-AO keys, is: use filters in ``getsockopt(TCP_AO_GET_KEYS)`` and asynchronous delete with ``setsockopt(TCP_AO_DEL_KEY)``.h](hgA tip here for scaled TCP_LISTEN sockets, that may have some thousands TCP-AO keys, is: use filters in }(hj hhhNhNubj%)}(h``getsockopt(TCP_AO_GET_KEYS)``h]hgetsockopt(TCP_AO_GET_KEYS)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh and asynchronous delete with }(hj hhhNhNubj%)}(h``setsockopt(TCP_AO_DEL_KEY)``h]hsetsockopt(TCP_AO_DEL_KEY)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMBhj hhubh)}(hXLinux TCP-AO also provides a bunch of segment counters that can be helpful with troubleshooting/debugging issues. Every MKT has good/bad counters that reflect how many packets passed/failed verification. Each TCP-AO socket has the following counters: - for good segments (properly signed) - for bad segments (failed TCP-AO verification) - for segments with unknown keys - for segments where an AO signature was expected, but wasn't found - for the number of ignored ICMPsh]hXLinux TCP-AO also provides a bunch of segment counters that can be helpful with troubleshooting/debugging issues. Every MKT has good/bad counters that reflect how many packets passed/failed verification. Each TCP-AO socket has the following counters: - for good segments (properly signed) - for bad segments (failed TCP-AO verification) - for segments with unknown keys - for segments where an AO signature was expected, but wasn’t found - for the number of ignored ICMPs}(hj6 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMFhj hhubh)}(hTCP-AO per-socket counters are also duplicated with per-netns counters, exposed with SNMP. Those are ``TCPAOGood``, ``TCPAOBad``, ``TCPAOKeyNotFound``, ``TCPAORequired`` and ``TCPAODroppedIcmps``.h](heTCP-AO per-socket counters are also duplicated with per-netns counters, exposed with SNMP. Those are }(hjD hhhNhNubj%)}(h ``TCPAOGood``h]h TCPAOGood}(hjL hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjD ubh, }(hjD hhhNhNubj%)}(h ``TCPAOBad``h]hTCPAOBad}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjD ubh, }hjD sbj%)}(h``TCPAOKeyNotFound``h]hTCPAOKeyNotFound}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjD ubh, }(hjD hhhNhNubj%)}(h``TCPAORequired``h]h TCPAORequired}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjD ubh and }(hjD hhhNhNubj%)}(h``TCPAODroppedIcmps``h]hTCPAODroppedIcmps}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjD ubh.}(hjD hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMPhj hhubh)}(hXXFor monitoring purposes, there are following TCP-AO trace events: ``tcp_hash_bad_header``, ``tcp_hash_ao_required``, ``tcp_ao_handshake_failure``, ``tcp_ao_wrong_maclen``, ``tcp_ao_wrong_maclen``, ``tcp_ao_key_not_found``, ``tcp_ao_rnext_request``, ``tcp_ao_synack_no_key``, ``tcp_ao_snd_sne_update``, ``tcp_ao_rcv_sne_update``. It's possible to separately enable any of them and one can filter them by net-namespace, 4-tuple, family, L3 index, and TCP header flags. If a segment has a TCP-AO header, the filters may also include keyid, rnext, and maclen. SNE updates include the rolled-over numbers.h](hBFor monitoring purposes, there are following TCP-AO trace events: }(hj hhhNhNubj%)}(h``tcp_hash_bad_header``h]htcp_hash_bad_header}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh, }(hj hhhNhNubj%)}(h``tcp_hash_ao_required``h]htcp_hash_ao_required}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh, }hj sbj%)}(h``tcp_ao_handshake_failure``h]htcp_ao_handshake_failure}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh, }(hj hhhNhNubj%)}(h``tcp_ao_wrong_maclen``h]htcp_ao_wrong_maclen}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh, }hj sbj%)}(h``tcp_ao_wrong_maclen``h]htcp_ao_wrong_maclen}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh, }hj sbj%)}(h``tcp_ao_key_not_found``h]htcp_ao_key_not_found}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh, }hj sbj%)}(h``tcp_ao_rnext_request``h]htcp_ao_rnext_request}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh, }hj sbj%)}(h``tcp_ao_synack_no_key``h]htcp_ao_synack_no_key}(hj2 hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh, }hj sbj%)}(h``tcp_ao_snd_sne_update``h]htcp_ao_snd_sne_update}(hjD hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh, }hj sbj%)}(h``tcp_ao_rcv_sne_update``h]htcp_ao_rcv_sne_update}(hjV hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubhX. It’s possible to separately enable any of them and one can filter them by net-namespace, 4-tuple, family, L3 index, and TCP header flags. If a segment has a TCP-AO header, the filters may also include keyid, rnext, and maclen. SNE updates include the rolled-over numbers.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMThj hhubh)}(hQRFC 5925 very permissively specifies how TCP port matching can be done for MKTs::h]hPRFC 5925 very permissively specifies how TCP port matching can be done for MKTs:}(hjn hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM]hj hhubjv)}(hXTCP connection identifier. A TCP socket pair, i.e., a local IP address, a remote IP address, a TCP local port, and a TCP remote port. Values can be partially specified using ranges (e.g., 2-30), masks (e.g., 0xF0), wildcards (e.g., "*"), or any other suitable indication.h]hXTCP connection identifier. A TCP socket pair, i.e., a local IP address, a remote IP address, a TCP local port, and a TCP remote port. Values can be partially specified using ranges (e.g., 2-30), masks (e.g., 0xF0), wildcards (e.g., "*"), or any other suitable indication.}hj| sbah}(h]h ]h"]h$]h&]hhuh1juhhhM`hj hhubh)}(hCurrently Linux TCP-AO implementation doesn't provide any TCP port matching. Probably, port ranges are the most flexible for uAPI, but so far not implemented.h]hCurrently Linux TCP-AO implementation doesn’t provide any TCP port matching. Probably, port ranges are the most flexible for uAPI, but so far not implemented.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMehj hhubeh}(h]uapiah ]h"]3. uapiah$]h&]uh1hhhhhhhhM#ubh)}(hhh](h)}(h(4. ``setsockopt()`` vs ``accept()`` raceh](h4. }(hj hhhNhNubj%)}(h``setsockopt()``h]h setsockopt()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh vs }(hj hhhNhNubj%)}(h ``accept()``h]haccept()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh race}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhj hhhhhMjubh)}(hXIn contrast with an established TCP-MD5 connection which has just one key, TCP-AO connections may have many keys, which means that accepted connections on a listen socket may have any amount of keys as well. As copying all those keys on a first properly signed SYN would make the request socket bigger, that would be undesirable. Currently, the implementation doesn't copy keys to request sockets, but rather look them up on the "parent" listener socket.h]hXIn contrast with an established TCP-MD5 connection which has just one key, TCP-AO connections may have many keys, which means that accepted connections on a listen socket may have any amount of keys as well. As copying all those keys on a first properly signed SYN would make the request socket bigger, that would be undesirable. Currently, the implementation doesn’t copy keys to request sockets, but rather look them up on the “parent” listener socket.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMlhj hhubh)}(hThe result is that when userspace removes TCP-AO keys, that may break not-yet-established connections on request sockets as well as not removing keys from sockets that were already established, but not yet ``accept()``'ed, hanging in the accept queue.h](hThe result is that when userspace removes TCP-AO keys, that may break not-yet-established connections on request sockets as well as not removing keys from sockets that were already established, but not yet }(hj hhhNhNubj%)}(h ``accept()``h]haccept()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hj ubh#’ed, hanging in the accept queue.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMshj hhubh)}(hThe reverse is valid as well: if userspace adds a new key for a peer on a listener socket, the established sockets in the accept queue won't have the new keys.h]hThe reverse is valid as well: if userspace adds a new key for a peer on a listener socket, the established sockets in the accept queue won’t have the new keys.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMxhj hhubh)}(hXAt this moment, the resolution for the two races: ``setsockopt(TCP_AO_ADD_KEY)`` vs ``accept()`` and ``setsockopt(TCP_AO_DEL_KEY)`` vs ``accept()`` is delegated to userspace. This means that it's expected that userspace would check the MKTs on the socket that was returned by ``accept()`` to verify that any key rotation that happened on the listen socket is reflected on the newly established connection.h](h2At this moment, the resolution for the two races: }(hjhhhNhNubj%)}(h``setsockopt(TCP_AO_ADD_KEY)``h]hsetsockopt(TCP_AO_ADD_KEY)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubh vs }(hjhhhNhNubj%)}(h ``accept()``h]haccept()}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubh and }(hjhhhNhNubj%)}(h``setsockopt(TCP_AO_DEL_KEY)``h]hsetsockopt(TCP_AO_DEL_KEY)}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubh vs }hjsbj%)}(h ``accept()``h]haccept()}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubh is delegated to userspace. This means that it’s expected that userspace would check the MKTs on the socket that was returned by }(hjhhhNhNubj%)}(h ``accept()``h]haccept()}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjubhu to verify that any key rotation that happened on the listen socket is reflected on the newly established connection.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM|hj hhubh)}(hThis is a similar "do-nothing" approach to TCP-MD5 from the kernel side and may be changed later by introducing new flags to ``tcp_ao_add`` and ``tcp_ao_del``.h](hThis is a similar “do-nothing” approach to TCP-MD5 from the kernel side and may be changed later by introducing new flags to }(hjyhhhNhNubj%)}(h``tcp_ao_add``h]h tcp_ao_add}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjyubh and }(hjyhhhNhNubj%)}(h``tcp_ao_del``h]h tcp_ao_del}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j$hjyubh.}(hjyhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(h}Note that this race is rare for it needs TCP-AO key rotation to happen during the 3-way handshake for the new TCP connection.h]h}Note that this race is rare for it needs TCP-AO key rotation to happen during the 3-way handshake for the new TCP connection.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h]setsockopt-vs-accept-raceah ]h"] 4. setsockopt() vs accept() raceah$]h&]uh1hhhhhhhhMjubh)}(hhh](h)}(h5. Interaction with TCP-MD5h]h5. Interaction with TCP-MD5}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hA TCP connection can not migrate between TCP-AO and TCP-MD5 options. The established sockets that have either AO or MD5 keys are restricted for adding keys of the other option.h]hA TCP connection can not migrate between TCP-AO and TCP-MD5 options. The established sockets that have either AO or MD5 keys are restricted for adding keys of the other option.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXFor listening sockets the picture is different: BGP server may want to receive both TCP-AO and (deprecated) TCP-MD5 clients. As a result, both types of keys may be added to TCP_CLOSED or TCP_LISTEN sockets. It's not allowed to add different types of keys for the same peer.h]hXFor listening sockets the picture is different: BGP server may want to receive both TCP-AO and (deprecated) TCP-MD5 clients. As a result, both types of keys may be added to TCP_CLOSED or TCP_LISTEN sockets. It’s not allowed to add different types of keys for the same peer.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h]interaction-with-tcp-md5ah ]h"]5. interaction with tcp-md5ah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(h6. SNE Linux implementationh]h6. SNE Linux implementation}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hX%RFC 5925 [6.2] describes the algorithm of how to extend TCP sequence numbers with SNE. In short: TCP has to track the previous sequence numbers and set sne_flag when the current SEQ number rolls over. The flag is cleared when both current and previous SEQ numbers cross 0x7fff, which is 32Kb.h]hX%RFC 5925 [6.2] describes the algorithm of how to extend TCP sequence numbers with SNE. In short: TCP has to track the previous sequence numbers and set sne_flag when the current SEQ number rolls over. The flag is cleared when both current and previous SEQ numbers cross 0x7fff, which is 32Kb.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXIn times when sne_flag is set, the algorithm compares SEQ for each packet with 0x7fff and if it's higher than 32Kb, it assumes that the packet should be verified with SNE before the increment. As a result, there's this [0; 32Kb] window, when packets with (SNE - 1) can be accepted.h]hXIn times when sne_flag is set, the algorithm compares SEQ for each packet with 0x7fff and if it’s higher than 32Kb, it assumes that the packet should be verified with SNE before the increment. As a result, there’s this [0; 32Kb] window, when packets with (SNE - 1) can be accepted.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXmLinux implementation simplifies this a bit: as the network stack already tracks the first SEQ byte that ACK is wanted for (snd_una) and the next SEQ byte that is wanted (rcv_nxt) - that's enough information for a rough estimation on where in the 4GB SEQ number space both sender and receiver are. When they roll over to zero, the corresponding SNE gets incremented.h]hXoLinux implementation simplifies this a bit: as the network stack already tracks the first SEQ byte that ACK is wanted for (snd_una) and the next SEQ byte that is wanted (rcv_nxt) - that’s enough information for a rough estimation on where in the 4GB SEQ number space both sender and receiver are. When they roll over to zero, the corresponding SNE gets incremented.}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hX1tcp_ao_compute_sne() is called for each TCP-AO segment. It compares SEQ numbers from the segment with snd_una or rcv_nxt and fits the result into a 2GB window around them, detecting SEQ numbers rolling over. That simplifies the code a lot and only requires SNE numbers to be stored on every TCP-AO socket.h]hX1tcp_ao_compute_sne() is called for each TCP-AO segment. It compares SEQ numbers from the segment with snd_una or rcv_nxt and fits the result into a 2GB window around them, detecting SEQ numbers rolling over. That simplifies the code a lot and only requires SNE numbers to be stored on every TCP-AO socket.}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXThe 2GB window at first glance seems much more permissive compared to RFC 5926. But that is only used to pick the correct SNE before/after a rollover. It allows more TCP segment replays, but yet all regular TCP checks in tcp_sequence() are applied on the verified segment. So, it trades a bit more permissive acceptance of replayed/retransmitted segments for the simplicity of the algorithm and what seems better behaviour for large TCP windows.h]hXThe 2GB window at first glance seems much more permissive compared to RFC 5926. But that is only used to pick the correct SNE before/after a rollover. It allows more TCP segment replays, but yet all regular TCP checks in tcp_sequence() are applied on the verified segment. So, it trades a bit more permissive acceptance of replayed/retransmitted segments for the simplicity of the algorithm and what seems better behaviour for large TCP windows.}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h]sne-linux-implementationah ]h"]6. sne linux implementationah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(h7. Linksh]h7. Links}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjUhhhhhMubhdefinition_list)}(hhh](hdefinition_list_item)}(h]RFC 5925 The TCP Authentication Option https://www.rfc-editor.org/rfc/pdfrfc/rfc5925.txt.pdf h](hterm)}(h&RFC 5925 The TCP Authentication Optionh]h&RFC 5925 The TCP Authentication Option}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jqhhhMhjmubh definition)}(hhh]h)}(h5https://www.rfc-editor.org/rfc/pdfrfc/rfc5925.txt.pdfh]h reference)}(hjh]h5https://www.rfc-editor.org/rfc/pdfrfc/rfc5925.txt.pdf}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jhjmubeh}(h]h ]h"]h$]h&]uh1jkhhhMhjhubjl)}(hRFC 5926 Cryptographic Algorithms for the TCP Authentication Option (TCP-AO) https://www.rfc-editor.org/rfc/pdfrfc/rfc5926.txt.pdf h](jr)}(hLRFC 5926 Cryptographic Algorithms for the TCP Authentication Option (TCP-AO)h]hLRFC 5926 Cryptographic Algorithms for the TCP Authentication Option (TCP-AO)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jqhhhMhjubj)}(hhh]h)}(h5https://www.rfc-editor.org/rfc/pdfrfc/rfc5926.txt.pdfh]j)}(hjh]h5https://www.rfc-editor.org/rfc/pdfrfc/rfc5926.txt.pdf}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jkhhhMhjhhhubjl)}(hDraft "SHA-2 Algorithm for the TCP Authentication Option (TCP-AO)" https://datatracker.ietf.org/doc/html/draft-nayak-tcp-sha2-03 h](jr)}(hBDraft "SHA-2 Algorithm for the TCP Authentication Option (TCP-AO)"h]hFDraft “SHA-2 Algorithm for the TCP Authentication Option (TCP-AO)”}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jqhhhMhjubj)}(hhh]h)}(h=https://datatracker.ietf.org/doc/html/draft-nayak-tcp-sha2-03h]j)}(hjh]h=https://datatracker.ietf.org/doc/html/draft-nayak-tcp-sha2-03}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jkhhhMhjhhhubjl)}(h{RFC 2385 Protection of BGP Sessions via the TCP MD5 Signature Option https://www.rfc-editor.org/rfc/pdfrfc/rfc2385.txt.pdf h](jr)}(hDRFC 2385 Protection of BGP Sessions via the TCP MD5 Signature Optionh]hDRFC 2385 Protection of BGP Sessions via the TCP MD5 Signature Option}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jqhhhMhjubj)}(hhh]h)}(h5https://www.rfc-editor.org/rfc/pdfrfc/rfc2385.txt.pdfh]j)}(hj5h]h5https://www.rfc-editor.org/rfc/pdfrfc/rfc2385.txt.pdf}(hj7hhhNhNubah}(h]h ]h"]h$]h&]refurij5uh1jhj3ubah}(h]h ]h"]h$]h&]uh1hhhhMhj0ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jkhhhMhjhhhubeh}(h]h ]h"]h$]h&]uh1jfhjUhhhhhNubh field_list)}(hhh]hfield)}(hhh](h field_name)}(hAuthorh]hAuthor}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1jghjdhhhKubh field_body)}(h Dmitry Safonov h]h)}(hj{h](hDmitry Safonov <}(hj}hhhNhNubj)}(hdima@arista.comh]hdima@arista.com}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:dima@arista.comuh1jhj}ubh>}(hj}hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjyubah}(h]h ]h"]h$]h&]uh1jwhjdubeh}(h]h ]h"]h$]h&]uh1jbhhhMhj_hhubah}(h]h ]h"]h$]h&]uh1j]hjUhhhhhMubeh}(h]linksah ]h"]7. linksah$]h&]uh1hhhhhhhhMubeh}(h]6tcp-authentication-option-linux-implementation-rfc5925ah ]h"]8tcp authentication option linux implementation (rfc5925)ah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksj,footnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jjjjjjj j j j jjjjjRjOjju nametypes}(jjjj j jjjRjuh}(jhjhjjHj j j j jj jjjOjjjUjChj jbu footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages]transform_messages] transformerN include_log] decorationNhhub.