Skip to content

Commit 49ca0d8

Browse files
wdebruijdavem330
authored andcommitted
net-timestamp: no-payload option
Add timestamping option SOF_TIMESTAMPING_OPT_TSONLY. For transmit timestamps, this loops timestamps on top of empty packets. Doing so reduces the pressure on SO_RCVBUF. Payload inspection and cmsg reception (aside from timestamps) are no longer possible. This works together with a follow on patch that allows administrators to only allow tx timestamping if it does not loop payload or metadata. Signed-off-by: Willem de Bruijn <[email protected]> ---- Changes (rfc -> v1) - add documentation - remove unnecessary skb->len test (thanks to Richard Cochran) Signed-off-by: David S. Miller <[email protected]>
1 parent 9766e97 commit 49ca0d8

File tree

6 files changed

+48
-12
lines changed

6 files changed

+48
-12
lines changed

Documentation/networking/timestamping.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,27 @@ SOF_TIMESTAMPING_OPT_CMSG:
162162
option IP_PKTINFO simultaneously.
163163

164164

165+
SOF_TIMESTAMPING_OPT_TSONLY:
166+
167+
Applies to transmit timestamps only. Makes the kernel return the
168+
timestamp as a cmsg alongside an empty packet, as opposed to
169+
alongside the original packet. This reduces the amount of memory
170+
charged to the socket's receive budget (SO_RCVBUF) and delivers
171+
the timestamp even if sysctl net.core.tstamp_allow_data is 0.
172+
This option disables SOF_TIMESTAMPING_OPT_CMSG.
173+
174+
175+
New applications are encouraged to pass SOF_TIMESTAMPING_OPT_ID to
176+
disambiguate timestamps and SOF_TIMESTAMPING_OPT_TSONLY to operate
177+
regardless of the setting of sysctl net.core.tstamp_allow_data.
178+
179+
An exception is when a process needs additional cmsg data, for
180+
instance SOL_IP/IP_PKTINFO to detect the egress network interface.
181+
Then pass option SOF_TIMESTAMPING_OPT_CMSG. This option depends on
182+
having access to the contents of the original packet, so cannot be
183+
combined with SOF_TIMESTAMPING_OPT_TSONLY.
184+
185+
165186
1.4 Bytestream Timestamps
166187

167188
The SO_TIMESTAMPING interface supports timestamping of bytes in a

include/uapi/linux/net_tstamp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ enum {
2424
SOF_TIMESTAMPING_TX_SCHED = (1<<8),
2525
SOF_TIMESTAMPING_TX_ACK = (1<<9),
2626
SOF_TIMESTAMPING_OPT_CMSG = (1<<10),
27+
SOF_TIMESTAMPING_OPT_TSONLY = (1<<11),
2728

28-
SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_CMSG,
29+
SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TSONLY,
2930
SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) |
3031
SOF_TIMESTAMPING_LAST
3132
};

net/core/skbuff.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3710,19 +3710,28 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
37103710
struct sock *sk, int tstype)
37113711
{
37123712
struct sk_buff *skb;
3713+
bool tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY;
37133714

37143715
if (!sk)
37153716
return;
37163717

3717-
if (hwtstamps)
3718-
*skb_hwtstamps(orig_skb) = *hwtstamps;
3718+
if (tsonly)
3719+
skb = alloc_skb(0, GFP_ATOMIC);
37193720
else
3720-
orig_skb->tstamp = ktime_get_real();
3721-
3722-
skb = skb_clone(orig_skb, GFP_ATOMIC);
3721+
skb = skb_clone(orig_skb, GFP_ATOMIC);
37233722
if (!skb)
37243723
return;
37253724

3725+
if (tsonly) {
3726+
skb_shinfo(skb)->tx_flags = skb_shinfo(orig_skb)->tx_flags;
3727+
skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey;
3728+
}
3729+
3730+
if (hwtstamps)
3731+
*skb_hwtstamps(skb) = *hwtstamps;
3732+
else
3733+
skb->tstamp = ktime_get_real();
3734+
37263735
__skb_complete_tx_timestamp(skb, sk, tstype);
37273736
}
37283737
EXPORT_SYMBOL_GPL(__skb_tstamp_tx);

net/ipv4/ip_sockglue.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
483483

484484
serr = SKB_EXT_ERR(skb);
485485

486-
if (sin) {
486+
if (sin && skb->len) {
487487
sin->sin_family = AF_INET;
488488
sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) +
489489
serr->addr_offset);
@@ -496,8 +496,9 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
496496
sin = &errhdr.offender;
497497
memset(sin, 0, sizeof(*sin));
498498

499-
if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
500-
ipv4_pktinfo_prepare_errqueue(sk, skb, serr->ee.ee_origin)) {
499+
if (skb->len &&
500+
(serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
501+
ipv4_pktinfo_prepare_errqueue(sk, skb, serr->ee.ee_origin))) {
501502
sin->sin_family = AF_INET;
502503
sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
503504
if (inet_sk(sk)->cmsg_flags)

net/ipv6/datagram.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
369369

370370
serr = SKB_EXT_ERR(skb);
371371

372-
if (sin) {
372+
if (sin && skb->len) {
373373
const unsigned char *nh = skb_network_header(skb);
374374
sin->sin6_family = AF_INET6;
375375
sin->sin6_flowinfo = 0;
@@ -394,8 +394,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
394394
memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
395395
sin = &errhdr.offender;
396396
memset(sin, 0, sizeof(*sin));
397-
398-
if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
397+
if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL && skb->len) {
399398
sin->sin6_family = AF_INET6;
400399
if (np->rxopt.all) {
401400
if (serr->ee.ee_origin != SO_EE_ORIGIN_ICMP &&

net/rxrpc/ar-error.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ void rxrpc_UDP_error_report(struct sock *sk)
4242
_leave("UDP socket errqueue empty");
4343
return;
4444
}
45+
if (!skb->len) {
46+
_leave("UDP empty message");
47+
kfree_skb(skb);
48+
return;
49+
}
4550

4651
rxrpc_new_skb(skb);
4752

0 commit comments

Comments
 (0)