All of lore.kernel.org
 help / color / mirror / Atom feed
* [MPTCP] Re: [MPTCP][PATCH v7 mptcp-next 1/5] mptcp: remove addr and subflow in PM netlink
@ 2020-08-21  3:48 Mat Martineau
  0 siblings, 0 replies; 2+ messages in thread
From: Mat Martineau @ 2020-08-21  3:48 UTC (permalink / raw)
  To: mptcp

[-- Attachment #1: Type: text/plain, Size: 7289 bytes --]

On Thu, 13 Aug 2020, Geliang Tang wrote:

> This patch implements the remove announced addr and subflow logic in PM
> netlink.
>
> When the PM netlink removes an address, we traverse all the existing msk
> sockets to find the relevant sockets.
>
> We add a new list named anno_list in mptcp_pm_data, to record all the
> announced addrs. In the traversing, we check if it has been recorded.
> If it has been, we trigger the RM_ADDR signal.
>
> We also check if this address is in conn_list. If it is, we remove the
> subflow which using this local address.
>
> Suggested-by: Matthieu Baerts <matthieu.baerts(a)tessares.net>
> Suggested-by: Paolo Abeni <pabeni(a)redhat.com>
> Suggested-by: Mat Martineau <mathew.j.martineau(a)linux.intel.com>
> Signed-off-by: Geliang Tang <geliangtang(a)gmail.com>
> ---
> net/mptcp/pm.c         |  7 +++-
> net/mptcp/pm_netlink.c | 87 ++++++++++++++++++++++++++++++++++++++++--
> net/mptcp/protocol.c   |  2 +
> net/mptcp/protocol.h   |  2 +
> 4 files changed, 93 insertions(+), 5 deletions(-)
>
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index 558462d87eb3..b3712771f268 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -24,7 +24,11 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
>
> int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id)
> {
> -	return -ENOTSUPP;
> +	pr_debug("msk=%p, local_id=%d", msk, local_id);
> +
> +	msk->pm.rm_id = local_id;
> +	WRITE_ONCE(msk->pm.rm_addr_signal, true);
> +	return 0;
> }
>
> int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 remote_id)
> @@ -229,6 +233,7 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
> 	msk->pm.status = 0;
>
> 	spin_lock_init(&msk->pm.lock);
> +	INIT_LIST_HEAD(&msk->pm.anno_list);
>
> 	mptcp_pm_nl_data_init(msk);
> }
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 848649a82649..8d29eae2a0c1 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -167,6 +167,19 @@ static void check_work_pending(struct mptcp_sock *msk)
> 		WRITE_ONCE(msk->pm.work_pending, false);
> }
>
> +void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
> +{
> +	struct mptcp_pm_addr_entry *entry, *tmp;
> +
> +	pr_debug("msk=%p\n", msk);
> +	spin_lock_bh(&msk->pm.lock);
> +	list_for_each_entry_safe(entry, tmp, &msk->pm.anno_list, list) {
> +		list_del(&entry->list);
> +		kfree(entry);
> +	}
> +	spin_unlock_bh(&msk->pm.lock);
> +}
> +
> static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
> {
> 	struct sock *sk = (struct sock *)msk;
> @@ -187,8 +200,16 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
> 					      msk->pm.add_addr_signaled);
>
> 		if (local) {
> +			struct mptcp_pm_addr_entry *clone = NULL;
> +

I suggest doing the kmemdup() here and handling the failure before 
triggering the add_addr signal, so no signal is sent without being added 
to anno_list.

Should this function check to see if an address is already announced so it 
is not added to anno_list twice?

> 			msk->pm.add_addr_signaled++;
> 			mptcp_pm_announce_addr(msk, &local->addr);
> +
> +			clone = kmemdup(local, sizeof(*local), GFP_ATOMIC);
> +			if (!clone)
> +				return;
> +
> +			list_add(&clone->list, &msk->pm.anno_list);
> 		} else {
> 			/* pick failed, avoid fourther attempts later */
> 			msk->pm.local_addr_used = msk->pm.add_addr_signal_max;
> @@ -552,6 +573,62 @@ __lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
> 	return NULL;
> }
>
> +static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
> +				      struct mptcp_addr_info *addr)
> +{
> +	struct mptcp_pm_addr_entry *entry, *tmp;
> +
> +	list_for_each_entry_safe(entry, tmp, &msk->pm.anno_list, list) {
> +		if (addresses_equal(&entry->addr, addr, false)) {
> +			list_del(&entry->list);
> +			kfree(entry);
> +			return true;
> +		}
> +	}
> +
> +	return false;
> +}
> +
> +static int mptcp_nl_remove_subflow_or_signal_addr(struct net *net,
> +						  struct mptcp_addr_info *addr)
> +{
> +	struct mptcp_sock *msk;
> +	long s_slot = 0, s_num = 0;
> +
> +	pr_debug("remove_id=%d\n", addr->id);
> +
> +	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
> +		struct sock *sk = (struct sock *)msk;
> +		bool ret = false;
> +
> +		/* check first for announced addr */
> +		if (list_empty(&msk->pm.anno_list))
> +			goto remove_subflow;
> +
> +		spin_lock_bh(&msk->pm.lock);
> +		ret = remove_anno_list_by_saddr(msk, addr);
> +		spin_unlock_bh(&msk->pm.lock);
> +		if (ret)
> +			mptcp_pm_remove_addr(msk, addr->id);
> +
> +		/* check if should remove a subflow */
> +remove_subflow:
> +		if (list_empty(&msk->conn_list))
> +			goto next;
> +
> +		lock_sock(sk);
> +		if (lookup_subflow_by_saddr(&msk->conn_list, addr))
> +			mptcp_pm_rm_addr_received(msk, addr->id);
> +		release_sock(sk);
> +
> +next:
> +		sock_put(sk);
> +		cond_resched();
> +	}
> +
> +	return 0;
> +}
> +
> static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
> {
> 	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
> @@ -567,8 +644,8 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
> 	entry = __lookup_addr_by_id(pernet, addr.addr.id);
> 	if (!entry) {
> 		GENL_SET_ERR_MSG(info, "address not found");
> -		ret = -EINVAL;
> -		goto out;
> +		spin_unlock_bh(&pernet->lock);
> +		return -EINVAL;
> 	}
> 	if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
> 		pernet->add_addr_signal_max--;
> @@ -577,9 +654,11 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
>
> 	pernet->addrs--;
> 	list_del_rcu(&entry->list);
> -	kfree_rcu(entry, rcu);
> -out:
> 	spin_unlock_bh(&pernet->lock);
> +
> +	mptcp_nl_remove_subflow_or_signal_addr(sock_net(skb->sk), &entry->addr);
> +	kfree_rcu(entry, rcu);
> +
> 	return ret;
> }
>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index c800b9147a3c..3bf4975d0ef3 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -1961,6 +1961,8 @@ static void mptcp_close(struct sock *sk, long timeout)
> 		__mptcp_close_ssk(sk, ssk, subflow, timeout);
> 	}
>
> +	mptcp_pm_free_anno_list(msk);
> +
> 	mptcp_cancel_work(sk);
>
> 	__skb_queue_purge(&sk->sk_receive_queue);
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 4b8a5308aeed..ceca1ddea9f8 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -179,6 +179,7 @@ struct mptcp_pm_data {
> 	u8		subflows_max;
> 	u8		status;
> 	u8		rm_id;
> +	struct list_head anno_list;

Minor: I'd move this new struct member just after the local & remote 
members at the beginning of this struct.

> };
>
> struct mptcp_data_frag {
> @@ -446,6 +447,7 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
> 			   const struct mptcp_addr_info *addr);
> int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id);
> int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 remote_id);
> +void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
>
> static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
> {
> -- 
> 2.17.1

Thanks!

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [MPTCP] Re: [MPTCP][PATCH v7 mptcp-next 1/5] mptcp: remove addr and subflow in PM netlink
@ 2020-09-07  7:01 Geliang Tang
  0 siblings, 0 replies; 2+ messages in thread
From: Geliang Tang @ 2020-09-07  7:01 UTC (permalink / raw)
  To: mptcp

[-- Attachment #1: Type: text/plain, Size: 9036 bytes --]

Hi Mat,

Thanks for your review.

Mat Martineau <mathew.j.martineau(a)linux.intel.com> 于2020年8月21日周五 上午11:48写道:
>
> On Thu, 13 Aug 2020, Geliang Tang wrote:
>
> > This patch implements the remove announced addr and subflow logic in PM
> > netlink.
> >
> > When the PM netlink removes an address, we traverse all the existing msk
> > sockets to find the relevant sockets.
> >
> > We add a new list named anno_list in mptcp_pm_data, to record all the
> > announced addrs. In the traversing, we check if it has been recorded.
> > If it has been, we trigger the RM_ADDR signal.
> >
> > We also check if this address is in conn_list. If it is, we remove the
> > subflow which using this local address.
> >
> > Suggested-by: Matthieu Baerts <matthieu.baerts(a)tessares.net>
> > Suggested-by: Paolo Abeni <pabeni(a)redhat.com>
> > Suggested-by: Mat Martineau <mathew.j.martineau(a)linux.intel.com>
> > Signed-off-by: Geliang Tang <geliangtang(a)gmail.com>
> > ---
> > net/mptcp/pm.c         |  7 +++-
> > net/mptcp/pm_netlink.c | 87 ++++++++++++++++++++++++++++++++++++++++--
> > net/mptcp/protocol.c   |  2 +
> > net/mptcp/protocol.h   |  2 +
> > 4 files changed, 93 insertions(+), 5 deletions(-)
> >
> > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> > index 558462d87eb3..b3712771f268 100644
> > --- a/net/mptcp/pm.c
> > +++ b/net/mptcp/pm.c
> > @@ -24,7 +24,11 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
> >
> > int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id)
> > {
> > -     return -ENOTSUPP;
> > +     pr_debug("msk=%p, local_id=%d", msk, local_id);
> > +
> > +     msk->pm.rm_id = local_id;
> > +     WRITE_ONCE(msk->pm.rm_addr_signal, true);
> > +     return 0;
> > }
> >
> > int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 remote_id)
> > @@ -229,6 +233,7 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
> >       msk->pm.status = 0;
> >
> >       spin_lock_init(&msk->pm.lock);
> > +     INIT_LIST_HEAD(&msk->pm.anno_list);
> >
> >       mptcp_pm_nl_data_init(msk);
> > }
> > diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> > index 848649a82649..8d29eae2a0c1 100644
> > --- a/net/mptcp/pm_netlink.c
> > +++ b/net/mptcp/pm_netlink.c
> > @@ -167,6 +167,19 @@ static void check_work_pending(struct mptcp_sock *msk)
> >               WRITE_ONCE(msk->pm.work_pending, false);
> > }
> >
> > +void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
> > +{
> > +     struct mptcp_pm_addr_entry *entry, *tmp;
> > +
> > +     pr_debug("msk=%p\n", msk);
> > +     spin_lock_bh(&msk->pm.lock);
> > +     list_for_each_entry_safe(entry, tmp, &msk->pm.anno_list, list) {
> > +             list_del(&entry->list);
> > +             kfree(entry);
> > +     }
> > +     spin_unlock_bh(&msk->pm.lock);
> > +}
> > +
> > static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
> > {
> >       struct sock *sk = (struct sock *)msk;
> > @@ -187,8 +200,16 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
> >                                             msk->pm.add_addr_signaled);
> >
> >               if (local) {
> > +                     struct mptcp_pm_addr_entry *clone = NULL;
> > +
>
> I suggest doing the kmemdup() here and handling the failure before
> triggering the add_addr signal, so no signal is sent without being added
> to anno_list.
>
> Should this function check to see if an address is already announced so it
> is not added to anno_list twice?
>

Fixed in 'Squash-to: "mptcp: remove addr and subflow in PM netlink v9"'.

> >                       msk->pm.add_addr_signaled++;
> >                       mptcp_pm_announce_addr(msk, &local->addr);
> > +
> > +                     clone = kmemdup(local, sizeof(*local), GFP_ATOMIC);
> > +                     if (!clone)
> > +                             return;
> > +
> > +                     list_add(&clone->list, &msk->pm.anno_list);
> >               } else {
> >                       /* pick failed, avoid fourther attempts later */
> >                       msk->pm.local_addr_used = msk->pm.add_addr_signal_max;
> > @@ -552,6 +573,62 @@ __lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
> >       return NULL;
> > }
> >
> > +static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
> > +                                   struct mptcp_addr_info *addr)
> > +{
> > +     struct mptcp_pm_addr_entry *entry, *tmp;
> > +
> > +     list_for_each_entry_safe(entry, tmp, &msk->pm.anno_list, list) {
> > +             if (addresses_equal(&entry->addr, addr, false)) {
> > +                     list_del(&entry->list);
> > +                     kfree(entry);
> > +                     return true;
> > +             }
> > +     }
> > +
> > +     return false;
> > +}
> > +
> > +static int mptcp_nl_remove_subflow_or_signal_addr(struct net *net,
> > +                                               struct mptcp_addr_info *addr)
> > +{
> > +     struct mptcp_sock *msk;
> > +     long s_slot = 0, s_num = 0;
> > +
> > +     pr_debug("remove_id=%d\n", addr->id);
> > +
> > +     while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
> > +             struct sock *sk = (struct sock *)msk;
> > +             bool ret = false;
> > +
> > +             /* check first for announced addr */
> > +             if (list_empty(&msk->pm.anno_list))
> > +                     goto remove_subflow;
> > +
> > +             spin_lock_bh(&msk->pm.lock);
> > +             ret = remove_anno_list_by_saddr(msk, addr);
> > +             spin_unlock_bh(&msk->pm.lock);
> > +             if (ret)
> > +                     mptcp_pm_remove_addr(msk, addr->id);
> > +
> > +             /* check if should remove a subflow */
> > +remove_subflow:
> > +             if (list_empty(&msk->conn_list))
> > +                     goto next;
> > +
> > +             lock_sock(sk);
> > +             if (lookup_subflow_by_saddr(&msk->conn_list, addr))
> > +                     mptcp_pm_rm_addr_received(msk, addr->id);
> > +             release_sock(sk);
> > +
> > +next:
> > +             sock_put(sk);
> > +             cond_resched();
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
> > {
> >       struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
> > @@ -567,8 +644,8 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
> >       entry = __lookup_addr_by_id(pernet, addr.addr.id);
> >       if (!entry) {
> >               GENL_SET_ERR_MSG(info, "address not found");
> > -             ret = -EINVAL;
> > -             goto out;
> > +             spin_unlock_bh(&pernet->lock);
> > +             return -EINVAL;
> >       }
> >       if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
> >               pernet->add_addr_signal_max--;
> > @@ -577,9 +654,11 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
> >
> >       pernet->addrs--;
> >       list_del_rcu(&entry->list);
> > -     kfree_rcu(entry, rcu);
> > -out:
> >       spin_unlock_bh(&pernet->lock);
> > +
> > +     mptcp_nl_remove_subflow_or_signal_addr(sock_net(skb->sk), &entry->addr);
> > +     kfree_rcu(entry, rcu);
> > +
> >       return ret;
> > }
> >
> > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> > index c800b9147a3c..3bf4975d0ef3 100644
> > --- a/net/mptcp/protocol.c
> > +++ b/net/mptcp/protocol.c
> > @@ -1961,6 +1961,8 @@ static void mptcp_close(struct sock *sk, long timeout)
> >               __mptcp_close_ssk(sk, ssk, subflow, timeout);
> >       }
> >
> > +     mptcp_pm_free_anno_list(msk);
> > +
> >       mptcp_cancel_work(sk);
> >
> >       __skb_queue_purge(&sk->sk_receive_queue);
> > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> > index 4b8a5308aeed..ceca1ddea9f8 100644
> > --- a/net/mptcp/protocol.h
> > +++ b/net/mptcp/protocol.h
> > @@ -179,6 +179,7 @@ struct mptcp_pm_data {
> >       u8              subflows_max;
> >       u8              status;
> >       u8              rm_id;
> > +     struct list_head anno_list;
>
> Minor: I'd move this new struct member just after the local & remote
> members at the beginning of this struct.
>

Fixed in 'Squash-to: "mptcp: remove addr and subflow in PM netlink v9"'.

-Geliang

> > };
> >
> > struct mptcp_data_frag {
> > @@ -446,6 +447,7 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
> >                          const struct mptcp_addr_info *addr);
> > int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id);
> > int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 remote_id);
> > +void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
> >
> > static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
> > {
> > --
> > 2.17.1
>
> Thanks!
>
> --
> Mat Martineau
> Intel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-09-07  7:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-21  3:48 [MPTCP] Re: [MPTCP][PATCH v7 mptcp-next 1/5] mptcp: remove addr and subflow in PM netlink Mat Martineau
2020-09-07  7:01 Geliang Tang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.