^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) }