static unsigned int
fill_remote_addresses_fullmesh(struct mptcp_sock *msk,
struct mptcp_addr_info *local,
- struct mptcp_addr_info *addrs)
+ struct mptcp_addr_info *addrs,
+ int addrs_size)
{
u8 limit_extra_subflows = mptcp_pm_get_limit_extra_subflows(msk);
bool deny_id0 = READ_ONCE(msk->pm.remote_deny_join_id0);
msk->pm.extra_subflows++;
i++;
- if (msk->pm.extra_subflows >= limit_extra_subflows)
+ if (msk->pm.extra_subflows >= limit_extra_subflows ||
+ i == addrs_size)
break;
}
*/
static unsigned int
fill_remote_addresses_vec(struct mptcp_sock *msk, struct mptcp_addr_info *local,
- bool fullmesh, struct mptcp_addr_info *addrs)
+ bool fullmesh, struct mptcp_addr_info *addrs,
+ int addrs_size)
{
/* Non-fullmesh: fill in the single entry corresponding to the primary
* MPC subflow remote address, and return 1, corresponding to 1 entry.
return fill_remote_addr(msk, local, addrs);
/* Fullmesh endpoint: fill all possible remote addresses */
- return fill_remote_addresses_fullmesh(msk, local, addrs);
+ return fill_remote_addresses_fullmesh(msk, local, addrs, addrs_size);
}
static struct mptcp_pm_addr_entry *
else /* local_addr_used is not decr for ID 0 */
msk->pm.local_addr_used++;
- nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs);
+ nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh,
+ addrs, ARRAY_SIZE(addrs));
if (nr == 0)
continue;
fill_local_addresses_vec_fullmesh(struct mptcp_sock *msk,
struct mptcp_addr_info *remote,
struct mptcp_pm_local *locals,
+ int locals_size,
bool c_flag_case)
{
u8 limit_extra_subflows = mptcp_pm_get_limit_extra_subflows(msk);
msk->pm.extra_subflows++;
i++;
- if (msk->pm.extra_subflows >= limit_extra_subflows)
+ if (msk->pm.extra_subflows >= limit_extra_subflows ||
+ i == locals_size)
break;
}
rcu_read_unlock();
static unsigned int
fill_local_addresses_vec_c_flag(struct mptcp_sock *msk,
struct mptcp_addr_info *remote,
- struct mptcp_pm_local *locals)
+ struct mptcp_pm_local *locals,
+ int locals_size)
{
u8 limit_extra_subflows = mptcp_pm_get_limit_extra_subflows(msk);
struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
msk->pm.extra_subflows++;
i++;
- if (msk->pm.extra_subflows >= limit_extra_subflows)
+ if (msk->pm.extra_subflows >= limit_extra_subflows ||
+ i == locals_size)
break;
}
*/
static unsigned int
fill_local_addresses_vec(struct mptcp_sock *msk, struct mptcp_addr_info *remote,
- struct mptcp_pm_local *locals)
+ struct mptcp_pm_local *locals, int locals_size)
{
bool c_flag_case = remote->id && mptcp_pm_add_addr_c_flag_case(msk);
/* If there is at least one MPTCP endpoint with a fullmesh flag */
if (mptcp_pm_get_endp_fullmesh_max(msk))
return fill_local_addresses_vec_fullmesh(msk, remote, locals,
+ locals_size,
c_flag_case);
/* If there is at least one MPTCP endpoint with a laminar flag */
* limits are used -- accepting no ADD_ADDR -- and use subflow endpoints
*/
if (c_flag_case)
- return fill_local_addresses_vec_c_flag(msk, remote, locals);
+ return fill_local_addresses_vec_c_flag(msk, remote, locals,
+ locals_size);
/* No special case: fill in the single 'IPADDRANY' local address */
return fill_local_address_any(msk, remote, &locals[0]);
/* connect to the specified remote address, using whatever
* local address the routing configuration will pick.
*/
- nr = fill_local_addresses_vec(msk, &remote, locals);
+ nr = fill_local_addresses_vec(msk, &remote, locals, ARRAY_SIZE(locals));
if (nr == 0)
return;