Skip to content

Commit e7ed11e

Browse files
yousukseungkuba-moo
authored andcommitted
tcp: add TTL to SCM_TIMESTAMPING_OPT_STATS
This patch adds TCP_NLA_TTL to SCM_TIMESTAMPING_OPT_STATS that exports the time-to-live or hop limit of the latest incoming packet with SCM_TSTAMP_ACK. The value exported may not be from the packet that acks the sequence when incoming packets are aggregated. Exporting the time-to-live or hop limit value of incoming packets helps to estimate the hop count of the path of the flow that may change over time. Signed-off-by: Yousuk Seung <ysseung@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Neal Cardwell <ncardwell@google.com> Link: https://lore.kernel.org/r/20210120204155.552275-1-ysseung@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent a05a728 commit e7ed11e

File tree

7 files changed

+34
-14
lines changed

7 files changed

+34
-14
lines changed

include/linux/skbuff.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3859,7 +3859,7 @@ static inline bool skb_defer_rx_timestamp(struct sk_buff *skb)
38593859
void skb_complete_tx_timestamp(struct sk_buff *skb,
38603860
struct skb_shared_hwtstamps *hwtstamps);
38613861

3862-
void __skb_tstamp_tx(struct sk_buff *orig_skb,
3862+
void __skb_tstamp_tx(struct sk_buff *orig_skb, const struct sk_buff *ack_skb,
38633863
struct skb_shared_hwtstamps *hwtstamps,
38643864
struct sock *sk, int tstype);
38653865

include/linux/tcp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,8 @@ static inline u32 tcp_saved_syn_len(const struct saved_syn *saved_syn)
496496
}
497497

498498
struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk,
499-
const struct sk_buff *orig_skb);
499+
const struct sk_buff *orig_skb,
500+
const struct sk_buff *ack_skb);
500501

501502
static inline u16 tcp_mss_clamp(const struct tcp_sock *tp, u16 mss)
502503
{

include/uapi/linux/tcp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ enum {
314314
TCP_NLA_TIMEOUT_REHASH, /* Timeout-triggered rehash attempts */
315315
TCP_NLA_BYTES_NOTSENT, /* Bytes in write queue not yet sent */
316316
TCP_NLA_EDT, /* Earliest departure time (CLOCK_MONOTONIC) */
317+
TCP_NLA_TTL, /* TTL or hop limit of a packet received */
317318
};
318319

319320
/* for TCP_MD5SIG socket option */

net/core/dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4084,7 +4084,7 @@ static int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
40844084
skb_reset_mac_header(skb);
40854085

40864086
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_SCHED_TSTAMP))
4087-
__skb_tstamp_tx(skb, NULL, skb->sk, SCM_TSTAMP_SCHED);
4087+
__skb_tstamp_tx(skb, NULL, NULL, skb->sk, SCM_TSTAMP_SCHED);
40884088

40894089
/* Disable soft irqs for various locks below. Also
40904090
* stops preemption for RCU.

net/core/skbuff.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4721,6 +4721,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
47214721
EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp);
47224722

47234723
void __skb_tstamp_tx(struct sk_buff *orig_skb,
4724+
const struct sk_buff *ack_skb,
47244725
struct skb_shared_hwtstamps *hwtstamps,
47254726
struct sock *sk, int tstype)
47264727
{
@@ -4743,7 +4744,8 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
47434744
if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) &&
47444745
sk->sk_protocol == IPPROTO_TCP &&
47454746
sk->sk_type == SOCK_STREAM) {
4746-
skb = tcp_get_timestamping_opt_stats(sk, orig_skb);
4747+
skb = tcp_get_timestamping_opt_stats(sk, orig_skb,
4748+
ack_skb);
47474749
opt_stats = true;
47484750
} else
47494751
#endif
@@ -4772,7 +4774,7 @@ EXPORT_SYMBOL_GPL(__skb_tstamp_tx);
47724774
void skb_tstamp_tx(struct sk_buff *orig_skb,
47734775
struct skb_shared_hwtstamps *hwtstamps)
47744776
{
4775-
return __skb_tstamp_tx(orig_skb, hwtstamps, orig_skb->sk,
4777+
return __skb_tstamp_tx(orig_skb, NULL, hwtstamps, orig_skb->sk,
47764778
SCM_TSTAMP_SND);
47774779
}
47784780
EXPORT_SYMBOL_GPL(skb_tstamp_tx);

net/ipv4/tcp.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3767,11 +3767,24 @@ static size_t tcp_opt_stats_get_size(void)
37673767
nla_total_size(sizeof(u16)) + /* TCP_NLA_TIMEOUT_REHASH */
37683768
nla_total_size(sizeof(u32)) + /* TCP_NLA_BYTES_NOTSENT */
37693769
nla_total_size_64bit(sizeof(u64)) + /* TCP_NLA_EDT */
3770+
nla_total_size(sizeof(u8)) + /* TCP_NLA_TTL */
37703771
0;
37713772
}
37723773

3774+
/* Returns TTL or hop limit of an incoming packet from skb. */
3775+
static u8 tcp_skb_ttl_or_hop_limit(const struct sk_buff *skb)
3776+
{
3777+
if (skb->protocol == htons(ETH_P_IP))
3778+
return ip_hdr(skb)->ttl;
3779+
else if (skb->protocol == htons(ETH_P_IPV6))
3780+
return ipv6_hdr(skb)->hop_limit;
3781+
else
3782+
return 0;
3783+
}
3784+
37733785
struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk,
3774-
const struct sk_buff *orig_skb)
3786+
const struct sk_buff *orig_skb,
3787+
const struct sk_buff *ack_skb)
37753788
{
37763789
const struct tcp_sock *tp = tcp_sk(sk);
37773790
struct sk_buff *stats;
@@ -3827,6 +3840,9 @@ struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk,
38273840
max_t(int, 0, tp->write_seq - tp->snd_nxt));
38283841
nla_put_u64_64bit(stats, TCP_NLA_EDT, orig_skb->skb_mstamp_ns,
38293842
TCP_NLA_PAD);
3843+
if (ack_skb)
3844+
nla_put_u8(stats, TCP_NLA_TTL,
3845+
tcp_skb_ttl_or_hop_limit(ack_skb));
38303846

38313847
return stats;
38323848
}

net/ipv4/tcp_input.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3145,7 +3145,7 @@ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
31453145
}
31463146

31473147
static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb,
3148-
u32 prior_snd_una)
3148+
const struct sk_buff *ack_skb, u32 prior_snd_una)
31493149
{
31503150
const struct skb_shared_info *shinfo;
31513151

@@ -3157,7 +3157,7 @@ static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb,
31573157
if (!before(shinfo->tskey, prior_snd_una) &&
31583158
before(shinfo->tskey, tcp_sk(sk)->snd_una)) {
31593159
tcp_skb_tsorted_save(skb) {
3160-
__skb_tstamp_tx(skb, NULL, sk, SCM_TSTAMP_ACK);
3160+
__skb_tstamp_tx(skb, ack_skb, NULL, sk, SCM_TSTAMP_ACK);
31613161
} tcp_skb_tsorted_restore(skb);
31623162
}
31633163
}
@@ -3166,8 +3166,8 @@ static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb,
31663166
* is before the ack sequence we can discard it as it's confirmed to have
31673167
* arrived at the other end.
31683168
*/
3169-
static int tcp_clean_rtx_queue(struct sock *sk, u32 prior_fack,
3170-
u32 prior_snd_una,
3169+
static int tcp_clean_rtx_queue(struct sock *sk, const struct sk_buff *ack_skb,
3170+
u32 prior_fack, u32 prior_snd_una,
31713171
struct tcp_sacktag_state *sack, bool ece_ack)
31723172
{
31733173
const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -3256,7 +3256,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, u32 prior_fack,
32563256
if (!fully_acked)
32573257
break;
32583258

3259-
tcp_ack_tstamp(sk, skb, prior_snd_una);
3259+
tcp_ack_tstamp(sk, skb, ack_skb, prior_snd_una);
32603260

32613261
next = skb_rb_next(skb);
32623262
if (unlikely(skb == tp->retransmit_skb_hint))
@@ -3274,7 +3274,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, u32 prior_fack,
32743274
tp->snd_up = tp->snd_una;
32753275

32763276
if (skb) {
3277-
tcp_ack_tstamp(sk, skb, prior_snd_una);
3277+
tcp_ack_tstamp(sk, skb, ack_skb, prior_snd_una);
32783278
if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)
32793279
flag |= FLAG_SACK_RENEGING;
32803280
}
@@ -3809,8 +3809,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
38093809
goto no_queue;
38103810

38113811
/* See if we can take anything off of the retransmit queue. */
3812-
flag |= tcp_clean_rtx_queue(sk, prior_fack, prior_snd_una, &sack_state,
3813-
flag & FLAG_ECE);
3812+
flag |= tcp_clean_rtx_queue(sk, skb, prior_fack, prior_snd_una,
3813+
&sack_state, flag & FLAG_ECE);
38143814

38153815
tcp_rack_update_reo_wnd(sk, &rs);
38163816

0 commit comments

Comments
 (0)