Skip to content

Commit 84dfe36

Browse files
geliangtangkuba-moo
authored andcommitted
mptcp: send out dedicated ADD_ADDR packet
When ADD_ADDR suboption includes an IPv6 address, the size is 28 octets. It will not fit when other MPTCP suboptions are included in this packet, e.g. DSS. So here we send out an ADD_ADDR dedicated packet to carry only ADD_ADDR suboption, no other MPTCP suboptions. In mptcp_pm_announce_addr, we check whether this is an IPv6 ADD_ADDR. If it is, we set the flag MPTCP_ADD_ADDR_IPV6 to true. Then we call mptcp_pm_nl_add_addr_send_ack to sent out a new pure ACK packet. In mptcp_established_options_add_addr, we check whether this is a pure ACK packet for ADD_ADDR. If it is, we drop all other MPTCP suboptions in this packet, only put ADD_ADDR suboption in it. Suggested-by: Paolo Abeni <[email protected]> Acked-by: Paolo Abeni <[email protected]> Signed-off-by: Geliang Tang <[email protected]> Signed-off-by: Mat Martineau <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent d91d322 commit 84dfe36

File tree

5 files changed

+80
-6
lines changed

5 files changed

+80
-6
lines changed

net/mptcp/options.c

+22-3
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,9 @@ static void mptcp_parse_option(const struct sk_buff *skb,
242242

243243
mp_opt->add_addr = 1;
244244
mp_opt->addr_id = *ptr++;
245-
pr_debug("ADD_ADDR: id=%d, echo=%d", mp_opt->addr_id, mp_opt->echo);
245+
pr_debug("ADD_ADDR%s: id=%d, echo=%d",
246+
(mp_opt->family == MPTCP_ADDR_IPVERSION_6) ? "6" : "",
247+
mp_opt->addr_id, mp_opt->echo);
246248
if (mp_opt->family == MPTCP_ADDR_IPVERSION_4) {
247249
memcpy((u8 *)&mp_opt->addr.s_addr, (u8 *)ptr, 4);
248250
ptr += 4;
@@ -573,17 +575,27 @@ static u64 add_addr6_generate_hmac(u64 key1, u64 key2, u8 addr_id,
573575
}
574576
#endif
575577

576-
static bool mptcp_established_options_add_addr(struct sock *sk,
578+
static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *skb,
577579
unsigned int *size,
578580
unsigned int remaining,
579581
struct mptcp_out_options *opts)
580582
{
581583
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
582584
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
585+
bool drop_other_suboptions = false;
586+
unsigned int opt_size = *size;
583587
struct mptcp_addr_info saddr;
584588
bool echo;
585589
int len;
586590

591+
if (mptcp_pm_should_add_signal_ipv6(msk) &&
592+
skb && skb_is_tcp_pure_ack(skb)) {
593+
pr_debug("drop other suboptions");
594+
opts->suboptions = 0;
595+
remaining += opt_size;
596+
drop_other_suboptions = true;
597+
}
598+
587599
if (!mptcp_pm_should_add_signal(msk) ||
588600
!(mptcp_pm_add_addr_signal(msk, remaining, &saddr, &echo)))
589601
return false;
@@ -593,6 +605,8 @@ static bool mptcp_established_options_add_addr(struct sock *sk,
593605
return false;
594606

595607
*size = len;
608+
if (drop_other_suboptions)
609+
*size -= opt_size;
596610
opts->addr_id = saddr.id;
597611
if (saddr.family == AF_INET) {
598612
opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
@@ -678,7 +692,7 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
678692

679693
*size += opt_size;
680694
remaining -= opt_size;
681-
if (mptcp_established_options_add_addr(sk, &opt_size, remaining, opts)) {
695+
if (mptcp_established_options_add_addr(sk, skb, &opt_size, remaining, opts)) {
682696
*size += opt_size;
683697
remaining -= opt_size;
684698
ret = true;
@@ -759,6 +773,11 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
759773
goto fully_established;
760774
}
761775

776+
if (mp_opt->add_addr) {
777+
WRITE_ONCE(msk->fully_established, true);
778+
return true;
779+
}
780+
762781
/* If the first established packet does not contain MP_CAPABLE + data
763782
* then fallback to TCP. Fallback scenarios requires a reset for
764783
* MP_JOIN subflows.

net/mptcp/pm.c

+14-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
2424
add_addr |= BIT(MPTCP_ADD_ADDR_SIGNAL);
2525
if (echo)
2626
add_addr |= BIT(MPTCP_ADD_ADDR_ECHO);
27+
if (addr->family == AF_INET6)
28+
add_addr |= BIT(MPTCP_ADD_ADDR_IPV6);
2729
WRITE_ONCE(msk->pm.add_addr_signal, add_addr);
2830
return 0;
2931
}
@@ -153,14 +155,24 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
153155

154156
spin_lock_bh(&pm->lock);
155157

156-
if (!READ_ONCE(pm->accept_addr))
158+
if (!READ_ONCE(pm->accept_addr)) {
157159
mptcp_pm_announce_addr(msk, addr, true);
158-
else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED))
160+
mptcp_pm_add_addr_send_ack(msk);
161+
} else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) {
159162
pm->remote = *addr;
163+
}
160164

161165
spin_unlock_bh(&pm->lock);
162166
}
163167

168+
void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk)
169+
{
170+
if (!mptcp_pm_should_add_signal_ipv6(msk))
171+
return;
172+
173+
mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_SEND_ACK);
174+
}
175+
164176
void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id)
165177
{
166178
struct mptcp_pm_data *pm = &msk->pm;

net/mptcp/pm_netlink.c

+29
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
228228
if (!mptcp_pm_should_add_signal(msk)) {
229229
pr_debug("retransmit ADD_ADDR id=%d", entry->addr.id);
230230
mptcp_pm_announce_addr(msk, &entry->addr, false);
231+
mptcp_pm_add_addr_send_ack(msk);
231232
entry->retrans_times++;
232233
}
233234

@@ -328,6 +329,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
328329
if (mptcp_pm_alloc_anno_list(msk, local)) {
329330
msk->pm.add_addr_signaled++;
330331
mptcp_pm_announce_addr(msk, &local->addr, false);
332+
mptcp_pm_nl_add_addr_send_ack(msk);
331333
}
332334
} else {
333335
/* pick failed, avoid fourther attempts later */
@@ -398,6 +400,33 @@ void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
398400
spin_lock_bh(&msk->pm.lock);
399401

400402
mptcp_pm_announce_addr(msk, &remote, true);
403+
mptcp_pm_nl_add_addr_send_ack(msk);
404+
}
405+
406+
void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk)
407+
{
408+
struct mptcp_subflow_context *subflow;
409+
410+
if (!mptcp_pm_should_add_signal_ipv6(msk))
411+
return;
412+
413+
__mptcp_flush_join_list(msk);
414+
subflow = list_first_entry_or_null(&msk->conn_list, typeof(*subflow), node);
415+
if (subflow) {
416+
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
417+
u8 add_addr;
418+
419+
spin_unlock_bh(&msk->pm.lock);
420+
pr_debug("send ack for add_addr6");
421+
lock_sock(ssk);
422+
tcp_send_ack(ssk);
423+
release_sock(ssk);
424+
spin_lock_bh(&msk->pm.lock);
425+
426+
add_addr = READ_ONCE(msk->pm.add_addr_signal);
427+
add_addr &= ~BIT(MPTCP_ADD_ADDR_IPV6);
428+
WRITE_ONCE(msk->pm.add_addr_signal, add_addr);
429+
}
401430
}
402431

403432
void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)

net/mptcp/protocol.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk)
690690
sk->sk_data_ready(sk);
691691
}
692692

693-
static void __mptcp_flush_join_list(struct mptcp_sock *msk)
693+
void __mptcp_flush_join_list(struct mptcp_sock *msk)
694694
{
695695
if (likely(list_empty(&msk->join_list)))
696696
return;
@@ -1808,6 +1808,10 @@ static void pm_work(struct mptcp_sock *msk)
18081808
pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
18091809
mptcp_pm_nl_add_addr_received(msk);
18101810
}
1811+
if (pm->status & BIT(MPTCP_PM_ADD_ADDR_SEND_ACK)) {
1812+
pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_SEND_ACK);
1813+
mptcp_pm_nl_add_addr_send_ack(msk);
1814+
}
18111815
if (pm->status & BIT(MPTCP_PM_RM_ADDR_RECEIVED)) {
18121816
pm->status &= ~BIT(MPTCP_PM_RM_ADDR_RECEIVED);
18131817
mptcp_pm_nl_rm_addr_received(msk);

net/mptcp/protocol.h

+10
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ struct mptcp_addr_info {
160160

161161
enum mptcp_pm_status {
162162
MPTCP_PM_ADD_ADDR_RECEIVED,
163+
MPTCP_PM_ADD_ADDR_SEND_ACK,
163164
MPTCP_PM_RM_ADDR_RECEIVED,
164165
MPTCP_PM_ESTABLISHED,
165166
MPTCP_PM_SUBFLOW_ESTABLISHED,
@@ -168,6 +169,7 @@ enum mptcp_pm_status {
168169
enum mptcp_add_addr_status {
169170
MPTCP_ADD_ADDR_SIGNAL,
170171
MPTCP_ADD_ADDR_ECHO,
172+
MPTCP_ADD_ADDR_IPV6,
171173
};
172174

173175
struct mptcp_pm_data {
@@ -466,6 +468,7 @@ bool mptcp_schedule_work(struct sock *sk);
466468
void mptcp_data_acked(struct sock *sk);
467469
void mptcp_subflow_eof(struct sock *sk);
468470
bool mptcp_update_rcv_data_fin(struct mptcp_sock *msk, u64 data_fin_seq, bool use_64bit);
471+
void __mptcp_flush_join_list(struct mptcp_sock *msk);
469472
static inline bool mptcp_data_fin_enabled(const struct mptcp_sock *msk)
470473
{
471474
return READ_ONCE(msk->snd_data_fin_enable) &&
@@ -506,6 +509,7 @@ void mptcp_pm_subflow_established(struct mptcp_sock *msk,
506509
void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id);
507510
void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
508511
const struct mptcp_addr_info *addr);
512+
void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk);
509513
void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id);
510514
void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
511515
struct mptcp_pm_add_entry *
@@ -528,6 +532,11 @@ static inline bool mptcp_pm_should_add_signal_echo(struct mptcp_sock *msk)
528532
return READ_ONCE(msk->pm.add_addr_signal) & BIT(MPTCP_ADD_ADDR_ECHO);
529533
}
530534

535+
static inline bool mptcp_pm_should_add_signal_ipv6(struct mptcp_sock *msk)
536+
{
537+
return READ_ONCE(msk->pm.add_addr_signal) & BIT(MPTCP_ADD_ADDR_IPV6);
538+
}
539+
531540
static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
532541
{
533542
return READ_ONCE(msk->pm.rm_addr_signal);
@@ -552,6 +561,7 @@ void mptcp_pm_nl_data_init(struct mptcp_sock *msk);
552561
void mptcp_pm_nl_fully_established(struct mptcp_sock *msk);
553562
void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk);
554563
void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk);
564+
void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk);
555565
void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk);
556566
void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, u8 rm_id);
557567
int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);

0 commit comments

Comments
 (0)