Skip to content

Commit fb92817

Browse files
committed
Merge branch 'mptcp-addr-adv-fixes'
Mat Martineau says: ==================== mptcp: Fixes for address advertisement Patches 1 and 2 allow address advertisements to be removed without affecting current connected subflows, and updates associated self tests. Patches 3 and 4 correctly track (and allow removal of) addresses that were implicitly announced as part of subflow creation. Also updates associated self tests. Patch 5 makes subflow and address announcement counters work consistently between the userspace and in-kernel path managers. ==================== Signed-off-by: Mat Martineau <martineau@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 9bc0097 + 77e4b94 commit fb92817

File tree

5 files changed

+95
-6
lines changed

5 files changed

+95
-6
lines changed

net/mptcp/pm.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,15 @@ bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)
8787
unsigned int subflows_max;
8888
int ret = 0;
8989

90-
if (mptcp_pm_is_userspace(msk))
91-
return mptcp_userspace_pm_active(msk);
90+
if (mptcp_pm_is_userspace(msk)) {
91+
if (mptcp_userspace_pm_active(msk)) {
92+
spin_lock_bh(&pm->lock);
93+
pm->subflows++;
94+
spin_unlock_bh(&pm->lock);
95+
return true;
96+
}
97+
return false;
98+
}
9299

93100
subflows_max = mptcp_pm_get_subflows_max(msk);
94101

@@ -181,8 +188,16 @@ void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, const struct sock *ssk,
181188
struct mptcp_pm_data *pm = &msk->pm;
182189
bool update_subflows;
183190

184-
update_subflows = (subflow->request_join || subflow->mp_join) &&
185-
mptcp_pm_is_kernel(msk);
191+
update_subflows = subflow->request_join || subflow->mp_join;
192+
if (mptcp_pm_is_userspace(msk)) {
193+
if (update_subflows) {
194+
spin_lock_bh(&pm->lock);
195+
pm->subflows--;
196+
spin_unlock_bh(&pm->lock);
197+
}
198+
return;
199+
}
200+
186201
if (!READ_ONCE(pm->work_pending) && !update_subflows)
187202
return;
188203

net/mptcp/pm_netlink.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,6 +1558,24 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
15581558
return ret;
15591559
}
15601560

1561+
void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
1562+
{
1563+
struct mptcp_rm_list alist = { .nr = 0 };
1564+
struct mptcp_pm_addr_entry *entry;
1565+
1566+
list_for_each_entry(entry, rm_list, list) {
1567+
remove_anno_list_by_saddr(msk, &entry->addr);
1568+
if (alist.nr < MPTCP_RM_IDS_MAX)
1569+
alist.ids[alist.nr++] = entry->addr.id;
1570+
}
1571+
1572+
if (alist.nr) {
1573+
spin_lock_bh(&msk->pm.lock);
1574+
mptcp_pm_remove_addr(msk, &alist);
1575+
spin_unlock_bh(&msk->pm.lock);
1576+
}
1577+
}
1578+
15611579
void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
15621580
struct list_head *rm_list)
15631581
{

net/mptcp/pm_userspace.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
6969
MPTCP_PM_MAX_ADDR_ID + 1,
7070
1);
7171
list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
72+
msk->pm.local_addr_used++;
7273
ret = e->addr.id;
7374
} else if (match) {
7475
ret = entry->addr.id;
@@ -79,6 +80,31 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
7980
return ret;
8081
}
8182

83+
/* If the subflow is closed from the other peer (not via a
84+
* subflow destroy command then), we want to keep the entry
85+
* not to assign the same ID to another address and to be
86+
* able to send RM_ADDR after the removal of the subflow.
87+
*/
88+
static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
89+
struct mptcp_pm_addr_entry *addr)
90+
{
91+
struct mptcp_pm_addr_entry *entry, *tmp;
92+
93+
list_for_each_entry_safe(entry, tmp, &msk->pm.userspace_pm_local_addr_list, list) {
94+
if (mptcp_addresses_equal(&entry->addr, &addr->addr, false)) {
95+
/* TODO: a refcount is needed because the entry can
96+
* be used multiple times (e.g. fullmesh mode).
97+
*/
98+
list_del_rcu(&entry->list);
99+
kfree(entry);
100+
msk->pm.local_addr_used--;
101+
return 0;
102+
}
103+
}
104+
105+
return -EINVAL;
106+
}
107+
82108
int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
83109
unsigned int id,
84110
u8 *flags, int *ifindex)
@@ -171,6 +197,7 @@ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info)
171197
spin_lock_bh(&msk->pm.lock);
172198

