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
1584 *ptr++ = mptcp_option(MPTCPOPT_MP_PRIO,1584 *ptr++ = mptcp_option(MPTCPOPT_MP_PRIO,
1585 TCPOLEN_MPTCP_PRIO,1585 TCPOLEN_MPTCP_PRIO,
1586 opts->backup, TCPOPT_NOP);1586 opts->backup, TCPOPT_NOP);
1587
1588 MPTCP_INC_STATS(sock_net((const struct sock *)tp),
1589 MPTCP_MIB_MPPRIOTX);
1587 }1590 }
1588 1591
1589mp_capable_done:1592mp_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
717 }717 }
718}718}
719 719
720static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,720int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
721 struct mptcp_addr_info *addr,721 struct mptcp_addr_info *addr,
722 u8 bkup)722 struct mptcp_addr_info *rem,
723 u8 bkup)
723{724{
724 struct mptcp_subflow_context *subflow;725 struct mptcp_subflow_context *subflow;
725 726
@@ -727,24 +728,29 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, · 1 unmodified line
727 728
728 mptcp_for_each_subflow(msk, subflow) {729 mptcp_for_each_subflow(msk, subflow) {
729 struct sock *ssk = mptcp_subflow_tcp_sock(subflow);730 struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
730 struct sock *sk = (struct sock *)msk;731 struct mptcp_addr_info local, remote;
731 struct mptcp_addr_info local;732 bool slow;
732 733
733 local_address((struct sock_common *)ssk, &local);734 local_address((struct sock_common *)ssk, &local);
734 if (!mptcp_addresses_equal(&local, addr, addr->port))735 if (!mptcp_addresses_equal(&local, addr, addr->port))
735 continue;736 continue;
736 737
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);
737 if (subflow->backup != bkup)745 if (subflow->backup != bkup)
738 msk->last_snd = NULL;746 msk->last_snd = NULL;
739 subflow->backup = bkup;747 subflow->backup = bkup;
740 subflow->send_mp_prio = 1;748 subflow->send_mp_prio = 1;
741 subflow->request_bkup = bkup;749 subflow->request_bkup = bkup;
742 __MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPPRIOTX);
743 750
744 spin_unlock_bh(&msk->pm.lock);
745 pr_debug("send ack for mp_prio");751 pr_debug("send ack for mp_prio");
746 mptcp_subflow_send_ack(ssk);752 __mptcp_subflow_send_ack(ssk);
747 spin_lock_bh(&msk->pm.lock);753 unlock_sock_fast(ssk, slow);
748 754
749 return 0;755 return 0;
750 }756 }
@@ -801,7 +807,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk, · 50 unmodified lines
801 removed = true;807 removed = true;
802 __MPTCP_INC_STATS(sock_net(sk), rm_type);808 __MPTCP_INC_STATS(sock_net(sk), rm_type);
803 }809 }
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);
805 if (!removed)812 if (!removed)
806 continue;813 continue;
807 814
@@ -1816,8 +1823,10 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk, · 1008 unmodified lines
1816 1823
1817 list.ids[list.nr++] = addr->id;1824 list.ids[list.nr++] = addr->id;
1818 1825
1826 spin_lock_bh(&msk->pm.lock);
1819 mptcp_pm_nl_rm_subflow_received(msk, &list);1827 mptcp_pm_nl_rm_subflow_received(msk, &list);
1820 mptcp_pm_create_subflow_or_signal_addr(msk);1828 mptcp_pm_create_subflow_or_signal_addr(msk);
1829 spin_unlock_bh(&msk->pm.lock);
1821}1830}
1822 1831
1823static int mptcp_nl_set_flags(struct net *net,1832static int mptcp_nl_set_flags(struct net *net,
@@ -1835,12 +1844,10 @@ static int mptcp_nl_set_flags(struct net *net, · 11 unmodified lines
1835 goto next;1844 goto next;
1836 1845
1837 lock_sock(sk);1846 lock_sock(sk);
1838 spin_lock_bh(&msk->pm.lock);
1839 if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)1847 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);
1841 if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)1849 if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
1842 mptcp_pm_nl_fullmesh(msk, addr);1850 mptcp_pm_nl_fullmesh(msk, addr);
1843 spin_unlock_bh(&msk->pm.lock);
1844 release_sock(sk);1851 release_sock(sk);
1845 1852
1846next:1853next:
@@ -1854,6 +1861,9 @@ next: · 7 unmodified lines
1854static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)1861static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
1855{1862{
1856 struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, }, *entry;1863 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];
1857 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];1867 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
1858 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);1868 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
1859 u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |1869 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
1866 if (ret < 0)1876 if (ret < 0)
1867 return ret;1877 return ret;
1868 1878
1879 if (attr_rem) {
1880 ret = mptcp_pm_parse_entry(attr_rem, info, false, &remote);
1881 if (ret < 0)
1882 return ret;
1883 }
1884
1869 if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)1885 if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
1870 bkup = 1;1886 bkup = 1;
1871 if (addr.addr.family == AF_UNSPEC) {1887 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
1874 return -EOPNOTSUPP;1890 return -EOPNOTSUPP;
1875 }1891 }
1876 1892
1893 if (token)
1894 return mptcp_userspace_pm_set_flags(sock_net(skb->sk),
1895 token, &addr, &remote, bkup);
1896
1877 spin_lock_bh(&pernet->lock);1897 spin_lock_bh(&pernet->lock);
1878 entry = __lookup_addr(pernet, &addr.addr, lookup_by_id);1898 entry = __lookup_addr(pernet, &addr.addr, lookup_by_id);
1879 if (!entry) {1899 if (!entry) {
net/mptcp/pm_userspace.c+38−13
@@ -5,6 +5,7 @@ · 4 unmodified lines
5 */5 */
6 6
7#include "protocol.h"7#include "protocol.h"
8#include "mib.h"
8 9
9void mptcp_free_local_addr_list(struct mptcp_sock *msk)10void mptcp_free_local_addr_list(struct mptcp_sock *msk)
10{11{
@@ -306,15 +307,11 @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk, · 295 unmodified lines
306 const struct mptcp_addr_info *local,307 const struct mptcp_addr_info *local,
307 const struct mptcp_addr_info *remote)308 const struct mptcp_addr_info *remote)
308{309{
309 struct sock *sk = &msk->sk.icsk_inet.sk;
310 struct mptcp_subflow_context *subflow;310 struct mptcp_subflow_context *subflow;
311 struct sock *found = NULL;
312 311
313 if (local->family != remote->family)312 if (local->family != remote->family)
314 return NULL;313 return NULL;
315 314
316 lock_sock(sk);
317
318 mptcp_for_each_subflow(msk, subflow) {315 mptcp_for_each_subflow(msk, subflow) {
319 const struct inet_sock *issk;316 const struct inet_sock *issk;
320 struct sock *ssk;317 struct sock *ssk;
@@ -347,16 +344,11 @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk, · 26 unmodified lines
347 }344 }
348 345
349 if (issk->inet_sport == local->port &&346 if (issk->inet_sport == local->port &&
350 issk->inet_dport == remote->port) {347 issk->inet_dport == remote->port)
351 found = ssk;348 return ssk;
352 goto found;
353 }
354 }349 }
355 350
356found:351 return NULL;
357 release_sock(sk);
358
359 return found;
360}352}
361 353
362int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)354int 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
412 }404 }
413 405
414 sk = &msk->sk.icsk_inet.sk;406 sk = &msk->sk.icsk_inet.sk;
407 lock_sock(sk);
415 ssk = mptcp_nl_find_ssk(msk, &addr_l, &addr_r);408 ssk = mptcp_nl_find_ssk(msk, &addr_l, &addr_r);
416 if (ssk) {409 if (ssk) {
417 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);410 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
418 411
419 mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);412 mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
420 mptcp_close_ssk(sk, ssk, subflow);413 mptcp_close_ssk(sk, ssk, subflow);
414 MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
421 err = 0;415 err = 0;
422 } else {416 } else {
423 err = -ESRCH;417 err = -ESRCH;
424 }418 }
419 release_sock(sk);
425 420
426 destroy_err:421destroy_err:
427 sock_put((struct sock *)msk);422 sock_put((struct sock *)msk);
428 return err;423 return err;
429}424}
425
426int 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
451set_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
506 (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE | TCPF_LISTEN));506 (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE | TCPF_LISTEN));
507}507}
508 508
509void __mptcp_subflow_send_ack(struct sock *ssk)
510{
511 if (tcp_can_send_ack(ssk))
512 tcp_send_ack(ssk);
513}
514
509void mptcp_subflow_send_ack(struct sock *ssk)515void mptcp_subflow_send_ack(struct sock *ssk)
510{516{
511 bool slow;517 bool slow;
512 518
513 slow = lock_sock_fast(ssk);519 slow = lock_sock_fast(ssk);
514 if (tcp_can_send_ack(ssk))520 __mptcp_subflow_send_ack(ssk);
515 tcp_send_ack(ssk);
516 unlock_sock_fast(ssk, slow);521 unlock_sock_fast(ssk, slow);
517}522}
518 523
net/mptcp/protocol.h+8−1
@@ -607,6 +607,7 @@ void __init mptcp_subflow_init(void); · 606 unmodified lines
607void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);607void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
608void mptcp_close_ssk(struct sock *sk, struct sock *ssk,608void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
609 struct mptcp_subflow_context *subflow);609 struct mptcp_subflow_context *subflow);
610void __mptcp_subflow_send_ack(struct sock *ssk);
610void mptcp_subflow_send_ack(struct sock *ssk);611void mptcp_subflow_send_ack(struct sock *ssk);
611void mptcp_subflow_reset(struct sock *ssk);612void mptcp_subflow_reset(struct sock *ssk);
612void mptcp_subflow_queue_clean(struct sock *ssk);613void mptcp_subflow_queue_clean(struct sock *ssk);
@@ -771,6 +772,10 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, · 158 unmodified lines
771 const struct mptcp_rm_list *rm_list);772 const struct mptcp_rm_list *rm_list);
772void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup);773void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup);
773void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq);774void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq);
775int 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);
774bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,779bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
775 const struct mptcp_pm_addr_entry *entry);780 const struct mptcp_pm_addr_entry *entry);
776void mptcp_pm_free_anno_list(struct mptcp_sock *msk);781void 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
787int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,792int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
788 unsigned int id,793 unsigned int id,
789 u8 *flags, int *ifindex);794 u8 *flags, int *ifindex);
790 795int 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);
791int mptcp_pm_announce_addr(struct mptcp_sock *msk,798int mptcp_pm_announce_addr(struct mptcp_sock *msk,
792 const struct mptcp_addr_info *addr,799 const struct mptcp_addr_info *addr,
793 bool echo);800 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
39 fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n");39 fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n");
40 fprintf(stderr, "\tdel <id> [<ip>]\n");40 fprintf(stderr, "\tdel <id> [<ip>]\n");
41 fprintf(stderr, "\tget <id>\n");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 fprintf(stderr, "\tflush\n");43 fprintf(stderr, "\tflush\n");
44 fprintf(stderr, "\tdump\n");44 fprintf(stderr, "\tdump\n");
45 fprintf(stderr, "\tlimits [<rcv addr max> <subflow max>]\n");45 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
1279 struct rtattr *rta, *nest;1279 struct rtattr *rta, *nest;
1280 struct nlmsghdr *nh;1280 struct nlmsghdr *nh;
1281 u_int32_t flags = 0;1281 u_int32_t flags = 0;
1282 u_int32_t token = 0;
1283 u_int16_t rport = 0;
1282 u_int16_t family;1284 u_int16_t family;
1285 void *rip = NULL;
1283 int nest_start;1286 int nest_start;
1284 int use_id = 0;1287 int use_id = 0;
1285 u_int8_t id;1288 u_int8_t id;
@@ -1339,7 +1342,13 @@ int set_flags(int fd, int pm_family, int argc, char *argv[]) · 53 unmodified lines
1339 error(1, 0, " missing flags keyword");1342 error(1, 0, " missing flags keyword");
1340 1343
1341 for (; arg < argc; arg++) {1344 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")) {
1343 char *tok, *str;1352 char *tok, *str;
1344 1353
1345 /* flags */1354 /* flags */
@@ -1378,12 +1387,72 @@ int set_flags(int fd, int pm_family, int argc, char *argv[]) · 32 unmodified lines
1378 rta->rta_len = RTA_LENGTH(2);1387 rta->rta_len = RTA_LENGTH(2);
1379 memcpy(RTA_DATA(rta), &port, 2);1388 memcpy(RTA_DATA(rta), &port, 2);
1380 off += NLMSG_ALIGN(rta->rta_len);1389 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];
1381 } else {1400 } else {
1382 error(1, 0, "unknown keyword %s", argv[arg]);1401 error(1, 0, "unknown keyword %s", argv[arg]);
1383 }1402 }
1384 }1403 }
1385 nest->rta_len = off - nest_start;1404 nest->rta_len = off - nest_start;
1386 1405
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
1387 do_nl_req(fd, nh, off, 0);1456 do_nl_req(fd, nh, off, 0);
1388 return 0;1457 return 0;
1389}1458}
tools/testing/selftests/net/mptcp/userspace_pm.sh+32−0
@@ -770,10 +770,42 @@ test_subflows() · 769 unmodified lines
770 rm -f "$evts"770 rm -f "$evts"
771}771}
772 772
773test_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
773make_connection804make_connection
774make_connection "v6"805make_connection "v6"
775test_announce806test_announce
776test_remove807test_remove
777test_subflows808test_subflows
809test_prio
778 810
779exit 0811exit 0