summaryrefslogtreecommitdiff
path: root/net/rds
diff options
context:
space:
mode:
authorAllison Henderson <achender@kernel.org>2026-10-19 17:28:15 -0700
committerJakub Kicinski <kuba@kernel.org>2026-10-23 15:16:44 -0700
commitb7dfff5e3eb3984d42026a6d653ec2a3d5cec729 (patch)
tree498ea0f9b0a99fd03f8a39d7b530efeff6dfddfc /net/rds
parent520631554a689d2cd52452578f3140f045730ee0 (diff)
net/rds: include the scope id in the sendmsg connection cache check
rds_sendmsg() reuses the connection cached in rs->rs_conn when its peer address and ToS match the request. The interface index is part of a connection's identity as well: rds_conn_create_outgoing() passes the request's scope_id down as dev_if, and rds_conn_lookup() compares c_dev_if, so sends to the same link-local address through two interfaces are two different connections. The cache-hit test never looked at it. A socket bound to a non-link-local address has rs_bound_scope_id 0, and the scope check at the top of rds_sendmsg() accepts any non-zero destination scope for such a socket. So after a send to fe80::x%ifA, a send to fe80::x%ifB hits the cached ifA connection and the datagram leaves through ifA, to whichever peer answers to that address there. Compare c_dev_if with the request's scope_id in the cache test, so that such a send takes the lookup path and finds, or creates, the ifB connection - the same key the lookup uses. A send without a destination takes its scope from the socket, and the connection it created was keyed on that same scope, so the comparison holds for it too; the next patch gives that send the connected peer's own scope. Found by inspection while reworking this cache for the connection lifetime series on net-next; not observed in the field. Fixes: 1e2b44e78eea ("rds: Enable RDS IPv6 support") Signed-off-by: Allison Henderson <achender@kernel.org> Link: https://patch.msgid.link/20261020002816.3087414-2-achender@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/send.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/rds/send.c b/net/rds/send.c
index 1afa981e5c06..38b9cc9e0d20 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -1342,7 +1342,8 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
/* rds_conn_create has a spinlock that runs with IRQ off.
* Caching the conn in the socket helps a lot. */
if (rs->rs_conn && ipv6_addr_equal(&rs->rs_conn->c_faddr, &daddr) &&
- rs->rs_tos == rs->rs_conn->c_tos) {
+ rs->rs_tos == rs->rs_conn->c_tos &&
+ rs->rs_conn->c_dev_if == scope_id) {
conn = rs->rs_conn;
} else {
conn = rds_conn_create_outgoing(sock_net(sock->sk),