static bool mptcp_established_options_add_addr(struct sock *sk,
struct sk_buff *skb, int *size,
unsigned int remaining,
+ bool has_ts,
struct mptcp_out_options *opts)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
struct mptcp_addr_info addr;
+ bool drop_ts = has_ts;
bool echo;
/* add addr will strip the existing options, be sure to avoid breaking
if (!mptcp_pm_should_add_signal(msk) ||
(opts->suboptions & (OPTION_MPTCP_MPJ_ACK | OPTION_MPTCP_MPC_ACK)) ||
!skb || !skb_is_tcp_pure_ack(skb) ||
- !mptcp_pm_add_addr_signal(msk, size, remaining, &addr, &echo))
+ !mptcp_pm_add_addr_signal(msk, size, remaining, &addr, &echo,
+ &drop_ts))
return false;
pr_debug("drop other suboptions\n");
opts->suboptions = OPTION_MPTCP_ADD_ADDR;
+ opts->drop_ts = drop_ts;
opts->addr = addr;
if (!echo) {
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDRTX);
total_size += opt_size;
remaining -= opt_size;
- if (mptcp_established_options_add_addr(sk, skb, &opt_size, remaining, opts)) {
+ if (mptcp_established_options_add_addr(sk, skb, &opt_size, remaining,
+ has_ts, opts)) {
total_size += opt_size;
remaining -= opt_size;
ret = true;
}
bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, int *size, int remaining,
- struct mptcp_addr_info *addr, bool *echo)
+ struct mptcp_addr_info *addr, bool *echo,
+ bool *drop_ts)
{
bool skip_add_addr = false;
bool ret = false;
if (len > remaining) {
struct net *net = sock_net((struct sock *)msk);
+ if (*drop_ts && mptcp_add_addr_v6_port_drop_ts(net)) {
+ /* OK without TCP Timestamps? */
+ len -= TCPOLEN_TSTAMP_ALIGNED;
+ if (len <= remaining)
+ goto enough_space;
+ }
+
if (*echo) {
MPTCP_INC_STATS(net, MPTCP_MIB_ECHOADDTXDROP);
} else {
goto drop_signal_mark;
}
+ *drop_ts = false;
+
+enough_space:
ret = true;
*size = len;
}
bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, int *size, int remaining,
- struct mptcp_addr_info *addr, bool *echo);
+ struct mptcp_addr_info *addr, bool *echo,
+ bool *drop_ts);
bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
struct mptcp_rm_list *rm_list, int *len);
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);