Skip to content

Commit 00cfd77

Browse files
geliangtangdavem330
authored andcommitted
mptcp: retransmit ADD_ADDR when timeout
This patch implemented the retransmition of ADD_ADDR when no ADD_ADDR echo is received. It added a timer with the announced address. When timeout occurs, ADD_ADDR will be retransmitted. Suggested-by: Mat Martineau <[email protected]> Suggested-by: Paolo Abeni <[email protected]> Acked-by: Paolo Abeni <[email protected]> Signed-off-by: Geliang Tang <[email protected]> Reviewed-by: Mat Martineau <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 08b81d8 commit 00cfd77

File tree

3 files changed

+96
-17
lines changed

3 files changed

+96
-17
lines changed

net/mptcp/options.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,7 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb,
893893
mptcp_pm_add_addr_received(msk, &addr);
894894
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDR);
895895
} else {
896+
mptcp_pm_del_add_timer(msk, &addr);
896897
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ECHOADD);
897898
}
898899
mp_opt.add_addr = 0;

net/mptcp/pm_netlink.c

Lines changed: 92 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ struct mptcp_pm_addr_entry {
3131
struct mptcp_pm_add_entry {
3232
struct list_head list;
3333
struct mptcp_addr_info addr;
34+
struct timer_list add_timer;
35+
struct mptcp_sock *sock;
36+
u8 retrans_times;
3437
};
3538

3639
struct pm_nl_pernet {
@@ -46,6 +49,7 @@ struct pm_nl_pernet {
4649
};
4750

4851
#define MPTCP_PM_ADDR_MAX 8
52+
#define ADD_ADDR_RETRANS_MAX 3
4953

5054
static bool addresses_equal(const struct mptcp_addr_info *a,
5155
struct mptcp_addr_info *b, bool use_port)
@@ -183,23 +187,83 @@ static void check_work_pending(struct mptcp_sock *msk)
183187
WRITE_ONCE(msk->pm.work_pending, false);
184188
}
185189

186-
static bool lookup_anno_list_by_saddr(struct mptcp_sock *msk,
187-
struct mptcp_addr_info *addr)
190+
static struct mptcp_pm_add_entry *
191+
lookup_anno_list_by_saddr(struct mptcp_sock *msk,
192+
struct mptcp_addr_info *addr)
188193
{
189194
struct mptcp_pm_add_entry *entry;
190195

191196
list_for_each_entry(entry, &msk->pm.anno_list, list) {
192197
if (addresses_equal(&entry->addr, addr, false))
193-
return true;
198+
return entry;
194199
}
195200

196-
return false;
201+
return NULL;
202+
}
203+
204+
static void mptcp_pm_add_timer(struct timer_list *timer)
205+
{
206+
struct mptcp_pm_add_entry *entry = from_timer(entry, timer, add_timer);
207+
struct mptcp_sock *msk = entry->sock;
208+
struct sock *sk = (struct sock *)msk;
209+
210+
pr_debug("msk=%p", msk);
211+
212+
if (!msk)
213+
return;
214+
215+
if (inet_sk_state_load(sk) == TCP_CLOSE)
216+
return;
217+
218+
if (!entry->addr.id)
219+
return;
220+
221+
if (mptcp_pm_should_add_signal(msk)) {
222+
sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
223+
goto out;
224+
}
225+
226+
spin_lock_bh(&msk->pm.lock);
227+
228+
if (!mptcp_pm_should_add_signal(msk)) {
229+
pr_debug("retransmit ADD_ADDR id=%d", entry->addr.id);
230+
mptcp_pm_announce_addr(msk, &entry->addr, false);
231+
entry->retrans_times++;
232+
}
233+
234+
if (entry->retrans_times < ADD_ADDR_RETRANS_MAX)
235+
sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX);
236+
237+
spin_unlock_bh(&msk->pm.lock);
238+
239+
out:
240+
__sock_put(sk);
241+
}
242+
243+
struct mptcp_pm_add_entry *
244+
mptcp_pm_del_add_timer(struct mptcp_sock *msk,
245+
struct mptcp_addr_info *addr)
246+
{
247+
struct mptcp_pm_add_entry *entry;
248+
struct sock *sk = (struct sock *)msk;
249+
250+
spin_lock_bh(&msk->pm.lock);
251+
entry = lookup_anno_list_by_saddr(msk, addr);
252+
if (entry)
253+
entry->retrans_times = ADD_ADDR_RETRANS_MAX;
254+
spin_unlock_bh(&msk->pm.lock);
255+
256+
if (entry)
257+
sk_stop_timer_sync(sk, &entry->add_timer);
258+
259+
return entry;
197260
}
198261

199262
static bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
200263
struct mptcp_pm_addr_entry *entry)
201264
{
202265
struct mptcp_pm_add_entry *add_entry = NULL;
266+
struct sock *sk = (struct sock *)msk;
203267

204268
if (lookup_anno_list_by_saddr(msk, &entry->addr))
205269
return false;
@@ -210,21 +274,32 @@ static bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
210274

211275
list_add(&add_entry->list, &msk->pm.anno_list);
212276

277+
add_entry->addr = entry->addr;
278+
add_entry->sock = msk;
279+
add_entry->retrans_times = 0;
280+
281+
timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
282+
sk_reset_timer(sk, &add_entry->add_timer, jiffies + TCP_RTO_MAX);
283+
213284
return true;
214285
}
215286

216287
void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
217288
{
218289
struct mptcp_pm_add_entry *entry, *tmp;
290+
struct sock *sk = (struct sock *)msk;
291+
LIST_HEAD(free_list);
219292

220293
pr_debug("msk=%p", msk);
221294

222295
spin_lock_bh(&msk->pm.lock);
223-
list_for_each_entry_safe(entry, tmp, &msk->pm.anno_list, list) {
224-
list_del(&entry->list);
296+
list_splice_init(&msk->pm.anno_list, &free_list);
297+
spin_unlock_bh(&msk->pm.lock);
298+
299+
list_for_each_entry_safe(entry, tmp, &free_list, list) {
300+
sk_stop_timer_sync(sk, &entry->add_timer);
225301
kfree(entry);
226302
}
227-
spin_unlock_bh(&msk->pm.lock);
228303
}
229304

230305
static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
@@ -659,14 +734,13 @@ __lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
659734
static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
660735
struct mptcp_addr_info *addr)
661736
{
662-
struct mptcp_pm_add_entry *entry, *tmp;
737+
struct mptcp_pm_add_entry *entry;
663738

664-
list_for_each_entry_safe(entry, tmp, &msk->pm.anno_list, list) {
665-
if (addresses_equal(&entry->addr, addr, false)) {
666-
list_del(&entry->list);
667-
kfree(entry);
668-
return true;
669-
}
739+
entry = mptcp_pm_del_add_timer(msk, addr);
740+
if (entry) {
741+
list_del(&entry->list);
742+
kfree(entry);
743+
return true;
670744
}
671745

672746
return false;
@@ -678,11 +752,12 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
678752
{
679753
bool ret;
680754

681-
spin_lock_bh(&msk->pm.lock);
682755
ret = remove_anno_list_by_saddr(msk, addr);
683-
if (ret || force)
756+
if (ret || force) {
757+
spin_lock_bh(&msk->pm.lock);
684758
mptcp_pm_remove_addr(msk, addr->id);
685-
spin_unlock_bh(&msk->pm.lock);
759+
spin_unlock_bh(&msk->pm.lock);
760+
}
686761
return ret;
687762
}
688763

net/mptcp/protocol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,9 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
444444
const struct mptcp_addr_info *addr);
445445
void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id);
446446
void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
447+
struct mptcp_pm_add_entry *
448+
mptcp_pm_del_add_timer(struct mptcp_sock *msk,
449+
struct mptcp_addr_info *addr);
447450

448451
int mptcp_pm_announce_addr(struct mptcp_sock *msk,
449452
const struct mptcp_addr_info *addr,

0 commit comments

Comments
 (0)