Skip to content

Commit d4dd482

Browse files
committed
Merge: mptcp: phase-2 packports for RHEL-9.7
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6795 JIRA: https://issues.redhat.com/browse/RHEL-84571 Upstream Status: all mainline in net-next.git Conflicts: see individual patches Tested: boot-tested only Signed-off-by: Davide Caratti <dcaratti@redhat.com> Approved-by: Paolo Abeni <pabeni@redhat.com> Approved-by: Florian Westphal <fwestpha@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents 9ce3a1b + 0e32ad6 commit d4dd482

File tree

8 files changed

+82
-45
lines changed

8 files changed

+82
-45
lines changed

net/mptcp/mib.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
1515
SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK),
1616
SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK),
1717
SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK),
18+
SNMP_MIB_ITEM("MPCapableEndpAttempt", MPTCP_MIB_MPCAPABLEENDPATTEMPT),
1819
SNMP_MIB_ITEM("MPFallbackTokenInit", MPTCP_MIB_TOKENFALLBACKINIT),
1920
SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS),
2021
SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN),

net/mptcp/mib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ enum linux_mptcp_mib_field {
1010
MPTCP_MIB_MPCAPABLEPASSIVEACK, /* Received third ACK with MP_CAPABLE */
1111
MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */
1212
MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */
13+
MPTCP_MIB_MPCAPABLEENDPATTEMPT, /* Prohibited MPC to port-based endp */
1314
MPTCP_MIB_TOKENFALLBACKINIT, /* Could not init/allocate token */
1415
MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */
1516
MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */

net/mptcp/options.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,6 @@ static void mptcp_parse_option(const struct sk_buff *skb,
156156
pr_debug("DSS\n");
157157
ptr++;
158158

159-
/* we must clear 'mpc_map' be able to detect MP_CAPABLE
160-
* map vs DSS map in mptcp_incoming_options(), and reconstruct
161-
* map info accordingly
162-
*/
163-
mp_opt->mpc_map = 0;
164159
flags = (*ptr++) & MPTCP_DSS_FLAG_MASK;
165160
mp_opt->data_fin = (flags & MPTCP_DSS_DATA_FIN) != 0;
166161
mp_opt->dsn64 = (flags & MPTCP_DSS_DSN64) != 0;
@@ -368,8 +363,11 @@ void mptcp_get_options(const struct sk_buff *skb,
368363
const unsigned char *ptr;
369364
int length;
370365

371-
/* initialize option status */
372-
mp_opt->suboptions = 0;
366+
/* Ensure that casting the whole status to u32 is efficient and safe */
367+
BUILD_BUG_ON(sizeof_field(struct mptcp_options_received, status) != sizeof(u32));
368+
BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct mptcp_options_received, status),
369+
sizeof(u32)));
370+
*(u32 *)&mp_opt->status = 0;
373371

374372
length = (th->doff * 4) - sizeof(struct tcphdr);
375373
ptr = (const unsigned char *)(th + 1);
@@ -606,7 +604,6 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
606604
}
607605
opts->ext_copy.use_ack = 1;
608606
opts->suboptions = OPTION_MPTCP_DSS;
609-
WRITE_ONCE(msk->old_wspace, __mptcp_space((struct sock *)msk));
610607

611608
/* Add kind/length/subtype/flag overhead if mapping is not populated */
612609
if (dss_size == 0)
@@ -654,6 +651,7 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
654651
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
655652
bool drop_other_suboptions = false;
656653
unsigned int opt_size = *size;
654+
struct mptcp_addr_info addr;
657655
bool echo;
658656
int len;
659657

@@ -662,7 +660,7 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
662660
*/
663661
if (!mptcp_pm_should_add_signal(msk) ||
664662
(opts->suboptions & (OPTION_MPTCP_MPJ_ACK | OPTION_MPTCP_MPC_ACK)) ||
665-
!mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, &opts->addr,
663+
!mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, &addr,
666664
&echo, &drop_other_suboptions))
667665
return false;
668666

@@ -675,7 +673,7 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
675673
else if (opts->suboptions & OPTION_MPTCP_DSS)
676674
return false;
677675

678-
len = mptcp_add_addr_len(opts->addr.family, echo, !!opts->addr.port);
676+
len = mptcp_add_addr_len(addr.family, echo, !!addr.port);
679677
if (remaining < len)
680678
return false;
681679

@@ -692,6 +690,7 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
692690
opts->ahmac = 0;
693691
*size -= opt_size;
694692
}
693+
opts->addr = addr;
695694
opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
696695
if (!echo) {
697696
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDRTX);
@@ -1286,7 +1285,7 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th)
12861285
}
12871286
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICT);
12881287
}
1289-
return;
1288+
goto update_wspace;
12901289
}
12911290

