Skip to content

Commit ae9fdf6

Browse files
committed
Merge branch 'mptcp-path-manager-fixes'
Mat Martineau says: ==================== mptcp: Path manager fixes for 5.19 The MPTCP userspace path manager is new in 5.19, and these patches fix some issues in that new code. Patches 1-3 fix path manager locking issues. Patches 4 and 5 allow userspace path managers to change priority of established subflows using the existing MPTCP_PM_CMD_SET_FLAGS generic netlink command. Includes corresponding self test update. Patches 6 and 7 fix accounting of available endpoint IDs and the MPTCP_MIB_RMSUBFLOW counter. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 44d632d + d2d21f1 commit ae9fdf6

File tree

7 files changed

+192
-31
lines changed

7 files changed

+192
-31
lines changed

net/mptcp/options.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,9 @@ void mptcp_write_options(struct tcphdr *th, __be32 *ptr, struct tcp_sock *tp,
15841584
*ptr++ = mptcp_option(MPTCPOPT_MP_PRIO,
15851585
TCPOLEN_MPTCP_PRIO,
15861586
opts->backup, TCPOPT_NOP);
1587+
1588+
MPTCP_INC_STATS(sock_net((const struct sock *)tp),
1589+
MPTCP_MIB_MPPRIOTX);
15871590
}
15881591

15891592
mp_capable_done:

net/mptcp/pm_netlink.c

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -717,34 +717,40 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
717717
}
718718
}
719719

720-
static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
721-
struct mptcp_addr_info *addr,
722-
u8 bkup)
720+
int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
721+
struct mptcp_addr_info *addr,
722+
struct mptcp_addr_info *rem,
723+
u8 bkup)
723724
{
724725
struct mptcp_subflow_context *subflow;
725726

726727
pr_debug("bkup=%d", bkup);
727728

728729
mptcp_for_each_subflow(msk, subflow) {
729730
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
730-
struct sock *sk = (struct sock *)msk;
731-
struct mptcp_addr_info local;
731+
struct mptcp_addr_info local, remote;
732+
bool slow;
732733

733734
local_address((struct sock_common *)ssk, &local);
734735
if (!mptcp_addresses_equal(&local, addr, addr->port))
735736
continue;
736737

738+
if (rem && rem->family != AF_UNSPEC) {
739+
remote_address((struct sock_common *)ssk, &remote);
740+
if (!mptcp_addresses_equal(&remote, rem, rem->port))
741+
continue;
742+
}
743+
744+
slow = lock_sock_fast(ssk);
737745
if (subflow->backup != bkup)
738746
msk->last_snd = NULL;
739747
subflow->backup = bkup;
740748
subflow->send_mp_prio = 1;
741749
subflow->request_bkup = bkup;
742-
__MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPPRIOTX);
743750

744-
spin_unlock_bh(&msk->pm.lock);
745751
pr_debug("send ack for mp_prio");
746-
mptcp_subflow_send_ack(ssk);
747-
spin_lock_bh(&msk->pm.lock);
752+
__mptcp_subflow_send_ack(ssk);
753+
unlock_sock_fast(ssk, slow);
748754

749755
return 0;
750756
}
@@ -801,7 +807,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
801807
removed = true;
802808
__MPTCP_INC_STATS(sock_net(sk), rm_type);
803809
}
804-
__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
810+
if (rm_type == MPTCP_MIB_RMSUBFLOW)
811+
__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
805812
if (!removed)
806813
continue;
807814

@@ -1816,8 +1823,10 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
18161823

18171824
list.ids[list.nr++] = addr->id;
18181825

1826+
spin_lock_bh(&msk->pm.lock);
18191827
mptcp_pm_nl_rm_subflow_received(msk, &list);
18201828
mptcp_pm_create_subflow_or_signal_addr(msk);
1829+
spin_unlock_bh(&msk->pm.lock);
18211830
}
18221831

18231832
static int mptcp_nl_set_flags(struct net *net,
@@ -1835,12 +1844,10 @@ static int mptcp_nl_set_flags(struct net *net,
18351844
goto next;
18361845

18371846
lock_sock(sk);
1838-
spin_lock_bh(&msk->pm.lock);
18391847
if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
1840-
ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup);
1848+
ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup);
18411849
if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
18421850
mptcp_pm_nl_fullmesh(msk, addr);
1843-
spin_unlock_bh(&msk->pm.lock);
18441851
release_sock(sk);
18451852

