Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <davem@davemloft.net>

+192 -31
+3
net/mptcp/options.c
··· 1584 1584 *ptr++ = mptcp_option(MPTCPOPT_MP_PRIO, 1585 1585 TCPOLEN_MPTCP_PRIO, 1586 1586 opts->backup, TCPOPT_NOP); 1587 + 1588 + MPTCP_INC_STATS(sock_net((const struct sock *)tp), 1589 + MPTCP_MIB_MPPRIOTX); 1587 1590 } 1588 1591 1589 1592 mp_capable_done:
+33 -13
net/mptcp/pm_netlink.c
··· 717 717 } 718 718 } 719 719 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) 723 724 { 724 725 struct mptcp_subflow_context *subflow; 725 726 ··· 728 727 729 728 mptcp_for_each_subflow(msk, subflow) { 730 729 struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 731 - struct sock *sk = (struct sock *)msk; 732 - struct mptcp_addr_info local; 730 + struct mptcp_addr_info local, remote; 731 + bool slow; 733 732 734 733 local_address((struct sock_common *)ssk, &local); 735 734 if (!mptcp_addresses_equal(&local, addr, addr->port)) 736 735 continue; 737 736 737 + if (rem && rem->family != AF_UNSPEC) { 738 + remote_address((struct sock_common *)ssk, &remote); 739 + if (!mptcp_addresses_equal(&remote, rem, rem->port)) 740 + continue; 741 + } 742 + 743 + slow = lock_sock_fast(ssk); 738 744 if (subflow->backup != bkup) 739 745 msk->last_snd = NULL; 740 746 subflow->backup = bkup; 741 747 subflow->send_mp_prio = 1; 742 748 subflow->request_bkup = bkup; 743 - __MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPPRIOTX); 744 749 745 - spin_unlock_bh(&msk->pm.lock); 746 750 pr_debug("send ack for mp_prio"); 747 - mptcp_subflow_send_ack(ssk); 748 - spin_lock_bh(&msk->pm.lock); 751 + __mptcp_subflow_send_ack(ssk); 752 + unlock_sock_fast(ssk, slow); 749 753 750 754 return 0; 751 755 } ··· 807 801 removed = true; 808 802 __MPTCP_INC_STATS(sock_net(sk), rm_type); 809 803 } 810 - __set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap); 804 + if (rm_type == MPTCP_MIB_RMSUBFLOW) 805 + __set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap); 811 806 if (!removed) 812 807 continue; 813 808 ··· 1823 1816 1824 1817 list.ids[list.nr++] = addr->id; 1825 1818 1819 + spin_lock_bh(&msk->pm.lock); 1826 1820 mptcp_pm_nl_rm_subflow_received(msk, &list); 1827 1821 mptcp_pm_create_subflow_or_signal_addr(msk); 1822 + spin_unlock_bh(&msk->pm.lock); 1828 1823 } 1829 1824 1830 1825 static int mptcp_nl_set_flags(struct net *net, ··· 1844 1835 goto next; 1845 1836 1846 1837 lock_sock(sk); 1847 - spin_lock_bh(&msk->pm.lock); 1848 1838 if (changed & MPTCP_PM_ADDR_FLAG_BACKUP) 1849 - ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup); 1839 + ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup); 1850 1840 if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH) 1851 1841 mptcp_pm_nl_fullmesh(msk, addr); 1852 - spin_unlock_bh(&msk->pm.lock); 1853 1842 release_sock(sk); 1854 1843 1855 1844 next: ··· 1861 1854 static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info) 1862 1855 { 1863 1856 struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, }, *entry; 1857 + struct mptcp_pm_addr_entry remote = { .addr = { .family = AF_UNSPEC }, }; 1858 + struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE]; 1859 + struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN]; 1864 1860 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR]; 1865 1861 struct pm_nl_pernet *pernet = genl_info_pm_nl(info); 1866 1862 u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP | ··· 1876 1866 if (ret < 0) 1877 1867 return ret; 1878 1868 1869 + if (attr_rem) { 1870 + ret = mptcp_pm_parse_entry(attr_rem, info, false, &remote); 1871 + if (ret < 0) 1872 + return ret; 1873 + } 1874 + 1879 1875 if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP) 1880 1876 bkup = 1; 1881 1877 if (addr.addr.family == AF_UNSPEC) { ··· 1889 1873 if (!addr.addr.id) 1890 1874 return -EOPNOTSUPP; 1891 1875 } 1876 + 1877 + if (token) 1878 + return mptcp_userspace_pm_set_flags(sock_net(skb->sk), 1879 + token, &addr, &remote, bkup); 1892 1880 1893 1881 spin_lock_bh(&pernet->lock); 1894 1882 entry = __lookup_addr(pernet, &addr.addr, lookup_by_id);
+38 -13
net/mptcp/pm_userspace.c
··· 5 5 */ 6 6 7 7 #include "protocol.h" 8 + #include "mib.h" 8 9 9 10 void mptcp_free_local_addr_list(struct mptcp_sock *msk) 10 11 { ··· 307 306 const struct mptcp_addr_info *local, 308 307 const struct mptcp_addr_info *remote) 309 308 { 310 - struct sock *sk = &msk->sk.icsk_inet.sk; 311 309 struct mptcp_subflow_context *subflow; 312 - struct sock *found = NULL; 313 310 314 311 if (local->family != remote->family) 315 312 return NULL; 316 - 317 - lock_sock(sk); 318 313 319 314 mptcp_for_each_subflow(msk, subflow) { 320 315 const struct inet_sock *issk; ··· 344 347 } 345 348 346 349 if (issk->inet_sport == local->port && 347 - issk->inet_dport == remote->port) { 348 - found = ssk; 349 - goto found; 350 - } 350 + issk->inet_dport == remote->port) 351 + return ssk; 351 352 } 352 353 353 - found: 354 - release_sock(sk); 355 - 356 - return found; 354 + return NULL; 357 355 } 358 356 359 357 int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info) ··· 404 412 } 405 413 406 414 sk = &msk->sk.icsk_inet.sk; 415 + lock_sock(sk); 407 416 ssk = mptcp_nl_find_ssk(msk, &addr_l, &addr_r); 408 417 if (ssk) { 409 418 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); 410 419 411 420 mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN); 412 421 mptcp_close_ssk(sk, ssk, subflow); 422 + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW); 413 423 err = 0; 414 424 } else { 415 425 err = -ESRCH; 416 426 } 427 + release_sock(sk); 417 428 418 - destroy_err: 429 + destroy_err: 419 430 sock_put((struct sock *)msk); 420 431 return err; 432 + } 433 + 434 + int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token, 435 + struct mptcp_pm_addr_entry *loc, 436 + struct mptcp_pm_addr_entry *rem, u8 bkup) 437 + { 438 + struct mptcp_sock *msk; 439 + int ret = -EINVAL; 440 + u32 token_val; 441 + 442 + token_val = nla_get_u32(token); 443 + 444 + msk = mptcp_token_get_sock(net, token_val); 445 + if (!msk) 446 + return ret; 447 + 448 + if (!mptcp_pm_is_userspace(msk)) 449 + goto set_flags_err; 450 + 451 + if (loc->addr.family == AF_UNSPEC || 452 + rem->addr.family == AF_UNSPEC) 453 + goto set_flags_err; 454 + 455 + lock_sock((struct sock *)msk); 456 + ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, &rem->addr, bkup); 457 + release_sock((struct sock *)msk); 458 + 459 + set_flags_err: 460 + sock_put((struct sock *)msk); 461 + return ret; 421 462 }
+7 -2
net/mptcp/protocol.c
··· 506 506 (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE | TCPF_LISTEN)); 507 507 } 508 508 509 + void __mptcp_subflow_send_ack(struct sock *ssk) 510 + { 511 + if (tcp_can_send_ack(ssk)) 512 + tcp_send_ack(ssk); 513 + } 514 + 509 515 void mptcp_subflow_send_ack(struct sock *ssk) 510 516 { 511 517 bool slow; 512 518 513 519 slow = lock_sock_fast(ssk); 514 - if (tcp_can_send_ack(ssk)) 515 - tcp_send_ack(ssk); 520 + __mptcp_subflow_send_ack(ssk); 516 521 unlock_sock_fast(ssk, slow); 517 522 } 518 523
+8 -1
net/mptcp/protocol.h
··· 607 607 void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how); 608 608 void mptcp_close_ssk(struct sock *sk, struct sock *ssk, 609 609 struct mptcp_subflow_context *subflow); 610 + void __mptcp_subflow_send_ack(struct sock *ssk); 610 611 void mptcp_subflow_send_ack(struct sock *ssk); 611 612 void mptcp_subflow_reset(struct sock *ssk); 612 613 void mptcp_subflow_queue_clean(struct sock *ssk); ··· 772 771 const struct mptcp_rm_list *rm_list); 773 772 void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup); 774 773 void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq); 774 + int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, 775 + struct mptcp_addr_info *addr, 776 + struct mptcp_addr_info *rem, 777 + u8 bkup); 775 778 bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, 776 779 const struct mptcp_pm_addr_entry *entry); 777 780 void mptcp_pm_free_anno_list(struct mptcp_sock *msk); ··· 792 787 int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, 793 788 unsigned int id, 794 789 u8 *flags, int *ifindex); 795 - 790 + int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token, 791 + struct mptcp_pm_addr_entry *loc, 792 + struct mptcp_pm_addr_entry *rem, u8 bkup); 796 793 int mptcp_pm_announce_addr(struct mptcp_sock *msk, 797 794 const struct mptcp_addr_info *addr, 798 795 bool echo);
+71 -2
tools/testing/selftests/net/mptcp/pm_nl_ctl.c
··· 39 39 fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n"); 40 40 fprintf(stderr, "\tdel <id> [<ip>]\n"); 41 41 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"); 43 43 fprintf(stderr, "\tflush\n"); 44 44 fprintf(stderr, "\tdump\n"); 45 45 fprintf(stderr, "\tlimits [<rcv addr max> <subflow max>]\n"); ··· 1279 1279 struct rtattr *rta, *nest; 1280 1280 struct nlmsghdr *nh; 1281 1281 u_int32_t flags = 0; 1282 + u_int32_t token = 0; 1283 + u_int16_t rport = 0; 1282 1284 u_int16_t family; 1285 + void *rip = NULL; 1283 1286 int nest_start; 1284 1287 int use_id = 0; 1285 1288 u_int8_t id; ··· 1342 1339 error(1, 0, " missing flags keyword"); 1343 1340 1344 1341 for (; arg < argc; arg++) { 1345 - if (!strcmp(argv[arg], "flags")) { 1342 + if (!strcmp(argv[arg], "token")) { 1343 + if (++arg >= argc) 1344 + error(1, 0, " missing token value"); 1345 + 1346 + /* token */ 1347 + token = atoi(argv[arg]); 1348 + } else if (!strcmp(argv[arg], "flags")) { 1346 1349 char *tok, *str; 1347 1350 1348 1351 /* flags */ ··· 1387 1378 rta->rta_len = RTA_LENGTH(2); 1388 1379 memcpy(RTA_DATA(rta), &port, 2); 1389 1380 off += NLMSG_ALIGN(rta->rta_len); 1381 + } else if (!strcmp(argv[arg], "rport")) { 1382 + if (++arg >= argc) 1383 + error(1, 0, " missing remote port"); 1384 + 1385 + rport = atoi(argv[arg]); 1386 + } else if (!strcmp(argv[arg], "rip")) { 1387 + if (++arg >= argc) 1388 + error(1, 0, " missing remote ip"); 1389 + 1390 + rip = argv[arg]; 1390 1391 } else { 1391 1392 error(1, 0, "unknown keyword %s", argv[arg]); 1392 1393 } 1393 1394 } 1394 1395 nest->rta_len = off - nest_start; 1396 + 1397 + /* token */ 1398 + if (token) { 1399 + rta = (void *)(data + off); 1400 + rta->rta_type = MPTCP_PM_ATTR_TOKEN; 1401 + rta->rta_len = RTA_LENGTH(4); 1402 + memcpy(RTA_DATA(rta), &token, 4); 1403 + off += NLMSG_ALIGN(rta->rta_len); 1404 + } 1405 + 1406 + /* remote addr/port */ 1407 + if (rip) { 1408 + nest_start = off; 1409 + nest = (void *)(data + off); 1410 + nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR_REMOTE; 1411 + nest->rta_len = RTA_LENGTH(0); 1412 + off += NLMSG_ALIGN(nest->rta_len); 1413 + 1414 + /* addr data */ 1415 + rta = (void *)(data + off); 1416 + if (inet_pton(AF_INET, rip, RTA_DATA(rta))) { 1417 + family = AF_INET; 1418 + rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4; 1419 + rta->rta_len = RTA_LENGTH(4); 1420 + } else if (inet_pton(AF_INET6, rip, RTA_DATA(rta))) { 1421 + family = AF_INET6; 1422 + rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6; 1423 + rta->rta_len = RTA_LENGTH(16); 1424 + } else { 1425 + error(1, errno, "can't parse ip %s", (char *)rip); 1426 + } 1427 + off += NLMSG_ALIGN(rta->rta_len); 1428 + 1429 + /* family */ 1430 + rta = (void *)(data + off); 1431 + rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY; 1432 + rta->rta_len = RTA_LENGTH(2); 1433 + memcpy(RTA_DATA(rta), &family, 2); 1434 + off += NLMSG_ALIGN(rta->rta_len); 1435 + 1436 + if (rport) { 1437 + rta = (void *)(data + off); 1438 + rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT; 1439 + rta->rta_len = RTA_LENGTH(2); 1440 + memcpy(RTA_DATA(rta), &rport, 2); 1441 + off += NLMSG_ALIGN(rta->rta_len); 1442 + } 1443 + 1444 + nest->rta_len = off - nest_start; 1445 + } 1395 1446 1396 1447 do_nl_req(fd, nh, off, 0); 1397 1448 return 0;
+32
tools/testing/selftests/net/mptcp/userspace_pm.sh
··· 770 770 rm -f "$evts" 771 771 } 772 772 773 + test_prio() 774 + { 775 + local count 776 + 777 + # Send MP_PRIO signal from client to server machine 778 + ip netns exec "$ns2" ./pm_nl_ctl set 10.0.1.2 port "$client4_port" flags backup token "$client4_token" rip 10.0.1.1 rport "$server4_port" 779 + sleep 0.5 780 + 781 + # Check TX 782 + stdbuf -o0 -e0 printf "MP_PRIO TX \t" 783 + count=$(ip netns exec "$ns2" nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}') 784 + [ -z "$count" ] && count=0 785 + if [ $count != 1 ]; then 786 + stdbuf -o0 -e0 printf "[FAIL]\n" 787 + exit 1 788 + else 789 + stdbuf -o0 -e0 printf "[OK]\n" 790 + fi 791 + 792 + # Check RX 793 + stdbuf -o0 -e0 printf "MP_PRIO RX \t" 794 + count=$(ip netns exec "$ns1" nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}') 795 + [ -z "$count" ] && count=0 796 + if [ $count != 1 ]; then 797 + stdbuf -o0 -e0 printf "[FAIL]\n" 798 + exit 1 799 + else 800 + stdbuf -o0 -e0 printf "[OK]\n" 801 + fi 802 + } 803 + 773 804 make_connection 774 805 make_connection "v6" 775 806 test_announce 776 807 test_remove 777 808 test_subflows 809 + test_prio 778 810 779 811 exit 0