* Re: [PATCH 14/31] net/tcp: Add TCP-AO sign to twsk
@ 2022-08-27 4:39 kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2022-08-27 4:39 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 4043 bytes --]
BCC: lkp(a)intel.com
CC: kbuild-all(a)lists.01.org
In-Reply-To: <20220818170005.747015-15-dima@arista.com>
References: <20220818170005.747015-15-dima@arista.com>
TO: Dmitry Safonov <dima@arista.com>
TO: Eric Dumazet <edumazet@google.com>
TO: "David S. Miller" <davem@davemloft.net>
CC: netdev(a)vger.kernel.org
TO: linux-kernel(a)vger.kernel.org
CC: Dmitry Safonov <dima@arista.com>
CC: Andy Lutomirski <luto@amacapital.net>
CC: Ard Biesheuvel <ardb@kernel.org>
CC: Bob Gilligan <gilligan@arista.com>
CC: David Ahern <dsahern@kernel.org>
CC: Eric Biggers <ebiggers@kernel.org>
CC: Francesco Ruggeri <fruggeri@arista.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
CC: Ivan Delalande <colona@arista.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Leonard Crestez <cdleonard@gmail.com>
CC: Paolo Abeni <pabeni@redhat.com>
CC: Salam Noureddine <noureddine@arista.com>
CC: Shuah Khan <skhan@linuxfoundation.org>
CC: linux-crypto(a)vger.kernel.org
Hi Dmitry,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on e34cfee65ec891a319ce79797dda18083af33a76]
url: https://github.com/intel-lab-lkp/linux/commits/Dmitry-Safonov/net-tcp-Add-TCP-AO-support/20220819-010628
base: e34cfee65ec891a319ce79797dda18083af33a76
:::::: branch date: 9 days ago
:::::: commit date: 9 days ago
config: x86_64-randconfig-c002 (https://download.01.org/0day-ci/archive/20220827/202208271241.MAJo5i2m-lkp(a)intel.com/config)
compiler: gcc-11 (Debian 11.3.0-5) 11.3.0
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Julia Lawall <julia.lawall@lip6.fr>
cocci warnings: (new ones prefixed by >>)
>> net/ipv4/tcp_ao.c:214:13-32: atomic_dec_and_test variation before object free at line 218.
net/ipv4/tcp_ao.c:214:13-32: atomic_dec_and_test variation before object free at line 224.
vim +214 net/ipv4/tcp_ao.c
469bd71e5ea011f Dmitry Safonov 2022-08-18 199
5e1471f5e8131f9 Dmitry Safonov 2022-08-18 200 void tcp_ao_destroy_sock(struct sock *sk, bool twsk)
469bd71e5ea011f Dmitry Safonov 2022-08-18 201 {
469bd71e5ea011f Dmitry Safonov 2022-08-18 202 struct tcp_ao_info *ao;
469bd71e5ea011f Dmitry Safonov 2022-08-18 203 struct tcp_ao_key *key;
469bd71e5ea011f Dmitry Safonov 2022-08-18 204 struct hlist_node *n;
469bd71e5ea011f Dmitry Safonov 2022-08-18 205
5e1471f5e8131f9 Dmitry Safonov 2022-08-18 206 if (twsk) {
5e1471f5e8131f9 Dmitry Safonov 2022-08-18 207 ao = rcu_dereference_protected(tcp_twsk(sk)->ao_info, 1);
5e1471f5e8131f9 Dmitry Safonov 2022-08-18 208 tcp_twsk(sk)->ao_info = NULL;
5e1471f5e8131f9 Dmitry Safonov 2022-08-18 209 } else {
469bd71e5ea011f Dmitry Safonov 2022-08-18 210 ao = rcu_dereference_protected(tcp_sk(sk)->ao_info, 1);
469bd71e5ea011f Dmitry Safonov 2022-08-18 211 tcp_sk(sk)->ao_info = NULL;
5e1471f5e8131f9 Dmitry Safonov 2022-08-18 212 }
469bd71e5ea011f Dmitry Safonov 2022-08-18 213
5e1471f5e8131f9 Dmitry Safonov 2022-08-18 @214 if (!ao || !atomic_dec_and_test(&ao->refcnt))
469bd71e5ea011f Dmitry Safonov 2022-08-18 215 return;
469bd71e5ea011f Dmitry Safonov 2022-08-18 216
469bd71e5ea011f Dmitry Safonov 2022-08-18 217 hlist_for_each_entry_safe(key, n, &ao->head, node) {
469bd71e5ea011f Dmitry Safonov 2022-08-18 @218 hlist_del_rcu(&key->node);
5e1471f5e8131f9 Dmitry Safonov 2022-08-18 219 if (!twsk)
469bd71e5ea011f Dmitry Safonov 2022-08-18 220 atomic_sub(tcp_ao_sizeof_key(key), &sk->sk_omem_alloc);
469bd71e5ea011f Dmitry Safonov 2022-08-18 221 call_rcu(&key->rcu, tcp_ao_key_free_rcu);
469bd71e5ea011f Dmitry Safonov 2022-08-18 222 }
469bd71e5ea011f Dmitry Safonov 2022-08-18 223
469bd71e5ea011f Dmitry Safonov 2022-08-18 224 kfree_rcu(ao, rcu);
469bd71e5ea011f Dmitry Safonov 2022-08-18 225 }
469bd71e5ea011f Dmitry Safonov 2022-08-18 226
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 2+ messages in thread* [PATCH 00/31] net/tcp: Add TCP-AO support @ 2022-08-18 16:59 Dmitry Safonov 2022-08-18 16:59 ` [PATCH 14/31] net/tcp: Add TCP-AO sign to twsk Dmitry Safonov 0 siblings, 1 reply; 2+ messages in thread From: Dmitry Safonov @ 2022-08-18 16:59 UTC (permalink / raw) To: Eric Dumazet, David S. Miller, linux-kernel Cc: Dmitry Safonov, Andy Lutomirski, Ard Biesheuvel, Bob Gilligan, David Ahern, Dmitry Safonov, Eric Biggers, Francesco Ruggeri, Herbert Xu, Hideaki YOSHIFUJI, Ivan Delalande, Jakub Kicinski, Leonard Crestez, Paolo Abeni, Salam Noureddine, Shuah Khan, netdev, linux-crypto This patchset implements the TCP-AO option as described in RFC5925. There is a request from industry to move away from TCP-MD5SIG and it seems the time is right to have a TCP-AO upstreamed. This TCP option is meant to replace the TCP MD5 option and address its shortcomings. Specifically, it provides more secure hashing, key rotation and support for long-lived connections (see the summary of TCP-AO advantages over TCP-MD5 in (1.3) of RFC5925). The patch series starts with six patches that are not specific to TCP-AO but implement a general crypto facility that we thought is useful to eliminate code duplication between TCP-MD5SIG and TCP-AO as well as other crypto users. These six patches are being submitted separately in a different patchset [1]. Including them here will show better the gain in code sharing. Next are 18 patches that implement the actual TCP-AO option, followed by patches implementing selftests. The patch set was written as a collaboration of three authors (in alphabetical order): Dmitry Safonov, Francesco Ruggeri and Salam Noureddine. Additional credits should be given to Prasad Koya, who was involved in early prototyping a few years back. There is also a separate submission done by Leonard Crestez whom we thank for his efforts getting an implementation of RFC5925 submitted for review upstream [2]. This is an independent implementation that makes different design decisions. For example, we chose a similar design to the TCP-MD5SIG implementation and used setsockopt()s to program per-socket keys, avoiding the extra complexity of managing a centralized key database in the kernel. A centralized database in the kernel has dubious benefits since it doesn’t eliminate per-socket setsockopts needed to specify which sockets need TCP-AO and what are the currently preferred keys. It also complicates traffic key caching and preventing deletion of in-use keys. In this implementation, a centralized database of keys can be thought of as living in user space and user applications would have to program those keys on matching sockets. On the server side, the user application programs keys (MKTS in TCP-AO nomenclature) on the listening socket for all peers that are expected to connect. Prefix matching on the peer address is supported. When a peer issues a successful connect, all the MKTs matching the IP address of the peer are copied to the newly created socket. On the active side, when a connect() is issued all MKTs that do not match the peer are deleted from the socket since they will never match the peer. This implementation uses three setsockopt()s for adding, deleting and modifying keys on a socket. All three setsockopt()s have extensive sanity checks that prevent inconsistencies in the keys on a given socket. A getsockopt() is provided to get key information from any given socket. Few things to note about this implementation: - Traffic keys are cached for established connections avoiding the cost of such calculation for each packet received or sent. - Great care has been taken to avoid deleting in-use MKTs as required by the RFC. - Any crypto algorithm supported by the Linux kernel can be used to calculate packet hashes. - Fastopen works with TCP-AO but hasn’t been tested extensively. - Tested for interop with other major networking vendors (on linux-4.19), including testing for key rotation and long lived connections. There are a couple of limitations that we’re aware of, including (but not limited to) the following: - setsockopt(TCP_REPAIR) not supported yet - IPv4-mapped-IPv6 addresses not tested - static key not implemented yet - CONFIG_TCP_AO depends on CONFIG_TCP_MD5SIG - A small window for a race condition exists between accept and key adding/deletion on a listening socket but can be easily overcome by using the getsockopt() to make sure the right keys are there on a newly accepted connection - Key matching by TCP port numbers, peer ranges, asterisks is unsupported as it’s unlikely to be useful [1]: https://lore.kernel.org/all/20220726201600.1715505-1-dima@arista.com/ [2]: https://lore.kernel.org/all/cover.1658815925.git.cdleonard@gmail.com/ Cc: Andy Lutomirski <luto@amacapital.net> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Bob Gilligan <gilligan@arista.com> Cc: David Ahern <dsahern@kernel.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Dmitry Safonov <0x7f454c46@gmail.com> Cc: Eric Biggers <ebiggers@kernel.org> Cc: Eric Dumazet <edumazet@google.com> Cc: Francesco Ruggeri <fruggeri@arista.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> Cc: Ivan Delalande <colona@arista.com> Cc: Jakub Kicinski <kuba@kernel.org> Cc: Leonard Crestez <cdleonard@gmail.com> Cc: Paolo Abeni <pabeni@redhat.com> Cc: Salam Noureddine <noureddine@arista.com> Cc: Shuah Khan <shuah@kernel.org> Cc: netdev@vger.kernel.org Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Dmitry Safonov (31): crypto: Introduce crypto_pool crypto_pool: Add crypto_pool_reserve_scratch() net/tcp: Separate tcp_md5sig_info allocation into tcp_md5sig_info_add() net/tcp: Disable TCP-MD5 static key on tcp_md5sig_info destruction net/tcp: Use crypto_pool for TCP-MD5 net/ipv6: sr: Switch to using crypto_pool tcp: Add TCP-AO config and structures net/tcp: Introduce TCP_AO setsockopt()s net/tcp: Prevent TCP-MD5 with TCP-AO being set net/tcp: Calculate TCP-AO traffic keys net/tcp: Add TCP-AO sign to outgoing packets net/tcp: Add tcp_parse_auth_options() net/tcp: Add AO sign to RST packets net/tcp: Add TCP-AO sign to twsk net/tcp: Wire TCP-AO to request sockets net/tcp: Sign SYN-ACK segments with TCP-AO net/tcp: Verify inbound TCP-AO signed segments net/tcp: Add TCP-AO segments counters net/tcp: Add TCP-AO SNE support net/tcp: Add tcp_hash_fail() ratelimited logs net/tcp: Ignore specific ICMPs for TCP-AO connections net/tcp: Add option for TCP-AO to (not) hash header net/tcp: Add getsockopt(TCP_AO_GET) net/tcp: Allow asynchronous delete for TCP-AO keys (MKTs) selftests/net: Add TCP-AO library selftests/net: Verify that TCP-AO complies with ignoring ICMPs selftest/net: Add TCP-AO ICMPs accept test selftest/tcp-ao: Add a test for MKT matching selftest/tcp-ao: Add test for TCP-AO add setsockopt() command selftests/tcp-ao: Add TCP-AO + TCP-MD5 + no sign listen socket tests selftests/aolib: Add test/benchmark for removing MKTs crypto/Kconfig | 12 + crypto/Makefile | 1 + crypto/crypto_pool.c | 323 +++ include/crypto/pool.h | 33 + include/linux/sockptr.h | 23 + include/linux/tcp.h | 24 + include/net/dropreason.h | 25 + include/net/seg6_hmac.h | 7 - include/net/tcp.h | 193 +- include/net/tcp_ao.h | 283 +++ include/uapi/linux/snmp.h | 5 + include/uapi/linux/tcp.h | 62 + net/ipv4/Kconfig | 15 +- net/ipv4/Makefile | 1 + net/ipv4/proc.c | 5 + net/ipv4/tcp.c | 191 +- net/ipv4/tcp_ao.c | 1939 +++++++++++++++++ net/ipv4/tcp_input.c | 94 +- net/ipv4/tcp_ipv4.c | 385 +++- net/ipv4/tcp_minisocks.c | 37 +- net/ipv4/tcp_output.c | 188 +- net/ipv6/Kconfig | 2 +- net/ipv6/Makefile | 1 + net/ipv6/seg6.c | 3 - net/ipv6/seg6_hmac.c | 204 +- net/ipv6/tcp_ao.c | 151 ++ net/ipv6/tcp_ipv6.c | 327 ++- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/net/tcp_ao/.gitignore | 2 + tools/testing/selftests/net/tcp_ao/Makefile | 50 + .../selftests/net/tcp_ao/bench-lookups.c | 403 ++++ .../selftests/net/tcp_ao/connect-deny.c | 217 ++ tools/testing/selftests/net/tcp_ao/connect.c | 81 + .../selftests/net/tcp_ao/icmps-accept.c | 1 + .../selftests/net/tcp_ao/icmps-discard.c | 447 ++++ .../testing/selftests/net/tcp_ao/lib/aolib.h | 333 +++ .../selftests/net/tcp_ao/lib/netlink.c | 341 +++ tools/testing/selftests/net/tcp_ao/lib/proc.c | 267 +++ .../testing/selftests/net/tcp_ao/lib/setup.c | 297 +++ tools/testing/selftests/net/tcp_ao/lib/sock.c | 294 +++ .../testing/selftests/net/tcp_ao/lib/utils.c | 30 + .../selftests/net/tcp_ao/setsockopt-closed.c | 191 ++ .../selftests/net/tcp_ao/unsigned-md5.c | 483 ++++ 43 files changed, 7516 insertions(+), 456 deletions(-) create mode 100644 crypto/crypto_pool.c create mode 100644 include/crypto/pool.h create mode 100644 include/net/tcp_ao.h create mode 100644 net/ipv4/tcp_ao.c create mode 100644 net/ipv6/tcp_ao.c create mode 100644 tools/testing/selftests/net/tcp_ao/.gitignore create mode 100644 tools/testing/selftests/net/tcp_ao/Makefile create mode 100644 tools/testing/selftests/net/tcp_ao/bench-lookups.c create mode 100644 tools/testing/selftests/net/tcp_ao/connect-deny.c create mode 100644 tools/testing/selftests/net/tcp_ao/connect.c create mode 120000 tools/testing/selftests/net/tcp_ao/icmps-accept.c create mode 100644 tools/testing/selftests/net/tcp_ao/icmps-discard.c create mode 100644 tools/testing/selftests/net/tcp_ao/lib/aolib.h create mode 100644 tools/testing/selftests/net/tcp_ao/lib/netlink.c create mode 100644 tools/testing/selftests/net/tcp_ao/lib/proc.c create mode 100644 tools/testing/selftests/net/tcp_ao/lib/setup.c create mode 100644 tools/testing/selftests/net/tcp_ao/lib/sock.c create mode 100644 tools/testing/selftests/net/tcp_ao/lib/utils.c create mode 100644 tools/testing/selftests/net/tcp_ao/setsockopt-closed.c create mode 100644 tools/testing/selftests/net/tcp_ao/unsigned-md5.c base-commit: e34cfee65ec891a319ce79797dda18083af33a76 -- 2.37.2 ^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH 14/31] net/tcp: Add TCP-AO sign to twsk 2022-08-18 16:59 [PATCH 00/31] net/tcp: Add TCP-AO support Dmitry Safonov @ 2022-08-18 16:59 ` Dmitry Safonov 0 siblings, 0 replies; 2+ messages in thread From: Dmitry Safonov @ 2022-08-18 16:59 UTC (permalink / raw) To: Eric Dumazet, David S. Miller, linux-kernel Cc: Dmitry Safonov, Andy Lutomirski, Ard Biesheuvel, Bob Gilligan, David Ahern, Dmitry Safonov, Eric Biggers, Francesco Ruggeri, Herbert Xu, Hideaki YOSHIFUJI, Ivan Delalande, Jakub Kicinski, Leonard Crestez, Paolo Abeni, Salam Noureddine, Shuah Khan, netdev, linux-crypto Add support for sockets in time-wait state. ao_info as well as all keys are inherited on transition to time-wait socket. The lifetime of ao_info is now protected by ref counter, so that tcp_ao_destroy_sock() will destruct it only when the last user is gone. Co-developed-by: Francesco Ruggeri <fruggeri@arista.com> Signed-off-by: Francesco Ruggeri <fruggeri@arista.com> Co-developed-by: Salam Noureddine <noureddine@arista.com> Signed-off-by: Salam Noureddine <noureddine@arista.com> Signed-off-by: Dmitry Safonov <dima@arista.com> --- include/linux/tcp.h | 3 ++ include/net/tcp_ao.h | 11 +++++-- net/ipv4/tcp_ao.c | 47 ++++++++++++++++++++++---- net/ipv4/tcp_ipv4.c | 71 ++++++++++++++++++++++++++++++++++++---- net/ipv4/tcp_minisocks.c | 4 ++- net/ipv6/tcp_ipv6.c | 47 +++++++++++++++++++++++--- 6 files changed, 161 insertions(+), 22 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index c8a8aaaf725b..8031995b58a2 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -489,6 +489,9 @@ struct tcp_timewait_sock { #ifdef CONFIG_TCP_MD5SIG struct tcp_md5sig_key *tw_md5_key; #endif +#ifdef CONFIG_TCP_AO + struct tcp_ao_info *ao_info; +#endif }; static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) diff --git a/include/net/tcp_ao.h b/include/net/tcp_ao.h index 35c33f7e9c27..af82b4aeef11 100644 --- a/include/net/tcp_ao.h +++ b/include/net/tcp_ao.h @@ -85,6 +85,7 @@ struct tcp_ao_info { u32 snd_sne_seq; u32 rcv_sne; u32 rcv_sne_seq; + atomic_t refcnt; /* Protects twsk destruction */ }; int tcp_do_parse_auth_options(const struct tcphdr *th, @@ -120,8 +121,9 @@ int tcp_parse_ao(struct sock *sk, int cmd, unsigned short int family, struct tcp_ao_key *tcp_ao_do_lookup_sndid(const struct sock *sk, u8 keyid); int tcp_ao_calc_traffic_key(struct tcp_ao_key *mkt, u8 *key, void *ctx, unsigned int len); -void tcp_ao_destroy_sock(struct sock *sk); +void tcp_ao_destroy_sock(struct sock *sk, bool twsk); u32 tcp_ao_compute_sne(u32 sne, u32 seq, u32 new_seq); +void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw, struct tcp_sock *tp); int tcp_ao_cache_traffic_keys(const struct sock *sk, struct tcp_ao_info *ao, struct tcp_ao_key *ao_key); struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk, @@ -170,7 +172,7 @@ static inline struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk, return NULL; } -static inline void tcp_ao_destroy_sock(struct sock *sk) +static inline void tcp_ao_destroy_sock(struct sock *sk, bool twsk) { } @@ -178,6 +180,11 @@ static inline void tcp_ao_finish_connect(struct sock *sk, struct sk_buff *skb) { } +static inline void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw, + struct tcp_sock *tp) +{ +} + static inline void tcp_ao_connect_init(struct sock *sk) { } diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c index 4bdd97536610..528b6650c72c 100644 --- a/net/ipv4/tcp_ao.c +++ b/net/ipv4/tcp_ao.c @@ -75,8 +75,13 @@ struct tcp_ao_key *tcp_ao_do_lookup_sndid(const struct sock *sk, u8 keyid) struct tcp_ao_key *key; struct tcp_ao_info *ao; - ao = rcu_dereference_check(tcp_sk(sk)->ao_info, - lockdep_sock_is_held(sk)); + if (sk->sk_state == TCP_TIME_WAIT) + ao = rcu_dereference_check(tcp_twsk(sk)->ao_info, + lockdep_sock_is_held(sk)); + else + ao = rcu_dereference_check(tcp_sk(sk)->ao_info, + lockdep_sock_is_held(sk)); + if (!ao) return NULL; @@ -172,6 +177,7 @@ static struct tcp_ao_info *tcp_ao_alloc_info(gfp_t flags, if (!ao) return NULL; INIT_HLIST_HEAD(&ao->head); + atomic_set(&ao->refcnt, 1); if (cloned_from) ao->ao_flags = cloned_from->ao_flags; @@ -191,27 +197,54 @@ static void tcp_ao_key_free_rcu(struct rcu_head *head) kfree(key); } -void tcp_ao_destroy_sock(struct sock *sk) +void tcp_ao_destroy_sock(struct sock *sk, bool twsk) { struct tcp_ao_info *ao; struct tcp_ao_key *key; struct hlist_node *n; - ao = rcu_dereference_protected(tcp_sk(sk)->ao_info, 1); - tcp_sk(sk)->ao_info = NULL; + if (twsk) { + ao = rcu_dereference_protected(tcp_twsk(sk)->ao_info, 1); + tcp_twsk(sk)->ao_info = NULL; + } else { + ao = rcu_dereference_protected(tcp_sk(sk)->ao_info, 1); + tcp_sk(sk)->ao_info = NULL; + } - if (!ao) + if (!ao || !atomic_dec_and_test(&ao->refcnt)) return; hlist_for_each_entry_safe(key, n, &ao->head, node) { hlist_del_rcu(&key->node); - atomic_sub(tcp_ao_sizeof_key(key), &sk->sk_omem_alloc); + if (!twsk) + atomic_sub(tcp_ao_sizeof_key(key), &sk->sk_omem_alloc); call_rcu(&key->rcu, tcp_ao_key_free_rcu); } kfree_rcu(ao, rcu); } +void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw, struct tcp_sock *tp) +{ + struct tcp_ao_info *ao_info = rcu_dereference_protected(tp->ao_info, 1); + + if (ao_info) { + struct tcp_ao_key *key; + struct hlist_node *n; + int omem = 0; + + hlist_for_each_entry_safe(key, n, &ao_info->head, node) { + omem += tcp_ao_sizeof_key(key); + } + + atomic_inc(&ao_info->refcnt); + atomic_sub(omem, &(((struct sock *)tp)->sk_omem_alloc)); + rcu_assign_pointer(tcptw->ao_info, ao_info); + } else { + tcptw->ao_info = NULL; + } +} + /* 4 tuple and ISNs are expected in NBO */ static int tcp_v4_ao_calc_key(struct tcp_ao_key *mkt, u8 *key, __be32 saddr, __be32 daddr, diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index c0add782d7af..003c5f320bfc 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -801,7 +801,10 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) struct tcp_ao_info *ao_info; u8 keyid; - ao_info = rcu_dereference(tcp_sk(sk)->ao_info); + if (sk->sk_state == TCP_TIME_WAIT) + ao_info = rcu_dereference(tcp_twsk(sk)->ao_info); + else + ao_info = rcu_dereference(tcp_sk(sk)->ao_info); /* XXX: optimize by using cached traffic key depending * on socket state @@ -902,16 +905,16 @@ static void tcp_v4_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, struct tcp_md5sig_key *key, + struct tcp_ao_key *ao_key, + u8 *traffic_key, + u8 rcv_next, + u32 ao_sne, int reply_flags, u8 tos) { const struct tcphdr *th = tcp_hdr(skb); struct { struct tcphdr th; - __be32 opt[(TCPOLEN_TSTAMP_ALIGNED >> 2) -#ifdef CONFIG_TCP_MD5SIG - + (TCPOLEN_MD5SIG_ALIGNED >> 2) -#endif - ]; + __be32 opt[(MAX_TCP_OPTION_SPACE >> 2)]; } rep; struct net *net = sock_net(sk); struct ip_reply_arg arg; @@ -957,6 +960,25 @@ static void tcp_v4_send_ack(const struct sock *sk, ip_hdr(skb)->daddr, &rep.th); } #endif +#ifdef CONFIG_TCP_AO + if (ao_key) { + int offset = (tsecr) ? 3 : 0; + + rep.opt[offset++] = htonl((TCPOPT_AO << 24) | + (tcp_ao_len(ao_key) << 16) | + (ao_key->sndid << 8) | rcv_next); + arg.iov[0].iov_len += round_up(tcp_ao_len(ao_key), 4); + rep.th.doff = arg.iov[0].iov_len / 4; + + tcp_ao_hash_hdr(AF_INET, (char *)&rep.opt[offset], + ao_key, traffic_key, + (union tcp_ao_addr *)&ip_hdr(skb)->saddr, + (union tcp_ao_addr *)&ip_hdr(skb)->daddr, + &rep.th, ao_sne); + } + WARN_ON_ONCE(key && ao_key); +#endif + /* XXX: TCP-AO: hash ACK header */ arg.flags = reply_flags; arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, ip_hdr(skb)->saddr, /* XXX */ @@ -990,6 +1012,36 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) { struct inet_timewait_sock *tw = inet_twsk(sk); struct tcp_timewait_sock *tcptw = tcp_twsk(sk); + struct tcp_ao_key *ao_key = NULL; + u8 *traffic_key = NULL; + u8 rcv_next = 0; + u32 ao_sne = 0; +#ifdef CONFIG_TCP_AO + struct tcp_ao_info *ao_info = NULL; + const struct tcp_ao_hdr *aoh; +#endif + +#ifdef CONFIG_TCP_AO + if (tcp_parse_auth_options(tcp_hdr(skb), NULL, &aoh)) + goto out; /* something is wrong with the sign */ + + /* FIXME: we haven't verified the segment to-be-acked */ + if (aoh) + ao_key = tcp_ao_do_lookup_sndid(sk, aoh->rnext_keyid); + + if (ao_key) { + traffic_key = snd_other_key(ao_key); + ao_info = rcu_dereference(tcptw->ao_info); + /* It's possible we can get rid of computing the sne + * below since sne probably doesn't change once we are + * in timewait state. + */ + ao_sne = tcp_ao_compute_sne(ao_info->snd_sne, + ao_info->snd_sne_seq, + tcptw->tw_snd_nxt); + rcv_next = ao_info->rnext_key->rcvid; + } +#endif tcp_v4_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, @@ -998,10 +1050,14 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), + ao_key, traffic_key, rcv_next, ao_sne, tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0, tw->tw_tos ); +#ifdef CONFIG_TCP_AO +out: +#endif inet_twsk_put(tw); } @@ -1031,6 +1087,7 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, req->ts_recent, 0, tcp_md5_do_lookup(sk, l3index, addr, AF_INET), + NULL, NULL, 0, 0, inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, ip_hdr(skb)->tos); } @@ -2367,7 +2424,7 @@ void tcp_v4_destroy_sock(struct sock *sk) rcu_assign_pointer(tp->md5sig_info, NULL); } #endif - tcp_ao_destroy_sock(sk); + tcp_ao_destroy_sock(sk, false); /* Clean up a referenced TCP bind bucket. */ if (inet_csk(sk)->icsk_bind_hash) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index d1d30337ffec..94012a015bd0 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -246,7 +246,7 @@ EXPORT_SYMBOL(tcp_timewait_state_process); void tcp_time_wait(struct sock *sk, int state, int timeo) { const struct inet_connection_sock *icsk = inet_csk(sk); - const struct tcp_sock *tp = tcp_sk(sk); + struct tcp_sock *tp = tcp_sk(sk); struct inet_timewait_sock *tw; struct inet_timewait_death_row *tcp_death_row = sock_net(sk)->ipv4.tcp_death_row; @@ -305,6 +305,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) } } while (0); #endif + tcp_ao_time_wait(tcptw, tp); /* Get the TIME_WAIT timeout firing. */ if (timeo < rto) @@ -359,6 +360,7 @@ void tcp_twsk_destructor(struct sock *sk) call_rcu(&twsk->tw_md5_key->rcu, tcp_md5_twsk_free_rcu); } #endif + tcp_ao_destroy_sock(sk, true); } EXPORT_SYMBOL_GPL(tcp_twsk_destructor); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index f5d339d5291a..bab4a1883b3c 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1112,7 +1112,10 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) ao_key = tcp_ao_do_lookup_sndid(sk, aoh->rnext_keyid); if (ao_key) { - ao_info = rcu_dereference(tcp_sk(sk)->ao_info); + if (sk->sk_state == TCP_TIME_WAIT) + ao_info = rcu_dereference(tcp_twsk(sk)->ao_info); + else + ao_info = rcu_dereference(tcp_sk(sk)->ao_info); /* XXX: optimize by using cached traffic key depending * on socket state @@ -1161,23 +1164,56 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, struct tcp_md5sig_key *key, u8 tclass, - __be32 label, u32 priority) + __be32 label, u32 priority, + struct tcp_ao_key *ao_key, char *tkey, + u8 rcv_next, u32 ao_sne) { tcp_v6_send_response(sk, skb, seq, ack, win, tsval, tsecr, oif, key, 0, - tclass, label, priority, NULL, NULL, 0, 0); + tclass, label, priority, + ao_key, tkey, rcv_next, ao_sne); } static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) { struct inet_timewait_sock *tw = inet_twsk(sk); struct tcp_timewait_sock *tcptw = tcp_twsk(sk); + struct tcp_ao_key *ao_key = NULL; + u8 *traffic_key = NULL; + u8 rcv_next = 0; + u32 ao_sne = 0; +#ifdef CONFIG_TCP_AO + struct tcp_ao_info *ao_info; + const struct tcp_ao_hdr *aoh; + + ao_info = rcu_dereference(tcptw->ao_info); + if (ao_info) { + /* Invalid TCP option size or twice included auth */ + if (tcp_parse_auth_options(tcp_hdr(skb), NULL, &aoh)) + goto out; + /* FIXME: we haven't verified the segment to-be-acked */ + if (aoh) + ao_key = tcp_ao_do_lookup_sndid(sk, aoh->rnext_keyid); + if (ao_key) { + traffic_key = snd_other_key(ao_key); + /* rcv_next switches to our rcv_next */ + rcv_next = ao_info->rnext_key->rcvid; + ao_sne = tcp_ao_compute_sne(ao_info->snd_sne, + ao_info->snd_sne_seq, + tcptw->tw_snd_nxt); + } + } +#endif tcp_v6_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, tcp_time_stamp_raw() + tcptw->tw_ts_offset, tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), - tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), tw->tw_priority); + tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), tw->tw_priority, + ao_key, traffic_key, rcv_next, ao_sne); +#ifdef CONFIG_TCP_AO +out: +#endif inet_twsk_put(tw); } @@ -1203,7 +1239,8 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, req->ts_recent, sk->sk_bound_dev_if, tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index), - ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority); + ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority, + NULL, NULL, 0, 0); } -- 2.37.2 ^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-08-27 4:39 UTC | newest] Thread overview: 2+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-08-27 4:39 [PATCH 14/31] net/tcp: Add TCP-AO sign to twsk kernel test robot -- strict thread matches above, loose matches on Subject: below -- 2022-08-18 16:59 [PATCH 00/31] net/tcp: Add TCP-AO support Dmitry Safonov 2022-08-18 16:59 ` [PATCH 14/31] net/tcp: Add TCP-AO sign to twsk Dmitry Safonov
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.