mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
mptcp: pm nl: support IPv4 mapped in v6 addresses
On one side, we can allow the creation of subflows between v4 mapped in v6 and v4 addresses. For that we look for v4mapped addresses between the local address we want to select and the remote one. On the other side, we also properly deal with received v4mapped addresses, either announced ones or set via Netlink. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/122 Suggested-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Co-developed-by: Geliang Tang <geliangtang@gmail.com> Signed-off-by: Geliang Tang <geliangtang@gmail.com> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
50a13bc394
commit
7b9b0f7e12
@ -60,15 +60,20 @@ static bool addresses_equal(const struct mptcp_addr_info *a,
|
||||
{
|
||||
bool addr_equals = false;
|
||||
|
||||
if (a->family != b->family)
|
||||
return false;
|
||||
|
||||
if (a->family == AF_INET)
|
||||
addr_equals = a->addr.s_addr == b->addr.s_addr;
|
||||
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_cmp(&a->addr6, &b->addr6);
|
||||
else
|
||||
addr_equals = !ipv6_addr_cmp(&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;
|
||||
@ -137,6 +142,7 @@ select_local_address(const struct pm_nl_pernet *pernet,
|
||||
struct mptcp_sock *msk)
|
||||
{
|
||||
struct mptcp_pm_addr_entry *entry, *ret = NULL;
|
||||
struct sock *sk = (struct sock *)msk;
|
||||
|
||||
rcu_read_lock();
|
||||
__mptcp_flush_join_list(msk);
|
||||
@ -144,11 +150,20 @@ select_local_address(const struct pm_nl_pernet *pernet,
|
||||
if (!(entry->addr.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
|
||||
continue;
|
||||
|
||||
if (entry->addr.family != sk->sk_family) {
|
||||
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
|
||||
if ((entry->addr.family == AF_INET &&
|
||||
!ipv6_addr_v4mapped(&sk->sk_v6_daddr)) ||
|
||||
(sk->sk_family == AF_INET &&
|
||||
!ipv6_addr_v4mapped(&entry->addr.addr6)))
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
/* avoid any address already in use by subflows and
|
||||
* pending join
|
||||
*/
|
||||
if (entry->addr.family == ((struct sock *)msk)->sk_family &&
|
||||
!lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) {
|
||||
if (!lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) {
|
||||
ret = entry;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user