On 5/11/20 11:59 AM, Tuong Lien wrote:
> 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.
> 
> v2: define a new macro to write sub field value (- Jon's comment)
> v3: break if the sub to be deleted has been found
> 
> Signed-off-by: Tuong Lien <tuong.t.l...@dektech.com.au>

Acked-by: Ying Xue <ying....@windriver.com>

> ---
>  net/tipc/subscr.h | 10 ++++++++++
>  net/tipc/topsrv.c |  9 +++++----
>  2 files changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
> index aa015c233898..6ebbec1bedd1 100644
> --- a/net/tipc/subscr.h
> +++ b/net/tipc/subscr.h
> @@ -96,6 +96,16 @@ void tipc_sub_get(struct tipc_subscription *subscription);
>               (swap_ ? swab32(val__) : val__);                        \
>       })
>  
> +/* tipc_sub_write - write val_ to field_ of struct sub_ in user endian format
> + */
> +#define tipc_sub_write(sub_, field_, val_)                           \
> +     ({                                                              \
> +             struct tipc_subscr *sub__ = sub_;                       \
> +             u32 val__ = val_;                                       \
> +             int swap_ = !((sub__)->filter & TIPC_FILTER_MASK);      \
> +             (sub__)->field_ = swap_ ? swab32(val__) : val__;        \
> +     })
> +
>  /* tipc_evt_write - write val_ to field_ of struct evt_ in user endian format
>   */
>  #define tipc_evt_write(evt_, field_, val_)                           \
> diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
> index 931c426673c0..446af7bbd13e 100644
> --- a/net/tipc/topsrv.c
> +++ b/net/tipc/topsrv.c
> @@ -237,8 +237,8 @@ static void tipc_conn_delete_sub(struct tipc_conn *con, 
> struct tipc_subscr *s)
>               if (!s || !memcmp(s, &sub->evt.s, sizeof(*s))) {
>                       tipc_sub_unsubscribe(sub);
>                       atomic_dec(&tn->subscription_count);
> -             } else if (s) {
> -                     break;
> +                     if (s)
> +                             break;
>               }
>       }
>       spin_unlock_bh(&con->sub_lock);
> @@ -362,9 +362,10 @@ static int tipc_conn_rcv_sub(struct tipc_topsrv *srv,
>  {
>       struct tipc_net *tn = tipc_net(srv->net);
>       struct tipc_subscription *sub;
> +     u32 s_filter = tipc_sub_read(s, filter);
>  
> -     if (tipc_sub_read(s, filter) & TIPC_SUB_CANCEL) {
> -             s->filter &= __constant_ntohl(~TIPC_SUB_CANCEL);
> +     if (s_filter & TIPC_SUB_CANCEL) {
> +             tipc_sub_write(s, filter, s_filter & ~TIPC_SUB_CANCEL);
>               tipc_conn_delete_sub(con, s);
>               return 0;
>       }
> 


_______________________________________________
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to