Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Namjae Jeon and committed by
Steve French
d8b6dc92 88daf2f4

+23 -13
+3 -2
fs/smb/server/ksmbd_netlink.h
··· 112 112 __u32 smbd_max_io_size; /* smbd read write size */ 113 113 __u32 max_connections; /* Number of maximum simultaneous connections */ 114 114 __s8 bind_interfaces_only; 115 - __s8 reserved[503]; /* Reserved room */ 115 + __u32 max_ip_connections; /* Number of maximum connection per ip address */ 116 + __s8 reserved[499]; /* Reserved room */ 116 117 __u32 ifc_list_sz; /* interfaces list size */ 117 118 __s8 ____payload[]; 118 - }; 119 + } __packed; 119 120 120 121 #define KSMBD_STARTUP_CONFIG_INTERFACES(s) ((s)->____payload) 121 122
+1
fs/smb/server/server.h
··· 43 43 unsigned int auth_mechs; 44 44 unsigned int max_connections; 45 45 unsigned int max_inflight_req; 46 + unsigned int max_ip_connections; 46 47 47 48 char *conf[SERVER_CONF_WORK_GROUP + 1]; 48 49 struct task_struct *dh_task;
+3
fs/smb/server/transport_ipc.c
··· 335 335 if (req->max_connections) 336 336 server_conf.max_connections = req->max_connections; 337 337 338 + if (req->max_ip_connections) 339 + server_conf.max_ip_connections = req->max_ip_connections; 340 + 338 341 ret = ksmbd_set_netbios_name(req->netbios_name); 339 342 ret |= ksmbd_set_server_string(req->server_string); 340 343 ret |= ksmbd_set_work_group(req->work_group);
+16 -11
fs/smb/server/transport_tcp.c
··· 225 225 struct interface *iface = (struct interface *)p; 226 226 struct ksmbd_conn *conn; 227 227 int ret; 228 + unsigned int max_ip_conns; 228 229 229 230 while (!kthread_should_stop()) { 230 231 mutex_lock(&iface->sock_release_lock); ··· 243 242 continue; 244 243 } 245 244 245 + if (!server_conf.max_ip_connections) 246 + goto skip_max_ip_conns_limit; 247 + 246 248 /* 247 249 * Limits repeated connections from clients with the same IP. 248 250 */ 251 + max_ip_conns = 0; 249 252 down_read(&conn_list_lock); 250 - list_for_each_entry(conn, &conn_list, conns_list) 253 + list_for_each_entry(conn, &conn_list, conns_list) { 251 254 #if IS_ENABLED(CONFIG_IPV6) 252 255 if (client_sk->sk->sk_family == AF_INET6) { 253 256 if (memcmp(&client_sk->sk->sk_v6_daddr, 254 - &conn->inet6_addr, 16) == 0) { 255 - ret = -EAGAIN; 256 - break; 257 - } 257 + &conn->inet6_addr, 16) == 0) 258 + max_ip_conns++; 258 259 } else if (inet_sk(client_sk->sk)->inet_daddr == 259 - conn->inet_addr) { 260 - ret = -EAGAIN; 261 - break; 262 - } 260 + conn->inet_addr) 261 + max_ip_conns++; 263 262 #else 264 263 if (inet_sk(client_sk->sk)->inet_daddr == 265 - conn->inet_addr) { 264 + conn->inet_addr) 265 + max_ip_conns++; 266 + #endif 267 + if (server_conf.max_ip_connections <= max_ip_conns) { 266 268 ret = -EAGAIN; 267 269 break; 268 270 } 269 - #endif 271 + } 270 272 up_read(&conn_list_lock); 271 273 if (ret == -EAGAIN) 272 274 continue; 273 275 276 + skip_max_ip_conns_limit: 274 277 if (server_conf.max_connections && 275 278 atomic_inc_return(&active_num_conn) >= server_conf.max_connections) { 276 279 pr_info_ratelimited("Limit the maximum number of connections(%u)\n",