12921291
if (rcv_wnd_new != rcv_wnd_old) {
@@ -1311,6 +1310,9 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th)
13111310
th->window = htons(new_win);
13121311
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDSHARED);
13131312
}
1313+
1314+
update_wspace:
1315+
WRITE_ONCE(msk->old_wspace, tp->rcv_wnd);
13141316
}
13151317

13161318
__sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum)

net/mptcp/pm_netlink.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,7 @@ static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry)
972972

973973
static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
974974
struct mptcp_pm_addr_entry *entry,
975-
bool needs_id)
975+
bool needs_id, bool replace)
976976
{
977977
struct mptcp_pm_addr_entry *cur, *del_entry = NULL;
978978
unsigned int addr_max;
@@ -1012,6 +1012,17 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
10121012
if (entry->addr.id)
10131013
goto out;
10141014

1015+
/* allow callers that only need to look up the local
1016+
* addr's id to skip replacement. This allows them to
1017+
* avoid calling synchronize_rcu in the packet recv
1018+
* path.
1019+
*/
1020+
if (!replace) {
1021+
kfree(entry);
1022+
ret = cur->addr.id;
1023+
goto out;
1024+
}
1025+
10151026
pernet->addrs--;
10161027
entry->addr.id = cur->addr.id;
10171028
list_del_rcu(&cur->list);
@@ -1126,6 +1137,7 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
11261137
*/
11271138
inet_sk_state_store(newsk, TCP_LISTEN);
11281139
lock_sock(ssk);
1140+
WRITE_ONCE(mptcp_subflow_ctx(ssk)->pm_listener, true);
11291141
err = __inet_listen_sk(ssk, backlog);
11301142
if (!err)
11311143
mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CREATED);
@@ -1163,7 +1175,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
11631175
entry->ifindex = 0;
11641176
entry->flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
11651177
entry->lsk = NULL;
1166-
ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true);
1178+
ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true, false);
11671179
if (ret < 0)
11681180
kfree(entry);
11691181