18461853
next:
@@ -1854,6 +1861,9 @@ static int mptcp_nl_set_flags(struct net *net,
18541861
static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
18551862
{
18561863
struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, }, *entry;
1864+
struct mptcp_pm_addr_entry remote = { .addr = { .family = AF_UNSPEC }, };
1865+
struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
1866+
struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
18571867
struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
18581868
struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
18591869
u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |
@@ -1866,6 +1876,12 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
18661876
if (ret < 0)
18671877
return ret;
18681878

1879+
if (attr_rem) {
1880+
ret = mptcp_pm_parse_entry(attr_rem, info, false, &remote);
1881+
if (ret < 0)
1882+
return ret;
1883+
}
1884+
18691885
if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
18701886
bkup = 1;
18711887
if (addr.addr.family == AF_UNSPEC) {
@@ -1874,6 +1890,10 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
18741890
return -EOPNOTSUPP;
18751891
}
18761892

1893+
if (token)
1894+
return mptcp_userspace_pm_set_flags(sock_net(skb->sk),
1895+
token, &addr, &remote, bkup);
1896+
18771897
spin_lock_bh(&pernet->lock);
18781898
entry = __lookup_addr(pernet, &addr.addr, lookup_by_id);
18791899
if (!entry) {

net/mptcp/pm_userspace.c

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include "protocol.h"
8+
#include "mib.h"
89

910
void mptcp_free_local_addr_list(struct mptcp_sock *msk)
1011
{
@@ -306,15 +307,11 @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk,
306307
const struct mptcp_addr_info *local,
307308
const struct mptcp_addr_info *remote)
308309
{
309-
struct sock *sk = &msk->sk.icsk_inet.sk;
310310
struct mptcp_subflow_context *subflow;
311-
struct sock *found = NULL;
312311

313312
if (local->family != remote->family)
314313
return NULL;
315314

316-
lock_sock(sk);
317-
318315
mptcp_for_each_subflow(msk, subflow) {
319316
const struct inet_sock *issk;
320317
struct sock *ssk;
@@ -347,16 +344,11 @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk,
347344
}
348345

349346
if (issk->inet_sport == local->port &&
350-
issk->inet_dport == remote->port) {
351-
found = ssk;
352-
goto found;
353-
}
347+
issk->inet_dport == remote->port)
348+
return ssk;
354349
}
355350

356-
found:
357-
release_sock(sk);
358-
359-
return found;
351+
return NULL;
360352
}
361353

362354
int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
@@ -412,18 +404,51 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
412404
}
413405

414406
sk = &msk->sk.icsk_inet.sk;
407+
lock_sock(sk);
415408
ssk = mptcp_nl_find_ssk(msk, &addr_l, &addr_r);
416409
if (ssk) {
417410
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
418411

419412
mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
420413
mptcp_close_ssk(sk, ssk, subflow);
414+
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
421415
err = 0;
422416
} else {
423417
err = -ESRCH;
424418
}
419+
release_sock(sk);
425420

426-
destroy_err:
421+
destroy_err:
427422
sock_put((struct sock *)msk);
428423
return err;
429424
}
425+
426+
int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
427+
struct mptcp_pm_addr_entry *loc,
428+
struct mptcp_pm_addr_entry *rem, u8 bkup)
429+
{
430+
struct mptcp_sock *msk;
431+
int ret = -EINVAL;
432+
u32 token_val;
433+
434+
token_val = nla_get_u32(token);
435+
436+
msk = mptcp_token_get_sock(net, token_val);
437+
if (!msk)
438+
return ret;
439+
440+
if (!mptcp_pm_is_userspace(msk))
441+
goto set_flags_err;
442+
443+
if (loc->addr.family == AF_UNSPEC ||
444+
rem->addr.family == AF_UNSPEC)
445+
goto set_flags_err;
446+
447+
lock_sock((struct sock *)msk);
448+
ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, &rem->addr, bkup);
449+
release_sock((struct sock *)msk);
450+
451+
set_flags_err:
452+
sock_put((struct sock *)msk);
453+
return ret;
454+
}

net/mptcp/protocol.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,13 +506,18 @@ static inline bool tcp_can_send_ack(const struct sock *ssk)
506506
(TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE | TCPF_LISTEN));
507507
}
508508

509+
void __mptcp_subflow_send_ack(struct sock *ssk)
510+
{
511+
if (tcp_can_send_ack(ssk))
512+
tcp_send_ack(ssk);
513+
}
514+
509515
void mptcp_subflow_send_ack(struct sock *ssk)
510516
{
511517
bool slow;
512518

513519
slow = lock_sock_fast(ssk);
514-
if (tcp_can_send_ack(ssk))
515-
tcp_send_ack(ssk);
520+
__mptcp_subflow_send_ack(ssk);
516521
unlock_sock_fast(ssk, slow);
517522
}
518523

net/mptcp/protocol.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,7 @@ void __init mptcp_subflow_init(void);
607607
void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
608608
void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
609609
struct mptcp_subflow_context *subflow);
610+
void __mptcp_subflow_send_ack(struct sock *ssk);
610611
void mptcp_subflow_send_ack(struct sock *ssk);
611612
void mptcp_subflow_reset(struct sock *ssk);
612613
void mptcp_subflow_queue_clean(struct sock *ssk);
@@ -771,6 +772,10 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
771772
const struct mptcp_rm_list *rm_list);
772773
void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup);
773774
void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq);
775+
int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
776+
struct mptcp_addr_info *addr,
777+
struct mptcp_addr_info *rem,
778+
u8 bkup);
774779
bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
775780
const struct mptcp_pm_addr_entry *entry);
776781
void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
@@ -787,7 +792,9 @@ int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
787792
int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
788793
unsigned int id,
789794
u8 *flags, int *ifindex);
790-
795+
int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
796+
struct mptcp_pm_addr_entry *loc,
797+
struct mptcp_pm_addr_entry *rem, u8 bkup);
791798
int mptcp_pm_announce_addr(struct mptcp_sock *msk,
792799
const struct mptcp_addr_info *addr,
793800
bool echo);

