Skip to content

Commit 88690b1

Browse files
Tuong Liendavem330
authored andcommitted
tipc: fix failed service subscription deletion
When a service subscription is expired or canceled by user, it needs to be deleted from the subscription list, so that new subscriptions can be registered (max = 65535 per net). However, there are two issues in code that can cause such an unused subscription to persist: 1) The 'tipc_conn_delete_sub()' has a loop on the subscription list but it makes a break shortly when the 1st subscription differs from the one specified, so the subscription will not be deleted. 2) In case a subscription is canceled, the code to remove the 'TIPC_SUB_CANCEL' flag from the subscription filter does not work if it is a local subscription (i.e. the little endian isn't involved). So, it will be no matches when looking for the subscription to delete later. The subscription(s) will be removed eventually when the user terminates its topology connection but that could be a long time later. Meanwhile, the number of available subscriptions may be exhausted. This commit fixes the two issues above, so as needed a subscription can be deleted correctly. Acked-by: Ying Xue <[email protected]> Acked-by: Jon Maloy <[email protected]> Signed-off-by: Tuong Lien <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0771d7d commit 88690b1

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

net/tipc/subscr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ void tipc_sub_get(struct tipc_subscription *subscription);
9696
(swap_ ? swab32(val__) : val__); \
9797
})
9898

99+
/* tipc_sub_write - write val_ to field_ of struct sub_ in user endian format
100+
*/
101+
#define tipc_sub_write(sub_, field_, val_) \
102+
({ \
103+
struct tipc_subscr *sub__ = sub_; \
104+
u32 val__ = val_; \
105+
int swap_ = !((sub__)->filter & TIPC_FILTER_MASK); \
106+
(sub__)->field_ = swap_ ? swab32(val__) : val__; \
107+
})
108+
99109
/* tipc_evt_write - write val_ to field_ of struct evt_ in user endian format
100110
*/
101111
#define tipc_evt_write(evt_, field_, val_) \

net/tipc/topsrv.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,8 @@ static void tipc_conn_delete_sub(struct tipc_conn *con, struct tipc_subscr *s)
237237
if (!s || !memcmp(s, &sub->evt.s, sizeof(*s))) {
238238
tipc_sub_unsubscribe(sub);
239239
atomic_dec(&tn->subscription_count);
240-
} else if (s) {
241-
break;
240+
if (s)
241+
break;
242242
}
243243
}
244244
spin_unlock_bh(&con->sub_lock);
@@ -362,9 +362,10 @@ static int tipc_conn_rcv_sub(struct tipc_topsrv *srv,
362362
{
363363
struct tipc_net *tn = tipc_net(srv->net);
364364
struct tipc_subscription *sub;
365+
u32 s_filter = tipc_sub_read(s, filter);
365366

366-
if (tipc_sub_read(s, filter) & TIPC_SUB_CANCEL) {
367-
s->filter &= __constant_ntohl(~TIPC_SUB_CANCEL);
367+
if (s_filter & TIPC_SUB_CANCEL) {
368+
tipc_sub_write(s, filter, s_filter & ~TIPC_SUB_CANCEL);
368369
tipc_conn_delete_sub(con, s);
369370
return 0;
370371
}

0 commit comments

Comments
 (0)