@@ -1435,7 +1447,8 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
14351447
}
14361448
}
14371449
ret = mptcp_pm_nl_append_new_local_addr(pernet, entry,
1438-
!mptcp_pm_has_addr_attr_id(attr, info));
1450+
!mptcp_pm_has_addr_attr_id(attr, info),
1451+
true);
14391452
if (ret < 0) {
14401453
GENL_SET_ERR_MSG_FMT(info, "too many addresses or duplicate one: %d", ret);
14411454
goto out_free;
@@ -1538,11 +1551,6 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
15381551
if (mptcp_pm_is_userspace(msk))
15391552
goto next;
15401553

1541-
if (list_empty(&msk->conn_list)) {
1542-
mptcp_pm_remove_anno_addr(msk, addr, false);
1543-
goto next;
1544-
}
1545-
15461554
lock_sock(sk);
15471555
remove_subflow = lookup_subflow_by_saddr(&msk->conn_list, addr);
15481556
mptcp_pm_remove_anno_addr(msk, addr, remove_subflow &&
@@ -2045,7 +2053,8 @@ int mptcp_pm_nl_set_flags(struct net *net, struct mptcp_pm_addr_entry *addr, u8
20452053
return -EINVAL;
20462054
}
20472055
if ((addr->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) &&
2048-
(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
2056+
(entry->flags & (MPTCP_PM_ADDR_FLAG_SIGNAL |
2057+
MPTCP_PM_ADDR_FLAG_IMPLICIT))) {
20492058
spin_unlock_bh(&pernet->lock);
20502059
return -EINVAL;
20512060
}

net/mptcp/pm_userspace.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
316316
}
317317

318318
lock_sock(sk);
319-
319+
spin_lock_bh(&msk->pm.lock);
320320
list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
321321
if (entry->addr.id == id_val) {
322322
match = entry;
@@ -326,11 +326,13 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
326326

327327
if (!match) {
328328
GENL_SET_ERR_MSG(info, "address with specified id not found");
329+
spin_unlock_bh(&msk->pm.lock);
329330
release_sock(sk);
330331
goto remove_err;
331332
}
332333

333334
list_move(&match->list, &free_list);
335+
spin_unlock_bh(&msk->pm.lock);
334336

335337
mptcp_pm_remove_addrs(msk, &free_list);
336338

net/mptcp/protocol.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1763,8 +1763,10 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
17631763
* see mptcp_disconnect().
17641764
* Attempt it again outside the problematic scope.
17651765
*/
1766-
if (!mptcp_disconnect(sk, 0))
1766+
if (!mptcp_disconnect(sk, 0)) {
1767+
sk->sk_disconnects++;
17671768
sk->sk_socket->state = SS_UNCONNECTED;
1769+
}
17681770
}
17691771
inet_sk(sk)->defer_connect = 0;
17701772

net/mptcp/protocol.h

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -149,22 +149,24 @@ struct mptcp_options_received {
149149
u32 subflow_seq;
150150
u16 data_len;
151151
__sum16 csum;
152-
u16 suboptions;
152+
struct_group(status,
153+
u16 suboptions;
154+
u16 use_map:1,
155+
dsn64:1,
156+
data_fin:1,
157+
use_ack:1,
158+
ack64:1,
159+
mpc_map:1,
160+
reset_reason:4,
161+
reset_transient:1,
162+
echo:1,
163+
backup:1,
164+
deny_join_id0:1,
165+
__unused:2;
166+
);
167+
u8 join_id;
153168
u32 token;
154169
u32 nonce;
155-
u16 use_map:1,
156-
dsn64:1,
157-
data_fin:1,
158-
use_ack:1,
159-
ack64:1,
160-
mpc_map:1,
161-
reset_reason:4,
162-
reset_transient:1,
163-
echo:1,
164-
backup:1,
165-
deny_join_id0:1,
166-
__unused:2;
167-
u8 join_id;
168170
u64 thmac;
169171
u8 hmac[MPTCPOPT_HMAC_LEN];
170172
struct mptcp_addr_info addr;
@@ -518,6 +520,7 @@ struct mptcp_subflow_context {
518520
__unused : 9;
519521
bool data_avail;
520522
bool scheduled;
523+
bool pm_listener; /* a listener managed by the kernel PM? */
521524
u32 remote_nonce;
522525
u64 thmac;
523526
u32 local_nonce;
@@ -736,10 +739,15 @@ static inline u64 mptcp_data_avail(const struct mptcp_sock *msk)
736739

737740
static inline bool mptcp_epollin_ready(const struct sock *sk)
738741
{
742+
u64 data_avail = mptcp_data_avail(mptcp_sk(sk));
743+
744+
if (!data_avail)
745+
return false;
746+
739747
/* mptcp doesn't have to deal with small skbs in the receive queue,
740-
* at it can always coalesce them
748+
* as it can always coalesce them
741749
*/
742-
return (mptcp_data_avail(mptcp_sk(sk)) >= sk->sk_rcvlowat) ||
750+
return (data_avail >= sk->sk_rcvlowat) ||
743751
(mem_cgroup_sockets_enabled && sk->sk_memcg &&
744752
mem_cgroup_under_socket_pressure(sk->sk_memcg)) ||
745753
READ_ONCE(tcp_memory_pressure);

net/mptcp/subflow.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,13 @@ static void subflow_add_reset_reason(struct sk_buff *skb, u8 reason)
134134
}
135135
}
136136

137+
static int subflow_reset_req_endp(struct request_sock *req, struct sk_buff *skb)
138+
{
139+
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEENDPATTEMPT);
140+
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
141+
return -EPERM;
142+
}
143+
137144
/* Init mptcp request socket.
138145
*
139146
* Returns an error code if a JOIN has failed and a TCP reset
@@ -165,13 +172,17 @@ static int subflow_check_req(struct request_sock *req,
165172
if (opt_mp_capable) {
166173
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
167174

175+
if (unlikely(listener->pm_listener))
176+
return subflow_reset_req_endp(req, skb);
168177
if (opt_mp_join)
169178
return 0;
170179
} else if (opt_mp_join) {
171180
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNRX);
172181

173182
if (mp_opt.backup)
174183
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNBACKUPRX);
184+
} else if (unlikely(listener->pm_listener)) {
185+
return subflow_reset_req_endp(req, skb);
175186
}
176187

177188
if (opt_mp_capable && listener->request_mptcp) {
@@ -736,8 +747,6 @@ static bool subflow_hmac_valid(const struct request_sock *req,
736747

737748
subflow_req = mptcp_subflow_rsk(req);
738749
msk = subflow_req->msk;
739-
if (!msk)
740-
return false;
741750

742751
subflow_generate_hmac(READ_ONCE(msk->remote_key),
743752
READ_ONCE(msk->local_key),
@@ -835,12 +844,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
835844

836845
} else if (subflow_req->mp_join) {
837846
mptcp_get_options(skb, &mp_opt);
838-
if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK) ||
839-
!subflow_hmac_valid(req, &mp_opt) ||
840-
!mptcp_can_accept_new_subflow(subflow_req->msk)) {
841-
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
847+
if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK))
842848
fallback = true;
843-
}
844849
}
845850

846851
create_child:
@@ -890,6 +895,13 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
890895
goto dispose_child;
891896
}
892897

898+
if (!subflow_hmac_valid(req, &mp_opt) ||
899+
!mptcp_can_accept_new_subflow(subflow_req->msk)) {
900+
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
901+
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
902+
goto dispose_child;
903+
}
904+
893905
/* move the msk reference ownership to the subflow */
894906
subflow_req->msk = NULL;
895907
ctx->conn = (struct sock *)owner;

0 commit comments

Comments
 (0)