return mptcp_pm_nl_is_backup(msk, &skc_local);
 }
 
-int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
-                                        u8 *flags, int *ifindex)
-{
-       *flags = 0;
-       *ifindex = 0;
-
-       if (mptcp_pm_is_userspace(msk))
-               return mptcp_userspace_pm_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
-       return mptcp_pm_nl_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
-}
-
 int mptcp_pm_get_addr(struct sk_buff *skb, struct genl_info *info)
 {
        if (info->attrs[MPTCP_PM_ATTR_TOKEN])
 
 static bool
 select_local_address(const struct pm_nl_pernet *pernet,
                     const struct mptcp_sock *msk,
-                    struct mptcp_pm_addr_entry *new_entry)
+                    struct mptcp_pm_local *new_local)
 {
        struct mptcp_pm_addr_entry *entry;
        bool found = false;
                if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
                        continue;
 
-               *new_entry = *entry;
+               new_local->addr = entry->addr;
+               new_local->flags = entry->flags;
+               new_local->ifindex = entry->ifindex;
                found = true;
                break;
        }
 
 static bool
 select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
-                     struct mptcp_pm_addr_entry *new_entry)
+                    struct mptcp_pm_local *new_local)
 {
        struct mptcp_pm_addr_entry *entry;
        bool found = false;
                if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
                        continue;
 
-               *new_entry = *entry;
+               new_local->addr = entry->addr;
+               new_local->flags = entry->flags;
+               new_local->ifindex = entry->ifindex;
                found = true;
                break;
        }
 static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 {
        struct sock *sk = (struct sock *)msk;
-       struct mptcp_pm_addr_entry local;
        unsigned int add_addr_signal_max;
        bool signal_and_subflow = false;
        unsigned int local_addr_max;
        struct pm_nl_pernet *pernet;
+       struct mptcp_pm_local local;
        unsigned int subflows_max;
 
        pernet = pm_nl_get_pernet(sock_net(sk));
 
                spin_unlock_bh(&msk->pm.lock);
                for (i = 0; i < nr; i++)
-                       __mptcp_subflow_connect(sk, &local.addr, &addrs[i]);
+                       __mptcp_subflow_connect(sk, &local, &addrs[i]);
                spin_lock_bh(&msk->pm.lock);
        }
        mptcp_pm_nl_check_work_pending(msk);
  */
 static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
                                             struct mptcp_addr_info *remote,
-                                            struct mptcp_addr_info *addrs)
+                                            struct mptcp_pm_local *locals)
 {
        struct sock *sk = (struct sock *)msk;
        struct mptcp_pm_addr_entry *entry;
                        continue;
 
                if (msk->pm.subflows < subflows_max) {
-                       msk->pm.subflows++;
-                       addrs[i] = entry->addr;
+                       locals[i].addr = entry->addr;
+                       locals[i].flags = entry->flags;
+                       locals[i].ifindex = entry->ifindex;
 
                        /* Special case for ID0: set the correct ID */
-                       if (mptcp_addresses_equal(&entry->addr, &mpc_addr, entry->addr.port))
-                               addrs[i].id = 0;
+                       if (mptcp_addresses_equal(&locals[i].addr, &mpc_addr, locals[i].addr.port))
+                               locals[i].addr.id = 0;
 
+                       msk->pm.subflows++;
                        i++;
                }
        }
         * 'IPADDRANY' local address
         */
        if (!i) {
-               struct mptcp_addr_info local;
-
-               memset(&local, 0, sizeof(local));
-               local.family =
+               memset(&locals[i], 0, sizeof(locals[i]));
+               locals[i].addr.family =
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
                               remote->family == AF_INET6 &&
                               ipv6_addr_v4mapped(&remote->addr6) ? AF_INET :
 #endif
                               remote->family;
 
-               if (!mptcp_pm_addr_families_match(sk, &local, remote))
+               if (!mptcp_pm_addr_families_match(sk, &locals[i].addr, remote))
                        return 0;
 
                msk->pm.subflows++;
-               addrs[i++] = local;
+               i++;
        }
 
        return i;
 
 static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
 {
-       struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX];
+       struct mptcp_pm_local locals[MPTCP_PM_ADDR_MAX];
        struct sock *sk = (struct sock *)msk;
        unsigned int add_addr_accept_max;
        struct mptcp_addr_info remote;
        /* connect to the specified remote address, using whatever
         * local address the routing configuration will pick.
         */
