History

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. ====================

David S. Miller committed 4 years ago

Commit ae9fdf62 parents 44d632d d2d21f17 files · +192 −31Browse files

Unified · Split

7 files
  1. net/mptcp/options.c +3 −0
  2. net/mptcp/pm_netlink.c +33 −13
  3. net/mptcp/pm_userspace.c +38 −13
  4. net/mptcp/protocol.c +7 −2
  5. net/mptcp/protocol.h +8 −1
  6. tools/testing/selftests/net/mptcp/pm_nl_ctl.c +71 −2
  7. tools/testing/selftests/net/mptcp/userspace_pm.sh +32 −0
net/mptcp/options.c+3−0
@@ -1584,6 +1584,9 @@ mp_rst: · 1583 unmodified lines
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+33−13
@@ -717,9 +717,10 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk) · 716 unmodified lines
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
@@ -727,24 +728,29 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, · 1 unmodified line
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, · 50 unmodified lines
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, · 1008 unmodified lines
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, · 11 unmodified lines
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 @@ next: · 7 unmodified lines
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) · 6 unmodified lines
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) · 2 unmodified lines
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+38−13
@@ -5,6 +5,7 @@ · 4 unmodified lines
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, · 295 unmodified lines
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, · 26 unmodified lines
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) · 49 unmodified lines
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+7−2
@@ -506,13 +506,18 @@ static inline bool tcp_can_send_ack(const struct sock *ssk) · 505 unmodified lines
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+8−1
@@ -607,6 +607,7 @@ void __init mptcp_subflow_init(void); · 606 unmodified lines
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, · 158 unmodified lines
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, · 10 unmodified lines
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+71−2
@@ -39,7 +39,7 @@ static void syntax(char *argv[]) · 38 unmodified lines
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[]) · 1233 unmodified lines
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[]) · 53 unmodified lines
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[]) · 32 unmodified lines
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 }
tools/testing/selftests/net/mptcp/userspace_pm.sh+32−0
@@ -770,10 +770,42 @@ test_subflows() · 769 unmodified lines
770770 rm -f "$evts"
771771 }
772772
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+
773804 make_connection
774805 make_connection "v6"
775806 test_announce
776807 test_remove
777808 test_subflows
809+test_prio
778810
779811 exit 0