net/mptcp/pm.c
Source file repositories/reference/linux-study-clean/net/mptcp/pm.c
File Facts
- System
- Linux kernel
- Corpus path
net/mptcp/pm.c- Extension
.c- Size
- 32098 bytes
- Lines
- 1263
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: implementation source
- Status
- source 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.
- 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/rculist.hlinux/spinlock.hprotocol.hmib.h
Detected Declarations
struct mptcp_pm_add_addrfunction mptcp_pm_addr_families_matchfunction mptcp_addresses_equalfunction mptcp_local_addressfunction mptcp_remote_addressfunction mptcp_pm_is_init_remote_addrfunction mptcp_pm_has_subflow_saddrfunction mptcp_for_each_subflowfunction mptcp_pm_announced_lookupfunction list_for_each_entryfunction mptcp_pm_announced_del_timerfunction rcu_read_lockfunction mptcp_pm_announced_removefunction mptcp_pm_announced_has_sskfunction __mptcp_pm_send_ackfunction mptcp_pm_send_ackfunction subflow_in_rm_listfunction mptcp_pm_addr_send_ack_avoid_listfunction mptcp_for_each_subflowfunction subflow_in_rm_listfunction mptcp_pm_addr_send_ackfunction mptcp_pm_mp_prio_send_ackfunction mptcp_for_each_subflowfunction mptcp_adjust_add_addr_timeoutfunction mptcp_for_each_subflowfunction mptcp_pm_add_addr_timerfunction mptcp_pm_announced_allocfunction mptcp_pm_free_announced_listfunction list_for_each_entry_safefunction mptcp_pm_announce_addrfunction mptcp_pm_remove_addrfunction mptcp_pm_new_connectionfunction mptcp_pm_allow_new_subflowfunction mptcp_pm_schedule_workfunction mptcp_pm_fully_establishedfunction mptcp_pm_connection_closedfunction mptcp_pm_subflow_establishedfunction mptcp_pm_subflow_check_nextfunction mptcp_pm_add_addr_receivedfunction mptcp_pm_add_addr_echoedfunction mptcp_pm_add_addr_send_ackfunction mptcp_pm_rm_addr_or_subflowfunction mptcp_for_each_subflow_safefunction mptcp_pm_rm_addr_recvfunction mptcp_pm_rm_subflowfunction mptcp_pm_rm_addr_receivedfunction mptcp_pm_mp_prio_receivedfunction mptcp_pm_mp_fail_received
Annotated Snippet
struct mptcp_pm_add_addr {
struct list_head list;
struct mptcp_addr_info addr;
u8 retrans_times;
bool timer_done;
struct timer_list timer;
struct mptcp_sock *sock;
struct rcu_head rcu;
};
static DEFINE_SPINLOCK(mptcp_pm_list_lock);
static LIST_HEAD(mptcp_pm_list);
/* path manager helpers */
/* if sk is ipv4 or ipv6_only allows only same-family local and remote addresses,
* otherwise allow any matching local/remote pair
*/
bool mptcp_pm_addr_families_match(const struct sock *sk,
const struct mptcp_addr_info *loc,
const struct mptcp_addr_info *rem)
{
bool mptcp_is_v4 = sk->sk_family == AF_INET;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
bool loc_is_v4 = loc->family == AF_INET || ipv6_addr_v4mapped(&loc->addr6);
bool rem_is_v4 = rem->family == AF_INET || ipv6_addr_v4mapped(&rem->addr6);
if (mptcp_is_v4)
return loc_is_v4 && rem_is_v4;
if (ipv6_only_sock(sk))
return !loc_is_v4 && !rem_is_v4;
return loc_is_v4 == rem_is_v4;
#else
return mptcp_is_v4 && loc->family == AF_INET && rem->family == AF_INET;
#endif
}
bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
const struct mptcp_addr_info *b, bool use_port)
{
bool addr_equals = false;
if (a->family == b->family) {
if (a->family == AF_INET)
addr_equals = a->addr.s_addr == b->addr.s_addr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
else
addr_equals = ipv6_addr_equal(&a->addr6, &b->addr6);
} else if (a->family == AF_INET) {
if (ipv6_addr_v4mapped(&b->addr6))
addr_equals = a->addr.s_addr == b->addr6.s6_addr32[3];
} else if (b->family == AF_INET) {
if (ipv6_addr_v4mapped(&a->addr6))
addr_equals = a->addr6.s6_addr32[3] == b->addr.s_addr;
#endif
}
if (!addr_equals)
return false;
if (!use_port)
return true;
return a->port == b->port;
}
void mptcp_local_address(const struct sock_common *skc,
struct mptcp_addr_info *addr)
{
addr->family = skc->skc_family;
addr->port = htons(skc->skc_num);
if (addr->family == AF_INET)
addr->addr.s_addr = skc->skc_rcv_saddr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
else if (addr->family == AF_INET6)
addr->addr6 = skc->skc_v6_rcv_saddr;
#endif
}
void mptcp_remote_address(const struct sock_common *skc,
struct mptcp_addr_info *addr)
{
addr->family = skc->skc_family;
addr->port = skc->skc_dport;
if (addr->family == AF_INET)
addr->addr.s_addr = skc->skc_daddr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
else if (addr->family == AF_INET6)
Annotation
- Immediate include surface: `linux/rculist.h`, `linux/spinlock.h`, `protocol.h`, `mib.h`.
- Detected declarations: `struct mptcp_pm_add_addr`, `function mptcp_pm_addr_families_match`, `function mptcp_addresses_equal`, `function mptcp_local_address`, `function mptcp_remote_address`, `function mptcp_pm_is_init_remote_addr`, `function mptcp_pm_has_subflow_saddr`, `function mptcp_for_each_subflow`, `function mptcp_pm_announced_lookup`, `function list_for_each_entry`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: source 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.