-       nr = fill_local_addresses_vec(msk, &remote, addrs);
+       nr = fill_local_addresses_vec(msk, &remote, locals);
        if (nr == 0)
                return;
 
        spin_unlock_bh(&msk->pm.lock);
        for (i = 0; i < nr; i++)
-               if (__mptcp_subflow_connect(sk, &addrs[i], &remote) == 0)
+               if (__mptcp_subflow_connect(sk, &locals[i], &remote) == 0)
                        sf_created = true;
        spin_lock_bh(&msk->pm.lock);
 
        return ret;
 }
 
-int mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
-                                           u8 *flags, int *ifindex)
-{
-       struct mptcp_pm_addr_entry *entry;
-       struct sock *sk = (struct sock *)msk;
-       struct net *net = sock_net(sk);
-
-       /* No entries with ID 0 */
-       if (id == 0)
-               return 0;
-
-       rcu_read_lock();
-       entry = __lookup_addr_by_id(pm_nl_get_pernet(net), id);
-       if (entry) {
-               *flags = entry->flags;
-               *ifindex = entry->ifindex;
-       }
-       rcu_read_unlock();
-
-       return 0;
-}
-
 static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
                                      const struct mptcp_addr_info *addr)
 {
 
        return NULL;
 }
 
-int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
-                                                  unsigned int id,
-                                                  u8 *flags, int *ifindex)
-{
-       struct mptcp_pm_addr_entry *match;
-
-       spin_lock_bh(&msk->pm.lock);
-       match = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
-       spin_unlock_bh(&msk->pm.lock);
-       if (match) {
-               *flags = match->flags;
-               *ifindex = match->ifindex;
-       }
-
-       return 0;
-}
-
 int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
                                    struct mptcp_addr_info *skc)
 {
        struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
        struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
        struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
-       struct mptcp_pm_addr_entry local = { 0 };
+       struct mptcp_pm_addr_entry entry = { 0 };
        struct mptcp_addr_info addr_r;
+       struct mptcp_pm_local local;
        struct mptcp_sock *msk;
        int err = -EINVAL;
        struct sock *sk;
                goto create_err;
        }
 
-       err = mptcp_pm_parse_entry(laddr, info, true, &local);
+       err = mptcp_pm_parse_entry(laddr, info, true, &entry);
        if (err < 0) {
                NL_SET_ERR_MSG_ATTR(info->extack, laddr, "error parsing local addr");
                goto create_err;
        }
 
-       if (local.flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
+       if (entry.flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
                GENL_SET_ERR_MSG(info, "invalid addr flags");
                err = -EINVAL;
                goto create_err;
        }
-       local.flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;
+       entry.flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;
 
        err = mptcp_pm_parse_addr(raddr, info, &addr_r);
        if (err < 0) {
                goto create_err;
        }
 
-       if (!mptcp_pm_addr_families_match(sk, &local.addr, &addr_r)) {
+       if (!mptcp_pm_addr_families_match(sk, &entry.addr, &addr_r)) {
                GENL_SET_ERR_MSG(info, "families mismatch");
                err = -EINVAL;
                goto create_err;
        }
 
-       err = mptcp_userspace_pm_append_new_local_addr(msk, &local, false);
+       err = mptcp_userspace_pm_append_new_local_addr(msk, &entry, false);
        if (err < 0) {
                GENL_SET_ERR_MSG(info, "did not match address and id");
                goto create_err;
        }
 
-       lock_sock(sk);
-
-       err = __mptcp_subflow_connect(sk, &local.addr, &addr_r);
+       local.addr = entry.addr;
+       local.flags = entry.flags;
+       local.ifindex = entry.ifindex;
 
+       lock_sock(sk);
+       err = __mptcp_subflow_connect(sk, &local, &addr_r);
        release_sock(sk);
 
        spin_lock_bh(&msk->pm.lock);
        if (err)
-               mptcp_userspace_pm_delete_local_addr(msk, &local);
+               mptcp_userspace_pm_delete_local_addr(msk, &entry);
        else
                msk->pm.subflows++;
        spin_unlock_bh(&msk->pm.lock);
 
        struct mptcp_rm_list rm_list_rx;
 };
 
+struct mptcp_pm_local {
+       struct mptcp_addr_info  addr;
+       u8                      flags;
+       int                     ifindex;
+};
+
 struct mptcp_pm_addr_entry {
        struct list_head        list;
        struct mptcp_addr_info  addr;
 void mptcp_local_address(const struct sock_common *skc, struct mptcp_addr_info *addr);
 
 /* called with sk socket lock held */
-int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
+int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_local *local,
                            const struct mptcp_addr_info *remote);
 int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
                                struct socket **new_sock);
 struct mptcp_pm_add_entry *
 mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
                                const struct mptcp_addr_info *addr);
