[PATCH mptcp-next v4 01/10] mptcp: preserve msk's sk_bound_dev_if on PM-default subflows
Geliang Tang <[email protected]> Thu, 30 Jul 2026 10:53:54 +0800
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <fc150fbcf8384d9ef0b3c650de3759399773a144.1785378180.git.tanggeliang@kylinos.cn> |
From: Geliang Tang <[email protected]> When the path manager creates a new subflow via __mptcp_subflow_connect(), it currently writes local->ifindex to ssk->sk_bound_dev_if unconditionally. The value was previously synced from the msk by mptcp_sockopt_sync_locked() -> sync_socket_options(), so the unconditional write in the connect path overwrites that inheritance. When the path manager leaves local->ifindex at 0 (no interface pinned for this subflow), the write wipes the synced value and clears any SO_BINDTODEVICE / SO_BINDTOIFINDEX binding the user set on the msk. The subflow then becomes free to route over any interface, bypassing VRF and per-interface binding restrictions the user explicitly requested on the master socket. Only override sk_bound_dev_if when the path manager actually picked an interface for this subflow; otherwise keep the value inherited from the msk. Signed-off-by: Geliang Tang <[email protected]> --- net/mptcp/subflow.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 8e386899ceb9..c39243c85f50 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -1667,7 +1667,15 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_local *local, if (addr.ss_family == AF_INET6) addrlen = sizeof(struct sockaddr_in6); #endif - ssk->sk_bound_dev_if = local->ifindex; + /* Only override the bound device if the path manager picked one. + * When local->ifindex == 0 the subflow must inherit sk_bound_dev_if + * synced from the msk via mptcp_sockopt_sync_locked() - otherwise + * SO_BINDTODEVICE / SO_BINDTOIFINDEX set on the master socket would + * be silently cleared, letting traffic route over unintended + * interfaces (bypassing VRF / interface-binding restrictions). + */ + if (local->ifindex) + ssk->sk_bound_dev_if = local->ifindex; err = kernel_bind(sf, (struct sockaddr_unsized *)&addr, addrlen); if (err) { MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNTXBINDERR); -- 2.53.0