173199
if (mptcp_pm_alloc_anno_list(msk, &addr_val)) {
200+
msk->pm.add_addr_signaled++;
174201
mptcp_pm_announce_addr(msk, &addr_val.addr, false);
175202
mptcp_pm_nl_addr_send_ack(msk);
176203
}
@@ -232,7 +259,7 @@ int mptcp_nl_cmd_remove(struct sk_buff *skb, struct genl_info *info)
232259

233260
list_move(&match->list, &free_list);
234261

235-
mptcp_pm_remove_addrs_and_subflows(msk, &free_list);
262+
mptcp_pm_remove_addrs(msk, &free_list);
236263

237264
release_sock((struct sock *)msk);
238265

@@ -251,6 +278,7 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
251278
struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
252279
struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
253280
struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
281+
struct mptcp_pm_addr_entry local = { 0 };
254282
struct mptcp_addr_info addr_r;
255283
struct mptcp_addr_info addr_l;
256284
struct mptcp_sock *msk;
@@ -302,12 +330,26 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
302330
goto create_err;
303331
}
304332

333+
local.addr = addr_l;
334+
err = mptcp_userspace_pm_append_new_local_addr(msk, &local);
335+
if (err < 0) {
336+
GENL_SET_ERR_MSG(info, "did not match address and id");
337+
goto create_err;
338+
}
339+
305340
lock_sock(sk);
306341

307342
err = __mptcp_subflow_connect(sk, &addr_l, &addr_r);
308343

309344
release_sock(sk);
310345

346+
spin_lock_bh(&msk->pm.lock);
347+
if (err)
348+
mptcp_userspace_pm_delete_local_addr(msk, &local);
349+
else
350+
msk->pm.subflows++;
351+
spin_unlock_bh(&msk->pm.lock);
352+
311353
create_err:
312354
sock_put((struct sock *)msk);
313355
return err;
@@ -420,7 +462,11 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
420462
ssk = mptcp_nl_find_ssk(msk, &addr_l, &addr_r);
421463
if (ssk) {
422464
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
465+
struct mptcp_pm_addr_entry entry = { .addr = addr_l };
423466

467+
spin_lock_bh(&msk->pm.lock);
468+
mptcp_userspace_pm_delete_local_addr(msk, &entry);
469+
spin_unlock_bh(&msk->pm.lock);
424470
mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
425471
mptcp_close_ssk(sk, ssk, subflow);
426472
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);

net/mptcp/protocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,7 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
832832
bool echo);
833833
int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
834834
int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
835+
void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list);
835836
void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
836837
struct list_head *rm_list);
837838

tools/testing/selftests/net/mptcp/mptcp_join.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,15 @@ do_transfer()
862862
sed -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q')
863863
ip netns exec ${listener_ns} ./pm_nl_ctl ann $addr token $tk id $id
864864
sleep 1
865+
sp=$(grep "type:10" "$evts_ns1" |
866+
sed -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q')
867+
da=$(grep "type:10" "$evts_ns1" |
868+
sed -n 's/.*\(daddr6:\)\([0-9a-f:.]*\).*$/\2/p;q')
869+
dp=$(grep "type:10" "$evts_ns1" |
870+
sed -n 's/.*\(dport:\)\([[:digit:]]*\).*$/\2/p;q')
865871
ip netns exec ${listener_ns} ./pm_nl_ctl rem token $tk id $id
872+
ip netns exec ${listener_ns} ./pm_nl_ctl dsf lip "::ffff:$addr" \
873+
lport $sp rip $da rport $dp token $tk
866874
fi
867875

868876
counter=$((counter + 1))
@@ -928,6 +936,7 @@ do_transfer()
928936
sleep 1
929937
sp=$(grep "type:10" "$evts_ns2" |
930938
sed -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q')
939+
ip netns exec ${connector_ns} ./pm_nl_ctl rem token $tk id $id
931940
ip netns exec ${connector_ns} ./pm_nl_ctl dsf lip $addr lport $sp \
932941
rip $da rport $dp token $tk
933942
fi
@@ -3142,7 +3151,7 @@ userspace_tests()
31423151
pm_nl_set_limits $ns1 0 1
31433152
run_tests $ns1 $ns2 10.0.1.1 0 0 userspace_1 slow
31443153
chk_join_nr 1 1 1
3145-
chk_rm_nr 0 1
3154+
chk_rm_nr 1 1
31463155
kill_events_pids
31473156
fi
31483157
}

0 commit comments

Comments
 (0)