-int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
-                                        unsigned int id,
-                                        u8 *flags, int *ifindex);
-int mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
-                                           u8 *flags, int *ifindex);
-int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
-                                                  unsigned int id,
-                                                  u8 *flags, int *ifindex);
 int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
 int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info);
 int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
 
 #endif
 }
 
-int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
+int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_local *local,
                            const struct mptcp_addr_info *remote)
 {
        struct mptcp_sock *msk = mptcp_sk(sk);
        struct mptcp_subflow_context *subflow;
+       int local_id = local->addr.id;
        struct sockaddr_storage addr;
        int remote_id = remote->id;
-       int local_id = loc->id;
        int err = -ENOTCONN;
        struct socket *sf;
        struct sock *ssk;
        u32 remote_token;
        int addrlen;
-       int ifindex;
-       u8 flags;
 
        if (!mptcp_is_fully_established(sk))
                goto err_out;
 
-       err = mptcp_subflow_create_socket(sk, loc->family, &sf);
+       err = mptcp_subflow_create_socket(sk, local->addr.family, &sf);
        if (err)
                goto err_out;
 
                get_random_bytes(&subflow->local_nonce, sizeof(u32));
        } while (!subflow->local_nonce);
 
-       if (local_id)
+       /* if 'IPADDRANY', the ID will be set later, after the routing */
+       if (local->addr.family == AF_INET) {
+               if (!local->addr.addr.s_addr)
+                       local_id = -1;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+       } else if (sk->sk_family == AF_INET6) {
+               if (ipv6_addr_any(&local->addr.addr6))
+                       local_id = -1;
+#endif
+       }
+
+       if (local_id >= 0)
                subflow_set_local_id(subflow, local_id);
 
-       mptcp_pm_get_flags_and_ifindex_by_id(msk, local_id,
-                                            &flags, &ifindex);
        subflow->remote_key_valid = 1;
        subflow->remote_key = READ_ONCE(msk->remote_key);
        subflow->local_key = READ_ONCE(msk->local_key);
        subflow->token = msk->token;
-       mptcp_info2sockaddr(loc, &addr, ssk->sk_family);
+       mptcp_info2sockaddr(&local->addr, &addr, ssk->sk_family);
 
        addrlen = sizeof(struct sockaddr_in);
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
        if (addr.ss_family == AF_INET6)
                addrlen = sizeof(struct sockaddr_in6);
 #endif
-       ssk->sk_bound_dev_if = ifindex;
+       ssk->sk_bound_dev_if = local->ifindex;
        err = kernel_bind(sf, (struct sockaddr *)&addr, addrlen);
        if (err)
                goto failed;
        subflow->remote_token = remote_token;
        WRITE_ONCE(subflow->remote_id, remote_id);
        subflow->request_join = 1;
-       subflow->request_bkup = !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP);
+       subflow->request_bkup = !!(local->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
        subflow->subflow_id = msk->subflow_id++;
        mptcp_info2sockaddr(remote, &addr, ssk->sk_family);