net/mptcp/subflow.c
Source file repositories/reference/linux-study-clean/net/mptcp/subflow.c
File Facts
- System
- Linux kernel
- Corpus path
net/mptcp/subflow.c- Extension
.c- Size
- 63385 bytes
- Lines
- 2216
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/netdevice.hcrypto/sha2.hcrypto/utils.hnet/sock.hnet/inet_common.hnet/inet_hashtables.hnet/protocol.hnet/ip6_route.hnet/transp_v6.hnet/mptcp.hprotocol.hmib.htrace/events/mptcp.htrace/events/sock.h
Detected Declarations
enum mapping_statusfunction SUBFLOW_REQ_INC_STATSfunction subflow_req_destructorfunction subflow_generate_hmacfunction mptcp_can_accept_new_subflowfunction subflow_req_create_thmacfunction subflow_init_reqfunction subflow_use_different_sportfunction subflow_add_reset_reasonfunction subflow_reset_req_endpfunction subflow_check_reqfunction mptcp_subflow_init_cookie_reqfunction mptcp_get_rst_reasonfunction subflow_prep_synackfunction subflow_v4_send_synackfunction subflow_v6_send_synackfunction subflow_thmac_validfunction mptcp_subflow_resetfunction subflow_use_different_dportfunction __mptcp_sync_statefunction subflow_set_remote_keyfunction mptcp_propagate_statefunction subflow_finish_connectfunction subflow_set_local_idfunction subflow_chk_local_idfunction subflow_rebuild_headerfunction subflow_v6_rebuild_headerfunction subflow_v4_conn_requestfunction subflow_v4_req_destructorfunction subflow_v6_conn_requestfunction subflow_v6_req_destructorfunction subflow_hmac_validfunction subflow_ulp_fallbackfunction mptcp_subflow_drop_ctxfunction __mptcp_subflow_fully_establishedfunction voidfunction dbg_bad_mapfunction skb_is_fully_mappedfunction validate_mappingfunction validate_data_csumfunction get_mapping_statusfunction mptcp_subflow_discard_datafunction subflow_is_donefunction subflow_sched_work_if_closedfunction mptcp_subflow_failfunction subflow_check_data_availfunction mptcp_subflow_data_availablefunction mptcp_subflow_get_map_offset
Annotated Snippet
if (unlikely(req->syncookie)) {
mptcp_crypto_key_sha(subflow_req->local_key,
&subflow_req->token,
&subflow_req->idsn);
if (mptcp_token_exists(subflow_req->token)) {
if (retries-- > 0)
goto again;
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_TOKENFALLBACKINIT);
} else {
subflow_req->mp_capable = 1;
}
return 0;
}
err = mptcp_token_new_request(req);
if (err == 0)
subflow_req->mp_capable = 1;
else if (retries-- > 0)
goto again;
else
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_TOKENFALLBACKINIT);
} else if (opt_mp_join && listener->request_mptcp) {
subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;
subflow_req->mp_join = 1;
subflow_req->backup = mp_opt.backup;
subflow_req->remote_id = mp_opt.join_id;
subflow_req->token = mp_opt.token;
subflow_req->remote_nonce = mp_opt.nonce;
subflow_req->msk = subflow_token_join_request(req);
/* Can't fall back to TCP in this case. */
if (!subflow_req->msk) {
subflow_add_reset_reason(skb, MPTCP_RST_EMPTCP);
return -EPERM;
}
if (subflow_use_different_sport(subflow_req->msk, sk_listener)) {
pr_debug("syn inet_sport=%d %d\n",
ntohs(inet_sk(sk_listener)->inet_sport),
ntohs(inet_sk((struct sock *)subflow_req->msk)->inet_sport));
if (!mptcp_pm_announced_has_ssk(subflow_req->msk, sk_listener)) {
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MISMATCHPORTSYNRX);
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
return -EPERM;
}
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINPORTSYNRX);
}
subflow_req_create_thmac(subflow_req);
if (unlikely(req->syncookie)) {
if (!mptcp_can_accept_new_subflow(subflow_req->msk)) {
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINREJECTED);
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
return -EPERM;
}
subflow_init_req_cookie_join_save(subflow_req, skb);
}
pr_debug("token=%u, remote_nonce=%u msk=%p\n", subflow_req->token,
subflow_req->remote_nonce, subflow_req->msk);
}
return 0;
}
int mptcp_subflow_init_cookie_req(struct request_sock *req,
const struct sock *sk_listener,
struct sk_buff *skb)
{
struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk_listener);
struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
struct mptcp_options_received mp_opt;
bool opt_mp_capable, opt_mp_join;
int err;
subflow_init_req(req, sk_listener);
mptcp_get_options(skb, &mp_opt);
opt_mp_capable = !!(mp_opt.suboptions & OPTION_MPTCP_MPC_ACK);
opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK);
if (opt_mp_capable && opt_mp_join)
return -EINVAL;
if (opt_mp_capable && listener->request_mptcp) {
if (mp_opt.sndr_key == 0)
return -EINVAL;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/netdevice.h`, `crypto/sha2.h`, `crypto/utils.h`, `net/sock.h`, `net/inet_common.h`, `net/inet_hashtables.h`.
- Detected declarations: `enum mapping_status`, `function SUBFLOW_REQ_INC_STATS`, `function subflow_req_destructor`, `function subflow_generate_hmac`, `function mptcp_can_accept_new_subflow`, `function subflow_req_create_thmac`, `function subflow_init_req`, `function subflow_use_different_sport`, `function subflow_add_reset_reason`, `function subflow_reset_req_endp`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.