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/group.c: TIPC group messaging code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 2017, Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * modification, are permitted provided that the following conditions are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *    notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *    notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *    documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * 3. Neither the names of the copyright holders nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *    contributors may be used to endorse or promote products derived from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *    this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * Alternatively, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * GNU General Public License ("GPL") version 2 as published by the Free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * 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  33)  * POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include "addr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include "group.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include "bcast.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include "topsrv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include "msg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include "socket.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include "node.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include "name_table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include "subscr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define ADV_UNIT (((MAX_MSG_SIZE + MAX_H_SIZE) / FLOWCTL_BLK_SZ) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define ADV_IDLE ADV_UNIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define ADV_ACTIVE (ADV_UNIT * 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) enum mbr_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	MBR_JOINING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	MBR_PUBLISHED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	MBR_JOINED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	MBR_PENDING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	MBR_ACTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	MBR_RECLAIMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	MBR_REMITTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	MBR_LEAVING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) struct tipc_member {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct rb_node tree_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct list_head small_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	struct sk_buff_head deferredq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct tipc_group *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	u32 node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	u32 port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	u32 instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	enum mbr_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	u16 advertised;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	u16 window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	u16 bc_rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	u16 bc_syncpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	u16 bc_acked;
^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_group {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct rb_root members;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	struct list_head small_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	struct list_head pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	struct list_head active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct tipc_nlist dests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	int subid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	u32 instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	u32 scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	u32 portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	u16 member_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	u16 active_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	u16 max_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	u16 bc_snd_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	u16 bc_ackers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	bool *open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	bool loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	bool events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 				  int mtyp, struct sk_buff_head *xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static void tipc_group_open(struct tipc_member *m, bool *wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	*wakeup = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (list_empty(&m->small_win))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	list_del_init(&m->small_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	*m->group->open = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	*wakeup = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void tipc_group_decr_active(struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 				   struct tipc_member *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	    m->state == MBR_REMITTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		grp->active_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int tipc_group_rcvbuf_limit(struct tipc_group *grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	int max_active, active_pool, idle_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	int mcnt = grp->member_cnt + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	/* Limit simultaneous reception from other members */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	max_active = min(mcnt / 8, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	max_active = max(max_active, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	grp->max_active = max_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	/* Reserve blocks for active and idle members */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	active_pool = max_active * ADV_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	idle_pool = (mcnt - max_active) * ADV_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	/* Scale to bytes, considering worst-case truesize/msgsize ratio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	return (active_pool + idle_pool) * FLOWCTL_BLK_SZ * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u16 tipc_group_bc_snd_nxt(struct tipc_group *grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	return grp->bc_snd_nxt;
^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 bool tipc_group_is_receiver(struct tipc_member *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	return m && m->state != MBR_JOINING && m->state != MBR_LEAVING;
^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 bool tipc_group_is_sender(struct tipc_member *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	return m && m->state != MBR_JOINING && m->state != MBR_PUBLISHED;
^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) u32 tipc_group_exclude(struct tipc_group *grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (!grp->loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		return grp->portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct tipc_group *tipc_group_create(struct net *net, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 				     struct tipc_group_req *mreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 				     bool *group_is_open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	u32 filter = TIPC_SUB_PORTS | TIPC_SUB_NO_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	bool global = mreq->scope != TIPC_NODE_SCOPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	struct tipc_group *grp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	u32 type = mreq->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	grp = kzalloc(sizeof(*grp), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (!grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	tipc_nlist_init(&grp->dests, tipc_own_addr(net));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	INIT_LIST_HEAD(&grp->small_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	INIT_LIST_HEAD(&grp->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	INIT_LIST_HEAD(&grp->pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	grp->members = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	grp->net = net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	grp->portid = portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	grp->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	grp->instance = mreq->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	grp->scope = mreq->scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	grp->loopback = mreq->flags & TIPC_GROUP_LOOPBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	grp->events = mreq->flags & TIPC_GROUP_MEMBER_EVTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	grp->open = group_is_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	*grp->open = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	filter |= global ? TIPC_SUB_CLUSTER_SCOPE : TIPC_SUB_NODE_SCOPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (tipc_topsrv_kern_subscr(net, portid, type, 0, ~0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 				    filter, &grp->subid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		return grp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	kfree(grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) void tipc_group_join(struct net *net, struct tipc_group *grp, int *sk_rcvbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	struct rb_root *tree = &grp->members;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	struct tipc_member *m, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	struct sk_buff_head xmitq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	__skb_queue_head_init(&xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	rbtree_postorder_for_each_entry_safe(m, tmp, tree, tree_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, &xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		tipc_group_update_member(m, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	tipc_node_distr_xmit(net, &xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	*sk_rcvbuf = tipc_group_rcvbuf_limit(grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) void tipc_group_delete(struct net *net, struct tipc_group *grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	struct rb_root *tree = &grp->members;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	struct tipc_member *m, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	struct sk_buff_head xmitq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	__skb_queue_head_init(&xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	rbtree_postorder_for_each_entry_safe(m, tmp, tree, tree_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		tipc_group_proto_xmit(grp, m, GRP_LEAVE_MSG, &xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		__skb_queue_purge(&m->deferredq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		list_del(&m->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		kfree(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	tipc_node_distr_xmit(net, &xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	tipc_nlist_purge(&grp->dests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	tipc_topsrv_kern_unsubscr(net, grp->subid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	kfree(grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static struct tipc_member *tipc_group_find_member(struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 						  u32 node, u32 port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	struct rb_node *n = grp->members.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	u64 nkey, key = (u64)node << 32 | port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct tipc_member *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		m = container_of(n, struct tipc_member, tree_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		nkey = (u64)m->node << 32 | m->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		if (key < nkey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		else if (key > nkey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			return m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static struct tipc_member *tipc_group_find_dest(struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 						u32 node, u32 port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	struct tipc_member *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	m = tipc_group_find_member(grp, node, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (m && tipc_group_is_receiver(m))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		return m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static struct tipc_member *tipc_group_find_node(struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 						u32 node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	struct tipc_member *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	for (n = rb_first(&grp->members); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		m = container_of(n, struct tipc_member, tree_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		if (m->node == node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			return m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int tipc_group_add_to_tree(struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 				  struct tipc_member *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	u64 nkey, key = (u64)m->node << 32 | m->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	struct rb_node **n, *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	struct tipc_member *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	n = &grp->members.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	while (*n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		tmp = container_of(*n, struct tipc_member, tree_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		parent = *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		tmp = container_of(parent, struct tipc_member, tree_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		nkey = (u64)tmp->node << 32 | tmp->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		if (key < nkey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			n = &(*n)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		else if (key > nkey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			n = &(*n)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	rb_link_node(&m->tree_node, parent, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	rb_insert_color(&m->tree_node, &grp->members);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 						    u32 node, u32 port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 						    u32 instance, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	struct tipc_member *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	m = kzalloc(sizeof(*m), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	INIT_LIST_HEAD(&m->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	INIT_LIST_HEAD(&m->small_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	__skb_queue_head_init(&m->deferredq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	m->group = grp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	m->node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	m->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	m->instance = instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	m->bc_acked = grp->bc_snd_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	ret = tipc_group_add_to_tree(grp, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		kfree(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	grp->member_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	tipc_nlist_add(&grp->dests, m->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	m->state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	return m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) void tipc_group_add_member(struct tipc_group *grp, u32 node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			   u32 port, u32 instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	tipc_group_create_member(grp, node, port, instance, MBR_PUBLISHED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static void tipc_group_delete_member(struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 				     struct tipc_member *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	rb_erase(&m->tree_node, &grp->members);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	grp->member_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	/* Check if we were waiting for replicast ack from this member */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	if (grp->bc_ackers && less(m->bc_acked, grp->bc_snd_nxt - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		grp->bc_ackers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	list_del_init(&m->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	list_del_init(&m->small_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	tipc_group_decr_active(grp, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	/* If last member on a node, remove node from dest list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	if (!tipc_group_find_node(grp, m->node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		tipc_nlist_del(&grp->dests, m->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	kfree(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct tipc_nlist *tipc_group_dests(struct tipc_group *grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	return &grp->dests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) void tipc_group_self(struct tipc_group *grp, struct tipc_name_seq *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		     int *scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	seq->type = grp->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	seq->lower = grp->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	seq->upper = grp->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	*scope = grp->scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) void tipc_group_update_member(struct tipc_member *m, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	struct tipc_group *grp = m->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	struct tipc_member *_m, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	if (!tipc_group_is_receiver(m))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	m->window -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (m->window >= ADV_IDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	list_del_init(&m->small_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	/* Sort member into small_window members' list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	list_for_each_entry_safe(_m, tmp, &grp->small_win, small_win) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		if (_m->window > m->window)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	list_add_tail(&m->small_win, &_m->small_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	u16 prev = grp->bc_snd_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	struct tipc_member *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	u16 ackers = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	for (n = rb_first(&grp->members); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		m = container_of(n, struct tipc_member, tree_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		if (tipc_group_is_receiver(m)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			tipc_group_update_member(m, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			m->bc_acked = prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			ackers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	/* Mark number of acknowledges to expect, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	if (ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		grp->bc_ackers = ackers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	grp->bc_snd_nxt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) bool tipc_group_cong(struct tipc_group *grp, u32 dnode, u32 dport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		     int len, struct tipc_member **mbr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	struct sk_buff_head xmitq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	struct tipc_member *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	int adv, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	m = tipc_group_find_dest(grp, dnode, dport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	if (!tipc_group_is_receiver(m)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		*mbr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	*mbr = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	if (m->window >= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	*grp->open = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	/* If not fully advertised, do it now to prevent mutual blocking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	adv = m->advertised;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	state = m->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	if (state == MBR_JOINED && adv == ADV_IDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	if (state == MBR_ACTIVE && adv == ADV_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (state == MBR_PENDING && adv == ADV_IDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	__skb_queue_head_init(&xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, &xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	tipc_node_distr_xmit(grp->net, &xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	return true;
^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) bool tipc_group_bc_cong(struct tipc_group *grp, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	struct tipc_member *m = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	/* If prev bcast was replicast, reject until all receivers have acked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	if (grp->bc_ackers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		*grp->open = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	if (list_empty(&grp->small_win))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	m = list_first_entry(&grp->small_win, struct tipc_member, small_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	if (m->window >= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	return tipc_group_cong(grp, m->node, m->port, len, &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* tipc_group_sort_msg() - sort msg into queue by bcast sequence number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static void tipc_group_sort_msg(struct sk_buff *skb, struct sk_buff_head *defq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	struct tipc_msg *_hdr, *hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	u16 bc_seqno = msg_grp_bc_seqno(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	struct sk_buff *_skb, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	int mtyp = msg_type(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	/* Bcast/mcast may be bypassed by ucast or other bcast, - sort it in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	if (mtyp == TIPC_GRP_BCAST_MSG || mtyp == TIPC_GRP_MCAST_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		skb_queue_walk_safe(defq, _skb, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 			_hdr = buf_msg(_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			if (!less(bc_seqno, msg_grp_bc_seqno(_hdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			__skb_queue_before(defq, _skb, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		/* Bcast was not bypassed, - add to tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	/* Unicasts are never bypassed, - always add to tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	__skb_queue_tail(defq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* tipc_group_filter_msg() - determine if we should accept arriving message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) void tipc_group_filter_msg(struct tipc_group *grp, struct sk_buff_head *inputq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 			   struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	struct sk_buff *skb = __skb_dequeue(inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	bool ack, deliver, update, leave = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	struct sk_buff_head *defq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	struct tipc_member *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	u32 node, port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	int mtyp, blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	node =  msg_orignode(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	port = msg_origport(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	if (!msg_in_group(hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	m = tipc_group_find_member(grp, node, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	if (!tipc_group_is_sender(m))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	if (less(msg_grp_bc_seqno(hdr), m->bc_rcv_nxt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	TIPC_SKB_CB(skb)->orig_member = m->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	defq = &m->deferredq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	tipc_group_sort_msg(skb, defq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	while ((skb = skb_peek(defq))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		mtyp = msg_type(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		blks = msg_blocks(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		deliver = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		ack = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		if (more(msg_grp_bc_seqno(hdr), m->bc_rcv_nxt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		/* Decide what to do with message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		switch (mtyp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		case TIPC_GRP_MCAST_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			if (msg_nameinst(hdr) != grp->instance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 				update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 				deliver = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		case TIPC_GRP_BCAST_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 			m->bc_rcv_nxt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 			ack = msg_grp_bc_ack_req(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		case TIPC_GRP_UCAST_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		case TIPC_GRP_MEMBER_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			if (m->state == MBR_LEAVING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 				leave = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 			if (!grp->events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 				deliver = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		/* Execute decisions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		__skb_dequeue(defq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		if (deliver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			__skb_queue_tail(inputq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		if (ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			tipc_group_proto_xmit(grp, m, GRP_ACK_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		if (leave) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			__skb_queue_purge(defq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			tipc_group_delete_member(grp, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		if (!update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		tipc_group_update_rcv_win(grp, blks, node, port, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 			       u32 port, struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	struct list_head *active = &grp->active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	int max_active = grp->max_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	int reclaim_limit = max_active * 3 / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	int active_cnt = grp->active_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	struct tipc_member *m, *rm, *pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	m = tipc_group_find_member(grp, node, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	m->advertised -= blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	switch (m->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	case MBR_JOINED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		/* First, decide if member can go active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		if (active_cnt <= max_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			m->state = MBR_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 			list_add_tail(&m->list, active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			grp->active_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 			m->state = MBR_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 			list_add_tail(&m->list, &grp->pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		if (active_cnt < reclaim_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		/* Reclaim from oldest active member, if possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		if (!list_empty(active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 			rm = list_first_entry(active, struct tipc_member, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 			rm->state = MBR_RECLAIMING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 			list_del_init(&rm->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 			tipc_group_proto_xmit(grp, rm, GRP_RECLAIM_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		/* Nobody to reclaim from; - revert oldest pending to JOINED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		pm = list_first_entry(&grp->pending, struct tipc_member, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		list_del_init(&pm->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		pm->state = MBR_JOINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	case MBR_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		if (!list_is_last(&m->list, &grp->active))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			list_move_tail(&m->list, &grp->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		if (m->advertised > (ADV_ACTIVE * 3 / 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	case MBR_REMITTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		if (m->advertised > ADV_IDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		m->state = MBR_JOINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		grp->active_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		if (m->advertised < ADV_IDLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 			pr_warn_ratelimited("Rcv unexpected msg after REMIT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 			tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		if (list_empty(&grp->pending))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		/* Set oldest pending member to active and advertise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		pm = list_first_entry(&grp->pending, struct tipc_member, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		pm->state = MBR_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		list_move_tail(&pm->list, &grp->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		grp->active_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	case MBR_RECLAIMING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	case MBR_JOINING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	case MBR_LEAVING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static void tipc_group_create_event(struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 				    struct tipc_member *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 				    u32 event, u16 seqno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 				    struct sk_buff_head *inputq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {	u32 dnode = tipc_own_addr(grp->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	struct tipc_event evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	memset(&evt, 0, sizeof(evt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	evt.event = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	evt.found_lower = m->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	evt.found_upper = m->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	evt.port.ref = m->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	evt.port.node = m->node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	evt.s.seq.type = grp->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	evt.s.seq.lower = m->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	evt.s.seq.upper = m->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_GRP_MEMBER_EVT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 			      GROUP_H_SIZE, sizeof(evt), dnode, m->node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 			      grp->portid, m->port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	msg_set_nametype(hdr, grp->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	msg_set_grp_evt(hdr, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	msg_set_dest_droppable(hdr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	msg_set_grp_bc_seqno(hdr, seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	memcpy(msg_data(hdr), &evt, sizeof(evt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	TIPC_SKB_CB(skb)->orig_member = m->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	__skb_queue_tail(inputq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 				  int mtyp, struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	int adv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	skb = tipc_msg_create(GROUP_PROTOCOL, mtyp, INT_H_SIZE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 			      m->node, tipc_own_addr(grp->net),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 			      m->port, grp->portid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	if (m->state == MBR_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		adv = ADV_ACTIVE - m->advertised;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	else if (m->state == MBR_JOINED || m->state == MBR_PENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		adv = ADV_IDLE - m->advertised;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	if (mtyp == GRP_JOIN_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		msg_set_grp_bc_syncpt(hdr, grp->bc_snd_nxt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		msg_set_adv_win(hdr, adv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		m->advertised += adv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	} else if (mtyp == GRP_LEAVE_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 		msg_set_grp_bc_syncpt(hdr, grp->bc_snd_nxt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	} else if (mtyp == GRP_ADV_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 		msg_set_adv_win(hdr, adv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		m->advertised += adv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	} else if (mtyp == GRP_ACK_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		msg_set_grp_bc_acked(hdr, m->bc_rcv_nxt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	} else if (mtyp == GRP_REMIT_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		msg_set_grp_remitted(hdr, m->window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	msg_set_dest_droppable(hdr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	__skb_queue_tail(xmitq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 			  struct tipc_msg *hdr, struct sk_buff_head *inputq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 			  struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	u32 node = msg_orignode(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	u32 port = msg_origport(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	struct tipc_member *m, *pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	u16 remitted, in_flight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	if (!grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	if (grp->scope == TIPC_NODE_SCOPE && node != tipc_own_addr(grp->net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	m = tipc_group_find_member(grp, node, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	switch (msg_type(hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	case GRP_JOIN_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 			m = tipc_group_create_member(grp, node, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 						     0, MBR_JOINING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 		if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		m->bc_syncpt = msg_grp_bc_syncpt(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 		m->bc_rcv_nxt = m->bc_syncpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		m->window += msg_adv_win(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		/* Wait until PUBLISH event is received if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 		if (m->state != MBR_PUBLISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		/* Member can be taken into service */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		m->state = MBR_JOINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		tipc_group_open(m, usr_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 		tipc_group_update_member(m, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		tipc_group_create_event(grp, m, TIPC_PUBLISHED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 					m->bc_syncpt, inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	case GRP_LEAVE_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		m->bc_syncpt = msg_grp_bc_syncpt(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 		list_del_init(&m->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		tipc_group_open(m, usr_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 		tipc_group_decr_active(grp, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 		m->state = MBR_LEAVING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		tipc_group_create_event(grp, m, TIPC_WITHDRAWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 					m->bc_syncpt, inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	case GRP_ADV_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 		if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 		m->window += msg_adv_win(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		tipc_group_open(m, usr_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	case GRP_ACK_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 		if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 		m->bc_acked = msg_grp_bc_acked(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 		if (--grp->bc_ackers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		list_del_init(&m->small_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 		*m->group->open = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 		*usr_wakeup = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 		tipc_group_update_member(m, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	case GRP_RECLAIM_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 		if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		tipc_group_proto_xmit(grp, m, GRP_REMIT_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		m->window = ADV_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 		tipc_group_open(m, usr_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	case GRP_REMIT_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 		if (!m || m->state != MBR_RECLAIMING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 		remitted = msg_grp_remitted(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 		/* Messages preceding the REMIT still in receive queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		if (m->advertised > remitted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 			m->state = MBR_REMITTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 			in_flight = m->advertised - remitted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 			m->advertised = ADV_IDLE + in_flight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 		/* This should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 		if (m->advertised < remitted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 			pr_warn_ratelimited("Unexpected REMIT msg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 		/* All messages preceding the REMIT have been read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 		m->state = MBR_JOINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 		grp->active_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 		m->advertised = ADV_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 		/* Set oldest pending member to active and advertise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 		if (list_empty(&grp->pending))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 		pm = list_first_entry(&grp->pending, struct tipc_member, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 		pm->state = MBR_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		list_move_tail(&pm->list, &grp->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 		grp->active_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 		if (pm->advertised <= (ADV_ACTIVE * 3 / 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 			tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 		pr_warn("Received unknown GROUP_PROTO message\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* tipc_group_member_evt() - receive and handle a member up/down event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) void tipc_group_member_evt(struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 			   bool *usr_wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 			   int *sk_rcvbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 			   struct tipc_msg *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 			   struct sk_buff_head *inputq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 			   struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	struct tipc_event *evt = (void *)msg_data(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	u32 instance = evt->found_lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	u32 node = evt->port.node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	u32 port = evt->port.ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	int event = evt->event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	struct tipc_member *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	u32 self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	if (!grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 	net = grp->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 	self = tipc_own_addr(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	if (!grp->loopback && node == self && port == grp->portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 	m = tipc_group_find_member(grp, node, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	case TIPC_PUBLISHED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 		/* Send and wait for arrival of JOIN message if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 		if (!m) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 			m = tipc_group_create_member(grp, node, port, instance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 						     MBR_PUBLISHED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 			if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 			tipc_group_update_member(m, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 			tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 		if (m->state != MBR_JOINING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 		/* Member can be taken into service */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 		m->instance = instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 		m->state = MBR_JOINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 		tipc_group_open(m, usr_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 		tipc_group_update_member(m, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 		tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 		tipc_group_create_event(grp, m, TIPC_PUBLISHED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 					m->bc_syncpt, inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 	case TIPC_WITHDRAWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 		if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		tipc_group_decr_active(grp, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 		m->state = MBR_LEAVING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 		list_del_init(&m->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 		tipc_group_open(m, usr_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 		/* Only send event if no LEAVE message can be expected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 		if (!tipc_node_is_up(net, node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 			tipc_group_create_event(grp, m, TIPC_WITHDRAWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 						m->bc_rcv_nxt, inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 	*sk_rcvbuf = tipc_group_rcvbuf_limit(grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) int tipc_group_fill_sock_diag(struct tipc_group *grp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 	struct nlattr *group = nla_nest_start_noflag(skb, TIPC_NLA_SOCK_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 	if (!group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 	if (nla_put_u32(skb, TIPC_NLA_SOCK_GROUP_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 			grp->type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 	    nla_put_u32(skb, TIPC_NLA_SOCK_GROUP_INSTANCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 			grp->instance) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	    nla_put_u32(skb, TIPC_NLA_SOCK_GROUP_BC_SEND_NEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 			grp->bc_snd_nxt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 		goto group_msg_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 	if (grp->scope == TIPC_NODE_SCOPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 		if (nla_put_flag(skb, TIPC_NLA_SOCK_GROUP_NODE_SCOPE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 			goto group_msg_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	if (grp->scope == TIPC_CLUSTER_SCOPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 		if (nla_put_flag(skb, TIPC_NLA_SOCK_GROUP_CLUSTER_SCOPE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 			goto group_msg_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 	if (*grp->open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 		if (nla_put_flag(skb, TIPC_NLA_SOCK_GROUP_OPEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 			goto group_msg_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 	nla_nest_end(skb, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) group_msg_cancel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 	nla_nest_cancel(skb, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }