Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * net/tipc/server.c: TIPC server infrastructure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 2012-2013, Wind River Systems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2017-2018, Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * modification, are permitted provided that the following conditions are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *    notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *    notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *    documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * 3. Neither the names of the copyright holders nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *    contributors may be used to endorse or promote products derived from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *    this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * Alternatively, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * GNU General Public License ("GPL") version 2 as published by the Free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include "subscr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include "topsrv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include "socket.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include "addr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include "msg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include "bearer.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /* Number of messages to send before rescheduling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define MAX_SEND_MSG_COUNT	25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define MAX_RECV_MSG_COUNT	25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define CF_CONNECTED		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define TIPC_SERVER_NAME_LEN	32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * struct tipc_topsrv - TIPC server structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * @conn_idr: identifier set of connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * @idr_lock: protect the connection identifier set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * @idr_in_use: amount of allocated identifier entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * @net: network namspace instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * @awork: accept work item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * @rcv_wq: receive workqueue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * @send_wq: send workqueue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * @listener: topsrv listener socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * @name: server name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) struct tipc_topsrv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct idr conn_idr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	spinlock_t idr_lock; /* for idr list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	int idr_in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct work_struct awork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct workqueue_struct *rcv_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct workqueue_struct *send_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct socket *listener;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	char name[TIPC_SERVER_NAME_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * struct tipc_conn - TIPC connection structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * @kref: reference counter to connection object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * @conid: connection identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * @sock: socket handler associated with connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * @flags: indicates connection state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * @server: pointer to connected server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * @sub_list: lsit to all pertaing subscriptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * @sub_lock: lock protecting the subscription list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * @rwork: receive work item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * @outqueue: pointer to first outbound message in queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * @outqueue_lock: control access to the outqueue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * @swork: send work item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) struct tipc_conn {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	struct kref kref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	int conid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	struct socket *sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	struct tipc_topsrv *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct list_head sub_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	spinlock_t sub_lock; /* for subscription list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	struct work_struct rwork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	struct list_head outqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	spinlock_t outqueue_lock; /* for outqueue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	struct work_struct swork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* An entry waiting to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct outqueue_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	bool inactive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	struct tipc_event evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static void tipc_conn_recv_work(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void tipc_conn_send_work(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void tipc_topsrv_kern_evt(struct net *net, struct tipc_event *evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static void tipc_conn_delete_sub(struct tipc_conn *con, struct tipc_subscr *s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static bool connected(struct tipc_conn *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	return con && test_bit(CF_CONNECTED, &con->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void tipc_conn_kref_release(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	struct tipc_topsrv *s = con->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	struct outqueue_entry *e, *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	spin_lock_bh(&s->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	idr_remove(&s->conn_idr, con->conid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	s->idr_in_use--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	spin_unlock_bh(&s->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (con->sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		sock_release(con->sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	spin_lock_bh(&con->outqueue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	list_for_each_entry_safe(e, safe, &con->outqueue, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		list_del(&e->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		kfree(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	spin_unlock_bh(&con->outqueue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	kfree(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static void conn_put(struct tipc_conn *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	kref_put(&con->kref, tipc_conn_kref_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static void conn_get(struct tipc_conn *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	kref_get(&con->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static void tipc_conn_close(struct tipc_conn *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	struct sock *sk = con->sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	bool disconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	write_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	disconnect = test_and_clear_bit(CF_CONNECTED, &con->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (disconnect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		sk->sk_user_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		tipc_conn_delete_sub(con, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	write_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	/* Handle concurrent calls from sending and receiving threads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (!disconnect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	/* Don't flush pending works, -just let them expire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	kernel_sock_shutdown(con->sock, SHUT_RDWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	conn_put(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	struct tipc_conn *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	con = kzalloc(sizeof(*con), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	if (!con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	kref_init(&con->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	INIT_LIST_HEAD(&con->outqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	INIT_LIST_HEAD(&con->sub_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	spin_lock_init(&con->outqueue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	spin_lock_init(&con->sub_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	INIT_WORK(&con->swork, tipc_conn_send_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	INIT_WORK(&con->rwork, tipc_conn_recv_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	spin_lock_bh(&s->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	ret = idr_alloc(&s->conn_idr, con, 0, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		kfree(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		spin_unlock_bh(&s->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	con->conid = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	s->idr_in_use++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	spin_unlock_bh(&s->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	set_bit(CF_CONNECTED, &con->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	con->server = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	return con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static struct tipc_conn *tipc_conn_lookup(struct tipc_topsrv *s, int conid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	struct tipc_conn *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	spin_lock_bh(&s->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	con = idr_find(&s->conn_idr, conid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (!connected(con) || !kref_get_unless_zero(&con->kref))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		con = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	spin_unlock_bh(&s->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	return con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* tipc_conn_delete_sub - delete a specific or all subscriptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  * for a given subscriber
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static void tipc_conn_delete_sub(struct tipc_conn *con, struct tipc_subscr *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	struct tipc_net *tn = tipc_net(con->server->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	struct list_head *sub_list = &con->sub_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	struct tipc_subscription *sub, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	spin_lock_bh(&con->sub_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	list_for_each_entry_safe(sub, tmp, sub_list, sub_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		if (!s || !memcmp(s, &sub->evt.s, sizeof(*s))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			tipc_sub_unsubscribe(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			atomic_dec(&tn->subscription_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			if (s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	spin_unlock_bh(&con->sub_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void tipc_conn_send_to_sock(struct tipc_conn *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	struct list_head *queue = &con->outqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	struct tipc_topsrv *srv = con->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	struct outqueue_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	struct tipc_event *evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	struct msghdr msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	struct kvec iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	spin_lock_bh(&con->outqueue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	while (!list_empty(queue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		e = list_first_entry(queue, struct outqueue_entry, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		evt = &e->evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		spin_unlock_bh(&con->outqueue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		if (e->inactive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			tipc_conn_delete_sub(con, &evt->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		memset(&msg, 0, sizeof(msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		msg.msg_flags = MSG_DONTWAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		iov.iov_base = evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		iov.iov_len = sizeof(*evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		msg.msg_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		if (con->sock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			ret = kernel_sendmsg(con->sock, &msg, &iov,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 					     1, sizeof(*evt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			if (ret == -EWOULDBLOCK || ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 				cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			} else if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 				return tipc_conn_close(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			tipc_topsrv_kern_evt(srv->net, evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		/* Don't starve users filling buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		if (++count >= MAX_SEND_MSG_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		spin_lock_bh(&con->outqueue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		list_del(&e->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		kfree(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	spin_unlock_bh(&con->outqueue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static void tipc_conn_send_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	struct tipc_conn *con = container_of(work, struct tipc_conn, swork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	if (connected(con))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		tipc_conn_send_to_sock(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	conn_put(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* tipc_topsrv_queue_evt() - interrupt level call from a subscription instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  * The queued work is launched into tipc_conn_send_work()->tipc_conn_send_to_sock()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) void tipc_topsrv_queue_evt(struct net *net, int conid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			   u32 event, struct tipc_event *evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	struct tipc_topsrv *srv = tipc_topsrv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	struct outqueue_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	struct tipc_conn *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	con = tipc_conn_lookup(srv, conid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (!con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	if (!connected(con))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	e = kmalloc(sizeof(*e), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	e->inactive = (event == TIPC_SUBSCR_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	memcpy(&e->evt, evt, sizeof(*evt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	spin_lock_bh(&con->outqueue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	list_add_tail(&e->list, &con->outqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	spin_unlock_bh(&con->outqueue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	if (queue_work(srv->send_wq, &con->swork))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	conn_put(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* tipc_conn_write_space - interrupt callback after a sendmsg EAGAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  * Indicates that there now is more space in the send buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  * The queued work is launched into tipc_send_work()->tipc_conn_send_to_sock()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static void tipc_conn_write_space(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	struct tipc_conn *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	read_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	con = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	if (connected(con)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		conn_get(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		if (!queue_work(con->server->send_wq, &con->swork))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			conn_put(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static int tipc_conn_rcv_sub(struct tipc_topsrv *srv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			     struct tipc_conn *con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			     struct tipc_subscr *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	struct tipc_net *tn = tipc_net(srv->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	struct tipc_subscription *sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	u32 s_filter = tipc_sub_read(s, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	if (s_filter & TIPC_SUB_CANCEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		tipc_sub_write(s, filter, s_filter & ~TIPC_SUB_CANCEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		tipc_conn_delete_sub(con, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		pr_warn("Subscription rejected, max (%u)\n", TIPC_MAX_SUBSCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	sub = tipc_sub_subscribe(srv->net, s, con->conid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	if (!sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	atomic_inc(&tn->subscription_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	spin_lock_bh(&con->sub_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	list_add(&sub->sub_list, &con->sub_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	spin_unlock_bh(&con->sub_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static int tipc_conn_rcv_from_sock(struct tipc_conn *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	struct tipc_topsrv *srv = con->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	struct sock *sk = con->sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	struct msghdr msg = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	struct tipc_subscr s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	struct kvec iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	iov.iov_base = &s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	iov.iov_len = sizeof(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	msg.msg_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, iov.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	if (ret == -EWOULDBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		return -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	if (ret == sizeof(s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		read_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		/* RACE: the connection can be closed in the meantime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		if (likely(connected(con)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			ret = tipc_conn_rcv_sub(srv, con, &s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	tipc_conn_close(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static void tipc_conn_recv_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	struct tipc_conn *con = container_of(work, struct tipc_conn, rwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	while (connected(con)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		if (tipc_conn_rcv_from_sock(con))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		/* Don't flood Rx machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		if (++count >= MAX_RECV_MSG_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	conn_put(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* tipc_conn_data_ready - interrupt callback indicating the socket has data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)  * The queued work is launched into tipc_recv_work()->tipc_conn_rcv_from_sock()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static void tipc_conn_data_ready(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	struct tipc_conn *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	read_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	con = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (connected(con)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		conn_get(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		if (!queue_work(con->server->rcv_wq, &con->rwork))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 			conn_put(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static void tipc_topsrv_accept(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	struct tipc_topsrv *srv = container_of(work, struct tipc_topsrv, awork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	struct socket *lsock = srv->listener;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	struct socket *newsock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	struct tipc_conn *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	struct sock *newsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		con = tipc_conn_alloc(srv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		if (IS_ERR(con)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			ret = PTR_ERR(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			sock_release(newsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		/* Register callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		newsk = newsock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		write_lock_bh(&newsk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		newsk->sk_data_ready = tipc_conn_data_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		newsk->sk_write_space = tipc_conn_write_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		newsk->sk_user_data = con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		con->sock = newsock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		write_unlock_bh(&newsk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		/* Wake up receive process in case of 'SYN+' message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		newsk->sk_data_ready(newsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* tipc_topsrv_listener_data_ready - interrupt callback with connection request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)  * The queued job is launched into tipc_topsrv_accept()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static void tipc_topsrv_listener_data_ready(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	struct tipc_topsrv *srv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	read_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	srv = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	if (srv->listener)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		queue_work(srv->rcv_wq, &srv->awork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int tipc_topsrv_create_listener(struct tipc_topsrv *srv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	struct socket *lsock = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	struct sockaddr_tipc saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	rc = sock_create_kern(srv->net, AF_TIPC, SOCK_SEQPACKET, 0, &lsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	srv->listener = lsock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	sk = lsock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	write_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	sk->sk_data_ready = tipc_topsrv_listener_data_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	sk->sk_user_data = srv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	write_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	rc = tsk_set_importance(sk, TIPC_CRITICAL_IMPORTANCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	saddr.family	                = AF_TIPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	saddr.addrtype		        = TIPC_ADDR_NAMESEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	saddr.addr.nameseq.type	        = TIPC_TOP_SRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	saddr.addr.nameseq.lower	= TIPC_TOP_SRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	saddr.addr.nameseq.upper	= TIPC_TOP_SRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	saddr.scope			= TIPC_NODE_SCOPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	rc = kernel_bind(lsock, (struct sockaddr *)&saddr, sizeof(saddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	rc = kernel_listen(lsock, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	/* As server's listening socket owner and creator is the same module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	 * we have to decrease TIPC module reference count to guarantee that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	 * it remains zero after the server socket is created, otherwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	 * executing "rmmod" command is unable to make TIPC module deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	 * after TIPC module is inserted successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	 * However, the reference count is ever increased twice in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	 * sock_create_kern(): one is to increase the reference count of owner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	 * of TIPC socket's proto_ops struct; another is to increment the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	 * reference count of owner of TIPC proto struct. Therefore, we must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	 * decrement the module reference count twice to ensure that it keeps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	 * zero after server's listening socket is created. Of course, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	 * must bump the module reference count twice as well before the socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	 * is closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	module_put(lsock->ops->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	module_put(sk->sk_prot_creator->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	sock_release(lsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 			     u32 upper, u32 filter, int *conid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	struct tipc_subscr sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	struct tipc_conn *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	sub.seq.type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	sub.seq.lower = lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	sub.seq.upper = upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	sub.timeout = TIPC_WAIT_FOREVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	sub.filter = filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	*(u32 *)&sub.usr_handle = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	con = tipc_conn_alloc(tipc_topsrv(net));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	if (IS_ERR(con))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	*conid = con->conid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	con->sock = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	if (rc >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	conn_put(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) void tipc_topsrv_kern_unsubscr(struct net *net, int conid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	struct tipc_conn *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	con = tipc_conn_lookup(tipc_topsrv(net), conid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	if (!con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	test_and_clear_bit(CF_CONNECTED, &con->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	tipc_conn_delete_sub(con, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	conn_put(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	conn_put(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static void tipc_topsrv_kern_evt(struct net *net, struct tipc_event *evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	u32 port = *(u32 *)&evt->s.usr_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	u32 self = tipc_own_addr(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	struct sk_buff_head evtq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	skb = tipc_msg_create(TOP_SRV, 0, INT_H_SIZE, sizeof(*evt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			      self, self, port, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	msg_set_dest_droppable(buf_msg(skb), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	memcpy(msg_data(buf_msg(skb)), evt, sizeof(*evt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	skb_queue_head_init(&evtq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	__skb_queue_tail(&evtq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	tipc_loopback_trace(net, &evtq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	tipc_sk_rcv(net, &evtq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int tipc_topsrv_work_start(struct tipc_topsrv *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	s->rcv_wq = alloc_ordered_workqueue("tipc_rcv", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	if (!s->rcv_wq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		pr_err("can't start tipc receive workqueue\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	s->send_wq = alloc_ordered_workqueue("tipc_send", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	if (!s->send_wq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		pr_err("can't start tipc send workqueue\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		destroy_workqueue(s->rcv_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static void tipc_topsrv_work_stop(struct tipc_topsrv *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	destroy_workqueue(s->rcv_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	destroy_workqueue(s->send_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static int tipc_topsrv_start(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	const char name[] = "topology_server";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	struct tipc_topsrv *srv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	srv = kzalloc(sizeof(*srv), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	if (!srv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	srv->net = net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	INIT_WORK(&srv->awork, tipc_topsrv_accept);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	strscpy(srv->name, name, sizeof(srv->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	tn->topsrv = srv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	atomic_set(&tn->subscription_count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	spin_lock_init(&srv->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	idr_init(&srv->conn_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	srv->idr_in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	ret = tipc_topsrv_work_start(srv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		goto err_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	ret = tipc_topsrv_create_listener(srv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		goto err_create;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) err_create:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	tipc_topsrv_work_stop(srv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) err_start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	kfree(srv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static void tipc_topsrv_stop(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	struct tipc_topsrv *srv = tipc_topsrv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	struct socket *lsock = srv->listener;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	struct tipc_conn *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	spin_lock_bh(&srv->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	for (id = 0; srv->idr_in_use; id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		con = idr_find(&srv->conn_idr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		if (con) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 			spin_unlock_bh(&srv->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 			tipc_conn_close(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 			spin_lock_bh(&srv->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	__module_get(lsock->ops->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	__module_get(lsock->sk->sk_prot_creator->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	srv->listener = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	spin_unlock_bh(&srv->idr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	sock_release(lsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	tipc_topsrv_work_stop(srv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	idr_destroy(&srv->conn_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	kfree(srv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int __net_init tipc_topsrv_init_net(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	return tipc_topsrv_start(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) void __net_exit tipc_topsrv_exit_net(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	tipc_topsrv_stop(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }