ksmbd: extend the connection limiting mechanism to support IPv6

Update the connection tracking logic to handle both IPv4 and IPv6
address families.

Cc: stable@vger.kernel.org
Fixes: e6bb919397 ("ksmbd: limit repeated connections from clients with the same IP")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
Namjae Jeon
2025-08-17 09:48:40 +09:00
committed by Steve French
parent bac7b996d4
commit c0d41112f1
2 changed files with 29 additions and 4 deletions

View File

@@ -46,7 +46,12 @@ struct ksmbd_conn {
struct mutex srv_mutex;
int status;
unsigned int cli_cap;
union {
__be32 inet_addr;
#if IS_ENABLED(CONFIG_IPV6)
u8 inet6_addr[16];
#endif
};
char *request_buf;
struct ksmbd_transport *transport;
struct nls_table *local_nls;

View File

@@ -85,7 +85,14 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk)
return NULL;
}
#if IS_ENABLED(CONFIG_IPV6)
if (client_sk->sk->sk_family == AF_INET6)
memcpy(&conn->inet6_addr, &client_sk->sk->sk_v6_daddr, 16);
else
conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
#else
conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
#endif
conn->transport = KSMBD_TRANS(t);
KSMBD_TRANS(t)->conn = conn;
KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops;
@@ -229,7 +236,6 @@ static int ksmbd_kthread_fn(void *p)
{
struct socket *client_sk = NULL;
struct interface *iface = (struct interface *)p;
struct inet_sock *csk_inet;
struct ksmbd_conn *conn;
int ret;
@@ -252,13 +258,27 @@ static int ksmbd_kthread_fn(void *p)
/*
* Limits repeated connections from clients with the same IP.
*/
csk_inet = inet_sk(client_sk->sk);
down_read(&conn_list_lock);
list_for_each_entry(conn, &conn_list, conns_list)
if (csk_inet->inet_daddr == conn->inet_addr) {
#if IS_ENABLED(CONFIG_IPV6)
if (client_sk->sk->sk_family == AF_INET6) {
if (memcmp(&client_sk->sk->sk_v6_daddr,
&conn->inet6_addr, 16) == 0) {
ret = -EAGAIN;
break;
}
} else if (inet_sk(client_sk->sk)->inet_daddr ==
conn->inet_addr) {
ret = -EAGAIN;
break;
}
#else
if (inet_sk(client_sk->sk)->inet_daddr ==
conn->inet_addr) {
ret = -EAGAIN;
break;
}
#endif
up_read(&conn_list_lock);
if (ret == -EAGAIN)
continue;