aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
authorWillem de Bruijn <willemb@google.com>2014-08-04 22:11:47 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-05 19:35:54 -0400
commit09c2d251b70723650ba47e83571ff49281320f7c (patch)
treeb40d8ab4ed6533a357b885ca6184ab7e86537c22 /net/ipv6/ip6_output.c
parentb9f40e21ef4298650ab33e35740fa85bd57706d5 (diff)
net-timestamp: add key to disambiguate concurrent datagrams
Datagrams timestamped on transmission can coexist in the kernel stack and be reordered in packet scheduling. When reading looped datagrams from the socket error queue it is not always possible to unique correlate looped data with original send() call (for application level retransmits). Even if possible, it may be expensive and complex, requiring packet inspection. Introduce a data-independent ID mechanism to associate timestamps with send calls. Pass an ID alongside the timestamp in field ee_data of sock_extended_err. The ID is a simple 32 bit unsigned int that is associated with the socket and incremented on each send() call for which software tx timestamp generation is enabled. The feature is enabled only if SOF_TIMESTAMPING_OPT_ID is set, to avoid changing ee_data for existing applications that expect it 0. The counter is reset each time the flag is reenabled. Reenabling does not change the ID of already submitted data. It is possible to receive out of order IDs if the timestamp stream is not quiesced first. Signed-off-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index f5dafe609f8b..315a55d66079 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1157,6 +1157,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1157 int err; 1157 int err;
1158 int offset = 0; 1158 int offset = 0;
1159 __u8 tx_flags = 0; 1159 __u8 tx_flags = 0;
1160 u32 tskey = 0;
1160 1161
1161 if (flags&MSG_PROBE) 1162 if (flags&MSG_PROBE)
1162 return 0; 1163 return 0;
@@ -1272,8 +1273,12 @@ emsgsize:
1272 } 1273 }
1273 } 1274 }
1274 1275
1275 if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW) 1276 if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW) {
1276 sock_tx_timestamp(sk, &tx_flags); 1277 sock_tx_timestamp(sk, &tx_flags);
1278 if (tx_flags & SKBTX_ANY_SW_TSTAMP &&
1279 sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
1280 tskey = sk->sk_tskey++;
1281 }
1277 1282
1278 /* 1283 /*
1279 * Let's try using as much space as possible. 1284 * Let's try using as much space as possible.
@@ -1397,6 +1402,8 @@ alloc_new_skb:
1397 /* Only the initial fragment is time stamped */ 1402 /* Only the initial fragment is time stamped */
1398 skb_shinfo(skb)->tx_flags = tx_flags; 1403 skb_shinfo(skb)->tx_flags = tx_flags;
1399 tx_flags = 0; 1404 tx_flags = 0;
1405 skb_shinfo(skb)->tskey = tskey;
1406 tskey = 0;
1400 1407
1401 /* 1408 /*
1402 * Find where to start putting bytes 1409 * Find where to start putting bytes