Commit bedee0b5 authored by Paolo Abeni's avatar Paolo Abeni Committed by Jakub Kicinski

mptcp: address lookup improvements

When looking-up a socket address in the endpoint list, we
must prefer port-based matches over address only match.

Ensure that port-based endpoints are listed first, using
head insertion for them. Additionally be sure that only
port-based endpoints carry a non zero port number.
Reviewed-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f5360e9b
...@@ -413,7 +413,7 @@ static bool lookup_address_in_vec(const struct mptcp_addr_info *addrs, unsigned ...@@ -413,7 +413,7 @@ static bool lookup_address_in_vec(const struct mptcp_addr_info *addrs, unsigned
int i; int i;
for (i = 0; i < nr; i++) { for (i = 0; i < nr; i++) {
if (mptcp_addresses_equal(&addrs[i], addr, addr->port)) if (addrs[i].id == addr->id)
return true; return true;
} }
...@@ -449,7 +449,8 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm ...@@ -449,7 +449,8 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm
mptcp_for_each_subflow(msk, subflow) { mptcp_for_each_subflow(msk, subflow) {
ssk = mptcp_subflow_tcp_sock(subflow); ssk = mptcp_subflow_tcp_sock(subflow);
remote_address((struct sock_common *)ssk, &addrs[i]); remote_address((struct sock_common *)ssk, &addrs[i]);
if (deny_id0 && mptcp_addresses_equal(&addrs[i], &remote, false)) addrs[i].id = subflow->remote_id;
if (deny_id0 && !addrs[i].id)
continue; continue;
if (!lookup_address_in_vec(addrs, i, &addrs[i]) && if (!lookup_address_in_vec(addrs, i, &addrs[i]) &&
...@@ -919,10 +920,11 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet, ...@@ -919,10 +920,11 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
/* do not insert duplicate address, differentiate on port only /* do not insert duplicate address, differentiate on port only
* singled addresses * singled addresses
*/ */
if (!address_use_port(entry))
entry->addr.port = 0;
list_for_each_entry(cur, &pernet->local_addr_list, list) { list_for_each_entry(cur, &pernet->local_addr_list, list) {
if (mptcp_addresses_equal(&cur->addr, &entry->addr, if (mptcp_addresses_equal(&cur->addr, &entry->addr,
address_use_port(entry) && cur->addr.port || entry->addr.port)) {
address_use_port(cur))) {
/* allow replacing the exiting endpoint only if such /* allow replacing the exiting endpoint only if such
* endpoint is an implicit one and the user-space * endpoint is an implicit one and the user-space
* did not provide an endpoint id * did not provide an endpoint id
...@@ -968,7 +970,10 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet, ...@@ -968,7 +970,10 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
} }
pernet->addrs++; pernet->addrs++;
list_add_tail_rcu(&entry->list, &pernet->local_addr_list); if (!entry->addr.port)
list_add_tail_rcu(&entry->list, &pernet->local_addr_list);
else
list_add_rcu(&entry->list, &pernet->local_addr_list);
ret = entry->addr.id; ret = entry->addr.id;
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment