]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ksmbd: browse interfaces list on FSCTL_QUERY_INTERFACE_INFO IOCTL
authorNamjae Jeon <linkinjeon@kernel.org>
Tue, 21 Oct 2025 07:40:04 +0000 (16:40 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Oct 2025 13:04:42 +0000 (14:04 +0100)
[ Upstream commit b2d99376c5d61eb60ffdb6c503e4b6c8f9712ddd ]

ksmbd.mount will give each interfaces list and bind_interfaces_only flags
to ksmbd server. Previously, the interfaces list was sent only
when bind_interfaces_only was enabled.
ksmbd server browse only interfaces list given from ksmbd.conf on
FSCTL_QUERY_INTERFACE_INFO IOCTL.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/smb/server/ksmbd_netlink.h
fs/smb/server/server.h
fs/smb/server/smb2pdu.c
fs/smb/server/transport_ipc.c
fs/smb/server/transport_tcp.c
fs/smb/server/transport_tcp.h

index d3c0b985eb8c15f2b133aaa33b6f3edfc6574d7c..475de7289e2209a1f1aec73d33517a10cbc4edae 100644 (file)
@@ -107,8 +107,9 @@ struct ksmbd_startup_request {
        __u32   smb2_max_credits;       /* MAX credits */
        __u32   smbd_max_io_size;       /* smbd read write size */
        __u32   max_connections;        /* Number of maximum simultaneous connections */
+       __s8    bind_interfaces_only;
        __u32   max_ip_connections;     /* Number of maximum connection per ip address */
-       __u32   reserved[125];          /* Reserved room */
+       __s8    reserved[499];          /* Reserved room */
        __u32   ifc_list_sz;            /* interfaces list size */
        __s8    ____payload[];
 } __packed;
index 2cb1b855a39e2ee7a9884ecba1746149ba7f1225..3cdeda5d0c20eb778ea64ba6e173286e720bc0cb 100644 (file)
@@ -45,6 +45,7 @@ struct ksmbd_server_config {
        unsigned int            max_ip_connections;
 
        char                    *conf[SERVER_CONF_WORK_GROUP + 1];
+       bool                    bind_interfaces_only;
 };
 
 extern struct ksmbd_server_config server_conf;
index 5cf14a910d5bcfe55c7424841d47e09ca563a515..d2dca5d2f17cb88f4d010cbccf0e001fb5bdae50 100644 (file)
@@ -37,6 +37,7 @@
 #include "mgmt/user_session.h"
 #include "mgmt/ksmbd_ida.h"
 #include "ndr.h"
+#include "transport_tcp.h"
 
 static void __wbuf(struct ksmbd_work *work, void **req, void **rsp)
 {
@@ -7423,6 +7424,9 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
                if (netdev->type == ARPHRD_LOOPBACK)
                        continue;
 
+               if (!ksmbd_find_netdev_name_iface_list(netdev->name))
+                       continue;
+
                flags = dev_get_flags(netdev);
                if (!(flags & IFF_RUNNING))
                        continue;
index 3ca820d0b8d62ce7b500bbf9f9a0e72a5f624ef0..85837ba47d902b6608d500ea7bc826f794036c14 100644 (file)
@@ -324,6 +324,7 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)
        ret = ksmbd_set_netbios_name(req->netbios_name);
        ret |= ksmbd_set_server_string(req->server_string);
        ret |= ksmbd_set_work_group(req->work_group);
+       server_conf.bind_interfaces_only = req->bind_interfaces_only;
        ret |= ksmbd_tcp_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req),
                                        req->ifc_list_sz);
 out:
index 4ef032e737f37cfcfa2b1118c7d99eab9c7fbaa5..f07b9e147fe2da50e4c2b1870d026c7cff581c11 100644 (file)
@@ -544,30 +544,37 @@ out_clear:
        return ret;
 }
 
+struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name)
+{
+       struct interface *iface;
+
+       list_for_each_entry(iface, &iface_list, entry)
+               if (!strcmp(iface->name, netdev_name))
+                       return iface;
+       return NULL;
+}
+
 static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,
                              void *ptr)
 {
        struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
        struct interface *iface;
-       int ret, found = 0;
+       int ret;
 
        switch (event) {
        case NETDEV_UP:
                if (netif_is_bridge_port(netdev))
                        return NOTIFY_OK;
 
-               list_for_each_entry(iface, &iface_list, entry) {
-                       if (!strcmp(iface->name, netdev->name)) {
-                               found = 1;
-                               if (iface->state != IFACE_STATE_DOWN)
-                                       break;
-                               ret = create_socket(iface);
-                               if (ret)
-                                       return NOTIFY_OK;
-                               break;
-                       }
+               iface = ksmbd_find_netdev_name_iface_list(netdev->name);
+               if (iface && iface->state == IFACE_STATE_DOWN) {
+                       ksmbd_debug(CONN, "netdev-up event: netdev(%s) is going up\n",
+                                       iface->name);
+                       ret = create_socket(iface);
+                       if (ret)
+                               return NOTIFY_OK;
                }
-               if (!found && bind_additional_ifaces) {
+               if (!iface && bind_additional_ifaces) {
                        iface = alloc_iface(kstrdup(netdev->name, GFP_KERNEL));
                        if (!iface)
                                return NOTIFY_OK;
@@ -577,19 +584,19 @@ static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,
                }
                break;
        case NETDEV_DOWN:
-               list_for_each_entry(iface, &iface_list, entry) {
-                       if (!strcmp(iface->name, netdev->name) &&
-                           iface->state == IFACE_STATE_CONFIGURED) {
-                               tcp_stop_kthread(iface->ksmbd_kthread);
-                               iface->ksmbd_kthread = NULL;
-                               mutex_lock(&iface->sock_release_lock);
-                               tcp_destroy_socket(iface->ksmbd_socket);
-                               iface->ksmbd_socket = NULL;
-                               mutex_unlock(&iface->sock_release_lock);
-
-                               iface->state = IFACE_STATE_DOWN;
-                               break;
-                       }
+               iface = ksmbd_find_netdev_name_iface_list(netdev->name);
+               if (iface && iface->state == IFACE_STATE_CONFIGURED) {
+                       ksmbd_debug(CONN, "netdev-down event: netdev(%s) is going down\n",
+                                       iface->name);
+                       tcp_stop_kthread(iface->ksmbd_kthread);
+                       iface->ksmbd_kthread = NULL;
+                       mutex_lock(&iface->sock_release_lock);
+                       tcp_destroy_socket(iface->ksmbd_socket);
+                       iface->ksmbd_socket = NULL;
+                       mutex_unlock(&iface->sock_release_lock);
+
+                       iface->state = IFACE_STATE_DOWN;
+                       break;
                }
                break;
        }
@@ -658,18 +665,6 @@ int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz)
        int sz = 0;
 
        if (!ifc_list_sz) {
-               struct net_device *netdev;
-
-               rtnl_lock();
-               for_each_netdev(&init_net, netdev) {
-                       if (netif_is_bridge_port(netdev))
-                               continue;
-                       if (!alloc_iface(kstrdup(netdev->name, GFP_KERNEL))) {
-                               rtnl_unlock();
-                               return -ENOMEM;
-                       }
-               }
-               rtnl_unlock();
                bind_additional_ifaces = 1;
                return 0;
        }
index e338bebe322f10269b4bacc00b2d488fd04ee4e0..8c9aa624cfe3cad9f853a1fc4f878b0acc5b35c9 100644 (file)
@@ -7,6 +7,7 @@
 #define __KSMBD_TRANSPORT_TCP_H__
 
 int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz);
+struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name);
 int ksmbd_tcp_init(void);
 void ksmbd_tcp_destroy(void);