mptcp: address lookup improvements
authorPaolo Abeni <pabeni@redhat.com>
Mon, 11 Jul 2022 19:16:30 +0000 (12:16 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 13 Jul 2022 01:37:19 +0000 (18:37 -0700)
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: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/mptcp/pm_netlink.c

index 8e1d3ae..fe8e22a 100644 (file)
@@ -413,7 +413,7 @@ static bool lookup_address_in_vec(const struct mptcp_addr_info *addrs, unsigned
        int i;
 
        for (i = 0; i < nr; i++) {
-               if (mptcp_addresses_equal(&addrs[i], addr, addr->port))
+               if (addrs[i].id == addr->id)
                        return true;
        }
 
@@ -449,7 +449,8 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm
                mptcp_for_each_subflow(msk, subflow) {
                        ssk = mptcp_subflow_tcp_sock(subflow);
                        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;
 
                        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,
        /* do not insert duplicate address, differentiate on port only
         * singled addresses
         */
+       if (!address_use_port(entry))
+               entry->addr.port = 0;
        list_for_each_entry(cur, &pernet->local_addr_list, list) {
                if (mptcp_addresses_equal(&cur->addr, &entry->addr,
-                                         address_use_port(entry) &&
-                                         address_use_port(cur))) {
+                                         cur->addr.port || entry->addr.port)) {
                        /* allow replacing the exiting endpoint only if such
                         * endpoint is an implicit one and the user-space
                         * did not provide an endpoint id
@@ -968,7 +970,10 @@ find_next:
        }
 
        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;
 
 out: