kernel: ksmbd: add max ip connection parameter
Some checks are pending
Build Kernel / Build all affected Kernels (push) Waiting to run
Build all core packages / Build all core packages for selected target (push) Waiting to run

With this patch is set the maximum number of connections per ip address instead of no control.
The default is 8.

Signed-off-by: Andrea Pesaresi <andreapesaresi82@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/20377
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Andrea Pesaresi 2025-10-11 10:10:29 +02:00 committed by Hauke Mehrtens
parent 711e14af79
commit e78f000869
6 changed files with 238 additions and 290 deletions

View file

@ -0,0 +1,119 @@
From d8b6dc9256762293048bf122fc11c4e612d0ef5d Mon Sep 17 00:00:00 2001
From: Namjae Jeon <linkinjeon@kernel.org>
Date: Wed, 1 Oct 2025 09:25:35 +0900
Subject: ksmbd: add max ip connections parameter
This parameter set the maximum number of connections per ip address.
The default is 8.
Cc: stable@vger.kernel.org
Fixes: c0d41112f1a5 ("ksmbd: extend the connection limiting mechanism to support IPv6")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
---
fs/smb/server/ksmbd_netlink.h | 5 +++--
fs/smb/server/server.h | 1 +
fs/smb/server/transport_ipc.c | 3 +++
fs/smb/server/transport_tcp.c | 27 ++++++++++++++++-----------
4 files changed, 23 insertions(+), 13 deletions(-)
(limited to 'fs/smb')
--- a/fs/smb/server/ksmbd_netlink.h
+++ b/fs/smb/server/ksmbd_netlink.h
@@ -112,10 +112,11 @@ struct ksmbd_startup_request {
__u32 smbd_max_io_size; /* smbd read write size */
__u32 max_connections; /* Number of maximum simultaneous connections */
__s8 bind_interfaces_only;
- __s8 reserved[503]; /* Reserved room */
+ __u32 max_ip_connections; /* Number of maximum connection per ip address */
+ __s8 reserved[499]; /* Reserved room */
__u32 ifc_list_sz; /* interfaces list size */
__s8 ____payload[];
-};
+} __packed;
#define KSMBD_STARTUP_CONFIG_INTERFACES(s) ((s)->____payload)
--- a/fs/smb/server/server.h
+++ b/fs/smb/server/server.h
@@ -43,6 +43,7 @@ struct ksmbd_server_config {
unsigned int auth_mechs;
unsigned int max_connections;
unsigned int max_inflight_req;
+ unsigned int max_ip_connections;
char *conf[SERVER_CONF_WORK_GROUP + 1];
struct task_struct *dh_task;
--- a/fs/smb/server/transport_ipc.c
+++ b/fs/smb/server/transport_ipc.c
@@ -335,6 +335,9 @@ static int ipc_server_config_on_startup(
if (req->max_connections)
server_conf.max_connections = req->max_connections;
+ if (req->max_ip_connections)
+ server_conf.max_ip_connections = req->max_ip_connections;
+
ret = ksmbd_set_netbios_name(req->netbios_name);
ret |= ksmbd_set_server_string(req->server_string);
ret |= ksmbd_set_work_group(req->work_group);
--- a/fs/smb/server/transport_tcp.c
+++ b/fs/smb/server/transport_tcp.c
@@ -240,6 +240,7 @@ static int ksmbd_kthread_fn(void *p)
struct interface *iface = (struct interface *)p;
struct ksmbd_conn *conn;
int ret;
+ unsigned int max_ip_conns;
while (!kthread_should_stop()) {
mutex_lock(&iface->sock_release_lock);
@@ -257,34 +258,38 @@ static int ksmbd_kthread_fn(void *p)
continue;
}
+ if (!server_conf.max_ip_connections)
+ goto skip_max_ip_conns_limit;
+
/*
* Limits repeated connections from clients with the same IP.
*/
+ max_ip_conns = 0;
down_read(&conn_list_lock);
- list_for_each_entry(conn, &conn_list, conns_list)
+ list_for_each_entry(conn, &conn_list, conns_list) {
#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;
- }
+ &conn->inet6_addr, 16) == 0)
+ max_ip_conns++;
} else if (inet_sk(client_sk->sk)->inet_daddr ==
- conn->inet_addr) {
- ret = -EAGAIN;
- break;
- }
+ conn->inet_addr)
+ max_ip_conns++;
#else
if (inet_sk(client_sk->sk)->inet_daddr ==
- conn->inet_addr) {
+ conn->inet_addr)
+ max_ip_conns++;
+#endif
+ if (server_conf.max_ip_connections <= max_ip_conns) {
ret = -EAGAIN;
break;
}
-#endif
+ }
up_read(&conn_list_lock);
if (ret == -EAGAIN)
continue;
+skip_max_ip_conns_limit:
if (server_conf.max_connections &&
atomic_inc_return(&active_num_conn) >= server_conf.max_connections) {
pr_info_ratelimited("Limit the maximum number of connections(%u)\n",

View file

@ -0,0 +1,119 @@
From d8b6dc9256762293048bf122fc11c4e612d0ef5d Mon Sep 17 00:00:00 2001
From: Namjae Jeon <linkinjeon@kernel.org>
Date: Wed, 1 Oct 2025 09:25:35 +0900
Subject: ksmbd: add max ip connections parameter
This parameter set the maximum number of connections per ip address.
The default is 8.
Cc: stable@vger.kernel.org
Fixes: c0d41112f1a5 ("ksmbd: extend the connection limiting mechanism to support IPv6")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
---
fs/smb/server/ksmbd_netlink.h | 5 +++--
fs/smb/server/server.h | 1 +
fs/smb/server/transport_ipc.c | 3 +++
fs/smb/server/transport_tcp.c | 27 ++++++++++++++++-----------
4 files changed, 23 insertions(+), 13 deletions(-)
(limited to 'fs/smb')
--- a/fs/smb/server/ksmbd_netlink.h
+++ b/fs/smb/server/ksmbd_netlink.h
@@ -109,10 +109,11 @@ struct ksmbd_startup_request {
__u32 smbd_max_io_size; /* smbd read write size */
__u32 max_connections; /* Number of maximum simultaneous connections */
__s8 bind_interfaces_only;
- __s8 reserved[503]; /* Reserved room */
+ __u32 max_ip_connections; /* Number of maximum connection per ip address */
+ __s8 reserved[499]; /* Reserved room */
__u32 ifc_list_sz; /* interfaces list size */
__s8 ____payload[];
-};
+} __packed;
#define KSMBD_STARTUP_CONFIG_INTERFACES(s) ((s)->____payload)
--- a/fs/smb/server/server.h
+++ b/fs/smb/server/server.h
@@ -43,6 +43,7 @@ struct ksmbd_server_config {
unsigned int auth_mechs;
unsigned int max_connections;
unsigned int max_inflight_req;
+ unsigned int max_ip_connections;
char *conf[SERVER_CONF_WORK_GROUP + 1];
};
--- a/fs/smb/server/transport_ipc.c
+++ b/fs/smb/server/transport_ipc.c
@@ -321,6 +321,9 @@ static int ipc_server_config_on_startup(
if (req->max_connections)
server_conf.max_connections = req->max_connections;
+ if (req->max_ip_connections)
+ server_conf.max_ip_connections = req->max_ip_connections;
+
ret = ksmbd_set_netbios_name(req->netbios_name);
ret |= ksmbd_set_server_string(req->server_string);
ret |= ksmbd_set_work_group(req->work_group);
--- a/fs/smb/server/transport_tcp.c
+++ b/fs/smb/server/transport_tcp.c
@@ -240,6 +240,7 @@ static int ksmbd_kthread_fn(void *p)
struct interface *iface = (struct interface *)p;
struct ksmbd_conn *conn;
int ret;
+ unsigned int max_ip_conns;
while (!kthread_should_stop()) {
mutex_lock(&iface->sock_release_lock);
@@ -257,34 +258,38 @@ static int ksmbd_kthread_fn(void *p)
continue;
}
+ if (!server_conf.max_ip_connections)
+ goto skip_max_ip_conns_limit;
+
/*
* Limits repeated connections from clients with the same IP.
*/
+ max_ip_conns = 0;
down_read(&conn_list_lock);
- list_for_each_entry(conn, &conn_list, conns_list)
+ list_for_each_entry(conn, &conn_list, conns_list) {
#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;
- }
+ &conn->inet6_addr, 16) == 0)
+ max_ip_conns++;
} else if (inet_sk(client_sk->sk)->inet_daddr ==
- conn->inet_addr) {
- ret = -EAGAIN;
- break;
- }
+ conn->inet_addr)
+ max_ip_conns++;
#else
if (inet_sk(client_sk->sk)->inet_daddr ==
- conn->inet_addr) {
+ conn->inet_addr)
+ max_ip_conns++;
+#endif
+ if (server_conf.max_ip_connections <= max_ip_conns) {
ret = -EAGAIN;
break;
}
-#endif
+ }
up_read(&conn_list_lock);
if (ret == -EAGAIN)
continue;
+skip_max_ip_conns_limit:
if (server_conf.max_connections &&
atomic_inc_return(&active_num_conn) >= server_conf.max_connections) {
pr_info_ratelimited("Limit the maximum number of connections(%u)\n",

View file

@ -1,83 +0,0 @@
From 7220ecc26a9a8e6766eb9ec7cd90fbba048ce7b3 Mon Sep 17 00:00:00 2001
From: Andrea Pesaresi <andreapesaresi82@gmail.com>
Date: Tue, 30 Sep 2025 19:35:36 +0200
Subject: Revert "ksmbd: extend the connection limiting mechanism to support
IPv6"
This reverts commit d9e157fcfebc126cd19b2333a6417a840c24e529.
---
fs/smb/server/connection.h | 7 +------
fs/smb/server/transport_tcp.c | 26 +++-----------------------
2 files changed, 4 insertions(+), 29 deletions(-)
--- a/fs/smb/server/connection.h
+++ b/fs/smb/server/connection.h
@@ -46,12 +46,7 @@ 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
- };
+ __be32 inet_addr;
char *request_buf;
struct ksmbd_transport *transport;
struct nls_table *local_nls;
--- a/fs/smb/server/transport_tcp.c
+++ b/fs/smb/server/transport_tcp.c
@@ -87,14 +87,7 @@ static struct tcp_transport *alloc_trans
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;
@@ -238,6 +231,7 @@ 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;
@@ -260,27 +254,13 @@ 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 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) {
+ if (csk_inet->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;

View file

@ -1,62 +0,0 @@
From 575b789e36cf4bfa85ba5b649673ede9b4c7b5d0 Mon Sep 17 00:00:00 2001
From: Andrea Pesaresi <andreapesaresi82@gmail.com>
Date: Tue, 30 Sep 2025 22:36:12 +0200
Subject: Revert "ksmbd: limit repeated connections from clients with the same
IP"
This reverts commit fa1c47af4ff641cf9197ecdb1f8240cbb30389c1.
---
fs/smb/server/connection.h | 1 -
fs/smb/server/transport_tcp.c | 17 -----------------
2 files changed, 18 deletions(-)
--- a/fs/smb/server/connection.h
+++ b/fs/smb/server/connection.h
@@ -46,7 +46,6 @@ struct ksmbd_conn {
struct mutex srv_mutex;
int status;
unsigned int cli_cap;
- __be32 inet_addr;
char *request_buf;
struct ksmbd_transport *transport;
struct nls_table *local_nls;
--- a/fs/smb/server/transport_tcp.c
+++ b/fs/smb/server/transport_tcp.c
@@ -87,7 +87,6 @@ static struct tcp_transport *alloc_trans
return NULL;
}
- conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
conn->transport = KSMBD_TRANS(t);
KSMBD_TRANS(t)->conn = conn;
KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops;
@@ -231,8 +230,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;
while (!kthread_should_stop()) {
@@ -251,20 +248,6 @@ static int ksmbd_kthread_fn(void *p)
continue;
}
- /*
- * 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) {
- ret = -EAGAIN;
- break;
- }
- up_read(&conn_list_lock);
- if (ret == -EAGAIN)
- continue;
-
if (server_conf.max_connections &&
atomic_inc_return(&active_num_conn) >= server_conf.max_connections) {
pr_info_ratelimited("Limit the maximum number of connections(%u)\n",

View file

@ -1,83 +0,0 @@
From a2002bb6f1b1dee2b1f3b1839f2d677c9a05fabc Mon Sep 17 00:00:00 2001
From: Andrea Pesaresi <andreapesaresi82@gmail.com>
Date: Tue, 30 Sep 2025 22:43:30 +0200
Subject: Revert "ksmbd: extend the connection limiting mechanism to support
IPv6"
This reverts commit d9e157fcfebc126cd19b2333a6417a840c24e529.
---
fs/smb/server/connection.h | 7 +------
fs/smb/server/transport_tcp.c | 26 +++-----------------------
2 files changed, 4 insertions(+), 29 deletions(-)
--- a/fs/smb/server/connection.h
+++ b/fs/smb/server/connection.h
@@ -46,12 +46,7 @@ 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
- };
+ __be32 inet_addr;
char *request_buf;
struct ksmbd_transport *transport;
struct nls_table *local_nls;
--- a/fs/smb/server/transport_tcp.c
+++ b/fs/smb/server/transport_tcp.c
@@ -87,14 +87,7 @@ static struct tcp_transport *alloc_trans
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;
@@ -238,6 +231,7 @@ 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;
@@ -260,27 +254,13 @@ 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 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) {
+ if (csk_inet->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;

View file

@ -1,62 +0,0 @@
From 7fe1a46e2d0bf2f4ca9da286be95c46c21111c0c Mon Sep 17 00:00:00 2001
From: Andrea Pesaresi <andreapesaresi82@gmail.com>
Date: Tue, 30 Sep 2025 22:44:36 +0200
Subject: Revert "ksmbd: limit repeated connections from clients with the same
IP"
This reverts commit fa1c47af4ff641cf9197ecdb1f8240cbb30389c1.
---
fs/smb/server/connection.h | 1 -
fs/smb/server/transport_tcp.c | 17 -----------------
2 files changed, 18 deletions(-)
--- a/fs/smb/server/connection.h
+++ b/fs/smb/server/connection.h
@@ -46,7 +46,6 @@ struct ksmbd_conn {
struct mutex srv_mutex;
int status;
unsigned int cli_cap;
- __be32 inet_addr;
char *request_buf;
struct ksmbd_transport *transport;
struct nls_table *local_nls;
--- a/fs/smb/server/transport_tcp.c
+++ b/fs/smb/server/transport_tcp.c
@@ -87,7 +87,6 @@ static struct tcp_transport *alloc_trans
return NULL;
}
- conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
conn->transport = KSMBD_TRANS(t);
KSMBD_TRANS(t)->conn = conn;
KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops;
@@ -231,8 +230,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;
while (!kthread_should_stop()) {
@@ -251,20 +248,6 @@ static int ksmbd_kthread_fn(void *p)
continue;
}
- /*
- * 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) {
- ret = -EAGAIN;
- break;
- }
- up_read(&conn_list_lock);
- if (ret == -EAGAIN)
- continue;
-
if (server_conf.max_connections &&
atomic_inc_return(&active_num_conn) >= server_conf.max_connections) {
pr_info_ratelimited("Limit the maximum number of connections(%u)\n",