tools/testing/selftests/net/mptcp/pm_nl_ctl.c

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static void syntax(char *argv[])
3939
fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n");
4040
fprintf(stderr, "\tdel <id> [<ip>]\n");
4141
fprintf(stderr, "\tget <id>\n");
42-
fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>]\n");
42+
fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>] [token <token>] [rip <ip>] [rport <port>]\n");
4343
fprintf(stderr, "\tflush\n");
4444
fprintf(stderr, "\tdump\n");
4545
fprintf(stderr, "\tlimits [<rcv addr max> <subflow max>]\n");
@@ -1279,7 +1279,10 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
12791279
struct rtattr *rta, *nest;
12801280
struct nlmsghdr *nh;
12811281
u_int32_t flags = 0;
1282+
u_int32_t token = 0;
1283+
u_int16_t rport = 0;
12821284
u_int16_t family;
1285+
void *rip = NULL;
12831286
int nest_start;
12841287
int use_id = 0;
12851288
u_int8_t id;
@@ -1339,7 +1342,13 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
13391342
error(1, 0, " missing flags keyword");
13401343

13411344
for (; arg < argc; arg++) {
1342-
if (!strcmp(argv[arg], "flags")) {
1345+
if (!strcmp(argv[arg], "token")) {
1346+
if (++arg >= argc)
1347+
error(1, 0, " missing token value");
1348+
1349+
/* token */
1350+
token = atoi(argv[arg]);
1351+
} else if (!strcmp(argv[arg], "flags")) {
13431352
char *tok, *str;
13441353

13451354
/* flags */
@@ -1378,12 +1387,72 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
13781387
rta->rta_len = RTA_LENGTH(2);
13791388
memcpy(RTA_DATA(rta), &port, 2);
13801389
off += NLMSG_ALIGN(rta->rta_len);
1390+
} else if (!strcmp(argv[arg], "rport")) {
1391+
if (++arg >= argc)
1392+
error(1, 0, " missing remote port");
1393+
1394+
rport = atoi(argv[arg]);
1395+
} else if (!strcmp(argv[arg], "rip")) {
1396+
if (++arg >= argc)
1397+
error(1, 0, " missing remote ip");
1398+
1399+
rip = argv[arg];
13811400
} else {
13821401
error(1, 0, "unknown keyword %s", argv[arg]);
13831402
}
13841403
}
13851404
nest->rta_len = off - nest_start;
13861405

1406+
/* token */
1407+
if (token) {
1408+
rta = (void *)(data + off);
1409+
rta->rta_type = MPTCP_PM_ATTR_TOKEN;
1410+
rta->rta_len = RTA_LENGTH(4);
1411+
memcpy(RTA_DATA(rta), &token, 4);
1412+
off += NLMSG_ALIGN(rta->rta_len);
1413+
}
1414+
1415+
/* remote addr/port */
1416+
if (rip) {
1417+
nest_start = off;
1418+
nest = (void *)(data + off);
1419+
nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR_REMOTE;
1420+
nest->rta_len = RTA_LENGTH(0);
1421+
off += NLMSG_ALIGN(nest->rta_len);
1422+
1423+
/* addr data */
1424+
rta = (void *)(data + off);
1425+
if (inet_pton(AF_INET, rip, RTA_DATA(rta))) {
1426+
family = AF_INET;
1427+
rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
1428+
rta->rta_len = RTA_LENGTH(4);
1429+
} else if (inet_pton(AF_INET6, rip, RTA_DATA(rta))) {
1430+
family = AF_INET6;
1431+
rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
1432+
rta->rta_len = RTA_LENGTH(16);
1433+
} else {
1434+
error(1, errno, "can't parse ip %s", (char *)rip);
1435+
}
1436+
off += NLMSG_ALIGN(rta->rta_len);
1437+
1438+
/* family */
1439+
rta = (void *)(data + off);
1440+
rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
1441+
rta->rta_len = RTA_LENGTH(2);
1442+
memcpy(RTA_DATA(rta), &family, 2);
1443+
off += NLMSG_ALIGN(rta->rta_len);
1444+
1445+
if (rport) {
1446+
rta = (void *)(data + off);
1447+
rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
1448+
rta->rta_len = RTA_LENGTH(2);
1449+
memcpy(RTA_DATA(rta), &rport, 2);
1450+
off += NLMSG_ALIGN(rta->rta_len);
1451+
}
1452+
1453+
nest->rta_len = off - nest_start;
1454+
}
1455+
13871456
do_nl_req(fd, nh, off, 0);
13881457
return 0;
13891458
}

0 commit comments

Comments
 (0)