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-pm-misc-cleanups-part-3'

Matthieu Baerts says:

====================
mptcp: pm: misc cleanups, part 3

These cleanups lead the way to the unification of the path-manager
interfaces, and allow future extensions. The following patches are not
all linked to each others, but are all related to the path-managers,
except the last three.

- Patch 1: remove unused returned value in mptcp_nl_set_flags().
- Patch 2: new flag: avoid iterating over all connections if not needed.
- Patch 3: add a build check making sure there is enough space in cb-ctx.
- Patch 4: new mptcp_pm_genl_fill_addr helper to reduce duplicated code.
- Patch 5: simplify userspace_pm_append_new_local_addr helper.
- Patch 6: drop unneeded inet6_sk().
- Patch 7: use ipv6_addr_equal() instead of !ipv6_addr_cmp()
- Patch 8: scheduler: split an interface in two.
- Patch 9: scheduler: save 64 bytes of currently unused data.
- Patch 10: small optimisation to exit early in case of retransmissions.
====================

Link: https://patch.msgid.link/20250221-net-next-mptcp-pm-misc-cleanup-3-v1-0-2b70ab1cee79@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+94 -81
+3 -2
include/net/mptcp.h
··· 103 103 #define MPTCP_SUBFLOWS_MAX 8 104 104 105 105 struct mptcp_sched_data { 106 - bool reinject; 107 106 u8 subflows; 108 107 struct mptcp_subflow_context *contexts[MPTCP_SUBFLOWS_MAX]; 109 108 }; 110 109 111 110 struct mptcp_sched_ops { 112 - int (*get_subflow)(struct mptcp_sock *msk, 111 + int (*get_send)(struct mptcp_sock *msk, 112 + struct mptcp_sched_data *data); 113 + int (*get_retrans)(struct mptcp_sock *msk, 113 114 struct mptcp_sched_data *data); 114 115 115 116 char name[MPTCP_SCHED_NAME_MAX];
+18 -14
net/mptcp/ctrl.c
··· 401 401 void mptcp_active_detect_blackhole(struct sock *ssk, bool expired) 402 402 { 403 403 struct mptcp_subflow_context *subflow; 404 + u8 timeouts, to_max; 405 + struct net *net; 404 406 405 - if (!sk_is_mptcp(ssk)) 407 + /* Only check MPTCP SYN ... */ 408 + if (likely(!sk_is_mptcp(ssk) || ssk->sk_state != TCP_SYN_SENT)) 406 409 return; 407 410 408 411 subflow = mptcp_subflow_ctx(ssk); 409 412 410 - if (subflow->request_mptcp && ssk->sk_state == TCP_SYN_SENT) { 411 - struct net *net = sock_net(ssk); 412 - u8 timeouts, to_max; 413 - 414 - timeouts = inet_csk(ssk)->icsk_retransmits; 415 - to_max = mptcp_get_pernet(net)->syn_retrans_before_tcp_fallback; 416 - 417 - if (timeouts == to_max || (timeouts < to_max && expired)) { 418 - MPTCP_INC_STATS(net, MPTCP_MIB_MPCAPABLEACTIVEDROP); 419 - subflow->mpc_drop = 1; 420 - mptcp_subflow_early_fallback(mptcp_sk(subflow->conn), subflow); 421 - } 422 - } else if (ssk->sk_state == TCP_SYN_SENT) { 413 + /* ... + MP_CAPABLE */ 414 + if (!subflow->request_mptcp) { 415 + /* Mark as blackhole iif the 1st non-MPTCP SYN is accepted */ 423 416 subflow->mpc_drop = 0; 417 + return; 418 + } 419 + 420 + net = sock_net(ssk); 421 + timeouts = inet_csk(ssk)->icsk_retransmits; 422 + to_max = mptcp_get_pernet(net)->syn_retrans_before_tcp_fallback; 423 + 424 + if (timeouts == to_max || (timeouts < to_max && expired)) { 425 + MPTCP_INC_STATS(net, MPTCP_MIB_MPCAPABLEACTIVEDROP); 426 + subflow->mpc_drop = 1; 427 + mptcp_subflow_early_fallback(mptcp_sk(subflow->conn), subflow); 424 428 } 425 429 } 426 430
+21
net/mptcp/pm.c
··· 489 489 return ret; 490 490 } 491 491 492 + int mptcp_pm_genl_fill_addr(struct sk_buff *msg, 493 + struct netlink_callback *cb, 494 + struct mptcp_pm_addr_entry *entry) 495 + { 496 + void *hdr; 497 + 498 + hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid, 499 + cb->nlh->nlmsg_seq, &mptcp_genl_family, 500 + NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR); 501 + if (!hdr) 502 + return -EINVAL; 503 + 504 + if (mptcp_nl_fill_addr(msg, entry) < 0) { 505 + genlmsg_cancel(msg, hdr); 506 + return -EINVAL; 507 + } 508 + 509 + genlmsg_end(msg, hdr); 510 + return 0; 511 + } 512 + 492 513 static int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb) 493 514 { 494 515 const struct genl_info *info = genl_info_dump(cb);
+16 -30
net/mptcp/pm_netlink.c
··· 64 64 addr_equals = a->addr.s_addr == b->addr.s_addr; 65 65 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 66 66 else 67 - addr_equals = !ipv6_addr_cmp(&a->addr6, &b->addr6); 67 + addr_equals = ipv6_addr_equal(&a->addr6, &b->addr6); 68 68 } else if (a->family == AF_INET) { 69 69 if (ipv6_addr_v4mapped(&b->addr6)) 70 70 addr_equals = a->addr.s_addr == b->addr6.s6_addr32[3]; ··· 1798 1798 struct mptcp_pm_addr_entry *entry; 1799 1799 struct pm_nl_pernet *pernet; 1800 1800 int id = cb->args[0]; 1801 - void *hdr; 1802 1801 int i; 1803 1802 1804 1803 pernet = pm_nl_get_pernet(net); ··· 1812 1813 if (entry->addr.id <= id) 1813 1814 continue; 1814 1815 1815 - hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid, 1816 - cb->nlh->nlmsg_seq, &mptcp_genl_family, 1817 - NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR); 1818 - if (!hdr) 1816 + if (mptcp_pm_genl_fill_addr(msg, cb, entry) < 0) 1819 1817 break; 1820 - 1821 - if (mptcp_nl_fill_addr(msg, entry) < 0) { 1822 - genlmsg_cancel(msg, hdr); 1823 - break; 1824 - } 1825 1818 1826 1819 id = entry->addr.id; 1827 - genlmsg_end(msg, hdr); 1828 1820 } 1829 1821 } 1830 1822 rcu_read_unlock(); ··· 1912 1922 spin_unlock_bh(&msk->pm.lock); 1913 1923 } 1914 1924 1915 - static int mptcp_nl_set_flags(struct net *net, 1916 - struct mptcp_addr_info *addr, 1917 - u8 bkup, u8 changed) 1925 + static void mptcp_nl_set_flags(struct net *net, struct mptcp_addr_info *addr, 1926 + u8 flags, u8 changed) 1918 1927 { 1928 + u8 is_subflow = !!(flags & MPTCP_PM_ADDR_FLAG_SUBFLOW); 1929 + u8 bkup = !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP); 1919 1930 long s_slot = 0, s_num = 0; 1920 1931 struct mptcp_sock *msk; 1921 - int ret = -EINVAL; 1932 + 1933 + if (changed == MPTCP_PM_ADDR_FLAG_FULLMESH && !is_subflow) 1934 + return; 1922 1935 1923 1936 while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) { 1924 1937 struct sock *sk = (struct sock *)msk; ··· 1931 1938 1932 1939 lock_sock(sk); 1933 1940 if (changed & MPTCP_PM_ADDR_FLAG_BACKUP) 1934 - ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup); 1935 - if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH) 1941 + mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup); 1942 + /* Subflows will only be recreated if the SUBFLOW flag is set */ 1943 + if (is_subflow && (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)) 1936 1944 mptcp_pm_nl_fullmesh(msk, addr); 1937 1945 release_sock(sk); 1938 1946 ··· 1942 1948 cond_resched(); 1943 1949 } 1944 1950 1945 - return ret; 1951 + return; 1946 1952 } 1947 1953 1948 1954 int mptcp_pm_nl_set_flags(struct mptcp_pm_addr_entry *local, ··· 1955 1961 struct mptcp_pm_addr_entry *entry; 1956 1962 struct pm_nl_pernet *pernet; 1957 1963 u8 lookup_by_id = 0; 1958 - u8 bkup = 0; 1959 1964 1960 1965 pernet = pm_nl_get_pernet(net); 1961 1966 ··· 1966 1973 return -EOPNOTSUPP; 1967 1974 } 1968 1975 } 1969 - 1970 - if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP) 1971 - bkup = 1; 1972 1976 1973 1977 spin_lock_bh(&pernet->lock); 1974 1978 entry = lookup_by_id ? __lookup_addr_by_id(pernet, local->addr.id) : ··· 1988 1998 *local = *entry; 1989 1999 spin_unlock_bh(&pernet->lock); 1990 2000 1991 - mptcp_nl_set_flags(net, &local->addr, bkup, changed); 2001 + mptcp_nl_set_flags(net, &local->addr, entry->flags, changed); 1992 2002 return 0; 1993 2003 } 1994 2004 ··· 2022 2032 break; 2023 2033 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 2024 2034 case AF_INET6: { 2025 - const struct ipv6_pinfo *np = inet6_sk(ssk); 2026 - 2027 - if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &np->saddr)) 2035 + if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &issk->pinet6->saddr)) 2028 2036 return -EMSGSIZE; 2029 2037 if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &ssk->sk_v6_daddr)) 2030 2038 return -EMSGSIZE; ··· 2249 2261 break; 2250 2262 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 2251 2263 case AF_INET6: { 2252 - const struct ipv6_pinfo *np = inet6_sk(ssk); 2253 - 2254 - if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &np->saddr)) 2264 + if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &issk->pinet6->saddr)) 2255 2265 goto nla_put_failure; 2256 2266 break; 2257 2267 }
+7 -22
net/mptcp/pm_userspace.c
··· 48 48 bool needs_id) 49 49 { 50 50 DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); 51 - struct mptcp_pm_addr_entry *match = NULL; 52 51 struct sock *sk = (struct sock *)msk; 53 52 struct mptcp_pm_addr_entry *e; 54 53 bool addr_match = false; ··· 62 63 if (addr_match && entry->addr.id == 0 && needs_id) 63 64 entry->addr.id = e->addr.id; 64 65 id_match = (e->addr.id == entry->addr.id); 65 - if (addr_match && id_match) { 66 - match = e; 66 + if (addr_match || id_match) 67 67 break; 68 - } else if (addr_match || id_match) { 69 - break; 70 - } 71 68 __set_bit(e->addr.id, id_bitmap); 72 69 } 73 70 74 - if (!match && !addr_match && !id_match) { 71 + if (!addr_match && !id_match) { 75 72 /* Memory for the entry is allocated from the 76 73 * sock option buffer. 77 74 */ ··· 85 90 list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list); 86 91 msk->pm.local_addr_used++; 87 92 ret = e->addr.id; 88 - } else if (match) { 93 + } else if (addr_match && id_match) { 89 94 ret = entry->addr.id; 90 95 } 91 96 ··· 460 465 break; 461 466 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 462 467 case AF_INET6: { 463 - const struct ipv6_pinfo *pinfo = inet6_sk(ssk); 464 - 465 - if (!ipv6_addr_equal(&local->addr6, &pinfo->saddr) || 468 + if (!ipv6_addr_equal(&local->addr6, &issk->pinet6->saddr) || 466 469 !ipv6_addr_equal(&remote->addr6, &ssk->sk_v6_daddr)) 467 470 continue; 468 471 break; ··· 634 641 struct mptcp_sock *msk; 635 642 int ret = -EINVAL; 636 643 struct sock *sk; 637 - void *hdr; 644 + 645 + BUILD_BUG_ON(sizeof(struct id_bitmap) > sizeof(cb->ctx)); 638 646 639 647 bitmap = (struct id_bitmap *)cb->ctx; 640 648 ··· 651 657 if (test_bit(entry->addr.id, bitmap->map)) 652 658 continue; 653 659 654 - hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid, 655 - cb->nlh->nlmsg_seq, &mptcp_genl_family, 656 - NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR); 657 - if (!hdr) 660 + if (mptcp_pm_genl_fill_addr(msg, cb, entry) < 0) 658 661 break; 659 - 660 - if (mptcp_nl_fill_addr(msg, entry) < 0) { 661 - genlmsg_cancel(msg, hdr); 662 - break; 663 - } 664 662 665 663 __set_bit(entry->addr.id, bitmap->map); 666 - genlmsg_end(msg, hdr); 667 664 } 668 665 spin_unlock_bh(&msk->pm.lock); 669 666 release_sock(sk);
+3
net/mptcp/protocol.h
··· 1057 1057 struct request_sock *req); 1058 1058 int mptcp_nl_fill_addr(struct sk_buff *skb, 1059 1059 struct mptcp_pm_addr_entry *entry); 1060 + int mptcp_pm_genl_fill_addr(struct sk_buff *msg, 1061 + struct netlink_callback *cb, 1062 + struct mptcp_pm_addr_entry *entry); 1060 1063 1061 1064 static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk) 1062 1065 {
+26 -13
net/mptcp/sched.c
··· 16 16 static DEFINE_SPINLOCK(mptcp_sched_list_lock); 17 17 static LIST_HEAD(mptcp_sched_list); 18 18 19 - static int mptcp_sched_default_get_subflow(struct mptcp_sock *msk, 19 + static int mptcp_sched_default_get_send(struct mptcp_sock *msk, 20 + struct mptcp_sched_data *data) 21 + { 22 + struct sock *ssk; 23 + 24 + ssk = mptcp_subflow_get_send(msk); 25 + if (!ssk) 26 + return -EINVAL; 27 + 28 + mptcp_subflow_set_scheduled(mptcp_subflow_ctx(ssk), true); 29 + return 0; 30 + } 31 + 32 + static int mptcp_sched_default_get_retrans(struct mptcp_sock *msk, 20 33 struct mptcp_sched_data *data) 21 34 { 22 35 struct sock *ssk; 23 36 24 - ssk = data->reinject ? mptcp_subflow_get_retrans(msk) : 25 - mptcp_subflow_get_send(msk); 37 + ssk = mptcp_subflow_get_retrans(msk); 26 38 if (!ssk) 27 39 return -EINVAL; 28 40 ··· 43 31 } 44 32 45 33 static struct mptcp_sched_ops mptcp_sched_default = { 46 - .get_subflow = mptcp_sched_default_get_subflow, 34 + .get_send = mptcp_sched_default_get_send, 35 + .get_retrans = mptcp_sched_default_get_retrans, 47 36 .name = "default", 48 37 .owner = THIS_MODULE, 49 38 }; ··· 86 73 87 74 int mptcp_register_scheduler(struct mptcp_sched_ops *sched) 88 75 { 89 - if (!sched->get_subflow) 76 + if (!sched->get_send) 90 77 return -EINVAL; 91 78 92 79 spin_lock(&mptcp_sched_list_lock); ··· 157 144 int mptcp_sched_get_send(struct mptcp_sock *msk) 158 145 { 159 146 struct mptcp_subflow_context *subflow; 160 - struct mptcp_sched_data data; 147 + struct mptcp_sched_data *data = NULL; 161 148 162 149 msk_owned_by_me(msk); 163 150 ··· 177 164 return 0; 178 165 } 179 166 180 - data.reinject = false; 181 167 if (msk->sched == &mptcp_sched_default || !msk->sched) 182 - return mptcp_sched_default_get_subflow(msk, &data); 183 - return msk->sched->get_subflow(msk, &data); 168 + return mptcp_sched_default_get_send(msk, data); 169 + return msk->sched->get_send(msk, data); 184 170 } 185 171 186 172 int mptcp_sched_get_retrans(struct mptcp_sock *msk) 187 173 { 188 174 struct mptcp_subflow_context *subflow; 189 - struct mptcp_sched_data data; 175 + struct mptcp_sched_data *data = NULL; 190 176 191 177 msk_owned_by_me(msk); 192 178 ··· 198 186 return 0; 199 187 } 200 188 201 - data.reinject = true; 202 189 if (msk->sched == &mptcp_sched_default || !msk->sched) 203 - return mptcp_sched_default_get_subflow(msk, &data); 204 - return msk->sched->get_subflow(msk, &data); 190 + return mptcp_sched_default_get_retrans(msk, data); 191 + if (msk->sched->get_retrans) 192 + return msk->sched->get_retrans(msk, data); 193 + return msk->sched->get_send(msk, data); 205 194 }