return NULL;
}
+static struct mptcp_pm_add_addr *
+mptcp_pm_announced_del_timer(struct mptcp_sock *msk,
+ const struct mptcp_addr_info *addr, bool check_id)
+{
+ struct sock *sk = (struct sock *)msk;
+ struct mptcp_pm_add_addr *entry;
+ bool stop_timer = false;
+
+ rcu_read_lock();
+
+ spin_lock_bh(&msk->pm.lock);
+ entry = mptcp_pm_announced_lookup(msk, addr);
+ if (entry && (!check_id || entry->addr.id == addr->id)) {
+ entry->retrans_times = ADD_ADDR_RETRANS_MAX;
+ stop_timer = true;
+ }
+ if (!check_id && entry)
+ list_del(&entry->list);
+ spin_unlock_bh(&msk->pm.lock);
+
+ /* Note: entry might have been removed by another thread.
+ * We hold rcu_read_lock() to ensure it is not freed under us.
+ */
+ if (stop_timer) {
+ if (check_id)
+ sk_stop_timer(sk, &entry->timer);
+ else
+ sk_stop_timer_sync(sk, &entry->timer);
+ }
+
+ rcu_read_unlock();
+ return entry;
+}
+
bool mptcp_pm_announced_remove(struct mptcp_sock *msk,
const struct mptcp_addr_info *addr)
{
sock_put(sk);
}
-struct mptcp_pm_add_addr *
-mptcp_pm_announced_del_timer(struct mptcp_sock *msk,
- const struct mptcp_addr_info *addr, bool check_id)
-{
- struct sock *sk = (struct sock *)msk;
- struct mptcp_pm_add_addr *entry;
- bool stop_timer = false;
-
- rcu_read_lock();
-
- spin_lock_bh(&msk->pm.lock);
- entry = mptcp_pm_announced_lookup(msk, addr);
- if (entry && (!check_id || entry->addr.id == addr->id)) {
- entry->retrans_times = ADD_ADDR_RETRANS_MAX;
- stop_timer = true;
- }
- if (!check_id && entry)
- list_del(&entry->list);
- spin_unlock_bh(&msk->pm.lock);
-
- /* Note: entry might have been removed by another thread.
- * We hold rcu_read_lock() to ensure it is not freed under us.
- */
- if (stop_timer) {
- if (check_id)
- sk_stop_timer(sk, &entry->timer);
- else
- sk_stop_timer_sync(sk, &entry->timer);
- }
-
- rcu_read_unlock();
- return entry;
-}
-
bool mptcp_pm_announced_alloc(struct mptcp_sock *msk,
const struct mptcp_addr_info *addr)
{
const struct mptcp_addr_info *addr)
{
struct mptcp_pm_data *pm = &msk->pm;
+ struct mptcp_pm_add_addr *entry;
pr_debug("msk=%p\n", msk);
- if (!READ_ONCE(pm->work_pending))
+ entry = mptcp_pm_announced_del_timer(msk, addr, true);
+
+ if (!entry || !READ_ONCE(pm->work_pending))
return;
spin_lock_bh(&pm->lock);
- if (mptcp_pm_announced_lookup(msk, addr) && READ_ONCE(pm->work_pending))
+ if (READ_ONCE(pm->work_pending))
mptcp_pm_schedule_work(msk, MPTCP_PM_SUBFLOW_ESTABLISHED);
spin_unlock_bh(&pm->lock);