diff mbox series

[v4,mptcp-next,7/9] mptcp: remove multi addresses and subflows in PM

Message ID 2e1e50023c1ca80e9737681fad83623f0be05a6f.1612534634.git.geliangtang@gmail.com
State Superseded, archived
Delegated to: Mat Martineau
Headers show
Series RM_ADDR: remove a list of addrs | expand

Commit Message

Geliang Tang Feb. 5, 2021, 2:24 p.m. UTC
This patch implemented the function to remove a list of addresses and
subflows, named mptcp_nl_remove_addrs_list, which had a input parameter
rm_list as the removing addresses list.

In mptcp_nl_remove_addrs_list, traverse all the existing msk sockets to
invoke mptcp_pm_remove_addrs_and_subflows to remove a list of addresses
for each msk socket.

In mptcp_pm_remove_addrs_and_subflows, traverse all the addresses in the
removing addresses list, to find whether this address is in the conn_list
or anno_list. If it is, put the address ID into the removing address ids
array, and pass the array to mptcp_pm_remove_addr or
mptcp_pm_remove_subflow.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/pm_netlink.c | 52 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

Comments

Mat Martineau Feb. 6, 2021, 1:20 a.m. UTC | #1
On Fri, 5 Feb 2021, Geliang Tang wrote:

> This patch implemented the function to remove a list of addresses and
> subflows, named mptcp_nl_remove_addrs_list, which had a input parameter
> rm_list as the removing addresses list.
>
> In mptcp_nl_remove_addrs_list, traverse all the existing msk sockets to
> invoke mptcp_pm_remove_addrs_and_subflows to remove a list of addresses
> for each msk socket.
>
> In mptcp_pm_remove_addrs_and_subflows, traverse all the addresses in the
> removing addresses list, to find whether this address is in the conn_list
> or anno_list. If it is, put the address ID into the removing address ids
> array, and pass the array to mptcp_pm_remove_addr or
> mptcp_pm_remove_subflow.
>
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> ---
> net/mptcp/pm_netlink.c | 52 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 52 insertions(+)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index b4d6f7b56a65..392aa4dc0834 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -1213,6 +1213,58 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
> 	return ret;
> }
>
> +static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
> +					       struct list_head *rm_list)
> +{
> +	struct mptcp_pm_addr_entry *entry;
> +	u8 subflow_ids[MPTCP_RM_IDS_MAX];
> +	u8 address_ids[MPTCP_RM_IDS_MAX];
> +	int i = 0, j = 0;
> +
> +	memset(subflow_ids, MAX_ADDR_ID, MPTCP_RM_IDS_MAX);
> +	memset(address_ids, MAX_ADDR_ID, MPTCP_RM_IDS_MAX);
> +
> +	list_for_each_entry(entry, rm_list, list) {
> +		if (lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) && i < MPTCP_RM_IDS_MAX)
> +			subflow_ids[i++] = entry->addr.id;
> +		else if (remove_anno_list_by_saddr(msk, &entry->addr) && j < MPTCP_RM_IDS_MAX)
> +			address_ids[j++] = entry->addr.id;
> +	}
> +
> +	if (mptcp_get_rm_ids_nr(subflow_ids)) {
> +		spin_lock_bh(&msk->pm.lock);
> +		mptcp_pm_remove_addr(msk, subflow_ids);
> +		spin_unlock_bh(&msk->pm.lock);
> +		mptcp_pm_remove_subflow(msk, subflow_ids);
> +	}
> +	if (mptcp_get_rm_ids_nr(address_ids)) {
> +		spin_lock_bh(&msk->pm.lock);
> +		mptcp_pm_remove_addr(msk, address_ids);
> +		spin_unlock_bh(&msk->pm.lock);
> +	}

This would send two RM_ADDR options (or overwrite some of the ids?), when 
it seems like the list of 8 is enough to hold all the of addresses that 
would have been advertised.

If you use one list to store *all* address ids to pass to 
mptcp_pm_remove_subflow(), and one list to store only the subflows that 
need to be passed to mptcp_pm_remove_subflow(), then only one option is 
sent and there's less duplicate code in the two 'if' statements.

> +}
> +
> +static void mptcp_nl_remove_addrs_list(struct net *net,
> +				       struct list_head *rm_list)
> +{
> +	long s_slot = 0, s_num = 0;
> +	struct mptcp_sock *msk;
> +
> +	if (list_empty(rm_list))
> +		return;
> +
> +	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
> +		struct sock *sk = (struct sock *)msk;
> +
> +		lock_sock(sk);
> +		mptcp_pm_remove_addrs_and_subflows(msk, rm_list);
> +		release_sock(sk);
> +
> +		sock_put(sk);
> +		cond_resched();
> +	}
> +}
> +
> static void __flush_addrs(struct net *net, struct list_head *list)
> {
> 	while (!list_empty(list)) {
> -- 
> 2.29.2

--
Mat Martineau
Intel
diff mbox series

Patch

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index b4d6f7b56a65..392aa4dc0834 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1213,6 +1213,58 @@  static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
 	return ret;
 }
 
+static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
+					       struct list_head *rm_list)
+{
+	struct mptcp_pm_addr_entry *entry;
+	u8 subflow_ids[MPTCP_RM_IDS_MAX];
+	u8 address_ids[MPTCP_RM_IDS_MAX];
+	int i = 0, j = 0;
+
+	memset(subflow_ids, MAX_ADDR_ID, MPTCP_RM_IDS_MAX);
+	memset(address_ids, MAX_ADDR_ID, MPTCP_RM_IDS_MAX);
+
+	list_for_each_entry(entry, rm_list, list) {
+		if (lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) && i < MPTCP_RM_IDS_MAX)
+			subflow_ids[i++] = entry->addr.id;
+		else if (remove_anno_list_by_saddr(msk, &entry->addr) && j < MPTCP_RM_IDS_MAX)
+			address_ids[j++] = entry->addr.id;
+	}
+
+	if (mptcp_get_rm_ids_nr(subflow_ids)) {
+		spin_lock_bh(&msk->pm.lock);
+		mptcp_pm_remove_addr(msk, subflow_ids);
+		spin_unlock_bh(&msk->pm.lock);
+		mptcp_pm_remove_subflow(msk, subflow_ids);
+	}
+	if (mptcp_get_rm_ids_nr(address_ids)) {
+		spin_lock_bh(&msk->pm.lock);
+		mptcp_pm_remove_addr(msk, address_ids);
+		spin_unlock_bh(&msk->pm.lock);
+	}
+}
+
+static void mptcp_nl_remove_addrs_list(struct net *net,
+				       struct list_head *rm_list)
+{
+	long s_slot = 0, s_num = 0;
+	struct mptcp_sock *msk;
+
+	if (list_empty(rm_list))
+		return;
+
+	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
+		struct sock *sk = (struct sock *)msk;
+
+		lock_sock(sk);
+		mptcp_pm_remove_addrs_and_subflows(msk, rm_list);
+		release_sock(sk);
+
+		sock_put(sk);
+		cond_resched();
+	}
+}
+
 static void __flush_addrs(struct net *net, struct list_head *list)
 {
 	while (!list_empty(list)) {