diff options
-rw-r--r-- | include/linux/skbuff.h | 1 | ||||
-rw-r--r-- | include/net/sock.h | 2 | ||||
-rw-r--r-- | include/uapi/linux/net_tstamp.h | 8 | ||||
-rw-r--r-- | net/core/skbuff.c | 2 | ||||
-rw-r--r-- | net/core/sock.c | 3 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 6 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 9 |
7 files changed, 27 insertions, 4 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 477f0f60db45..0e35b3af7317 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -278,6 +278,7 @@ struct skb_shared_info { | |||
278 | unsigned short gso_type; | 278 | unsigned short gso_type; |
279 | struct sk_buff *frag_list; | 279 | struct sk_buff *frag_list; |
280 | struct skb_shared_hwtstamps hwtstamps; | 280 | struct skb_shared_hwtstamps hwtstamps; |
281 | u32 tskey; | ||
281 | __be32 ip6_frag_id; | 282 | __be32 ip6_frag_id; |
282 | 283 | ||
283 | /* | 284 | /* |
diff --git a/include/net/sock.h b/include/net/sock.h index a21129716aae..52fe0bc5598a 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -280,6 +280,7 @@ struct cg_proto; | |||
280 | * @sk_timer: sock cleanup timer | 280 | * @sk_timer: sock cleanup timer |
281 | * @sk_stamp: time stamp of last packet received | 281 | * @sk_stamp: time stamp of last packet received |
282 | * @sk_tsflags: SO_TIMESTAMPING socket options | 282 | * @sk_tsflags: SO_TIMESTAMPING socket options |
283 | * @sk_tskey: counter to disambiguate concurrent tstamp requests | ||
283 | * @sk_socket: Identd and reporting IO signals | 284 | * @sk_socket: Identd and reporting IO signals |
284 | * @sk_user_data: RPC layer private data | 285 | * @sk_user_data: RPC layer private data |
285 | * @sk_frag: cached page frag | 286 | * @sk_frag: cached page frag |
@@ -414,6 +415,7 @@ struct sock { | |||
414 | struct timer_list sk_timer; | 415 | struct timer_list sk_timer; |
415 | ktime_t sk_stamp; | 416 | ktime_t sk_stamp; |
416 | u16 sk_tsflags; | 417 | u16 sk_tsflags; |
418 | u32 sk_tskey; | ||
417 | struct socket *sk_socket; | 419 | struct socket *sk_socket; |
418 | void *sk_user_data; | 420 | void *sk_user_data; |
419 | struct page_frag sk_frag; | 421 | struct page_frag sk_frag; |
diff --git a/include/uapi/linux/net_tstamp.h b/include/uapi/linux/net_tstamp.h index f53879c0f590..1e861d2e1a31 100644 --- a/include/uapi/linux/net_tstamp.h +++ b/include/uapi/linux/net_tstamp.h | |||
@@ -20,9 +20,11 @@ enum { | |||
20 | SOF_TIMESTAMPING_SOFTWARE = (1<<4), | 20 | SOF_TIMESTAMPING_SOFTWARE = (1<<4), |
21 | SOF_TIMESTAMPING_SYS_HARDWARE = (1<<5), | 21 | SOF_TIMESTAMPING_SYS_HARDWARE = (1<<5), |
22 | SOF_TIMESTAMPING_RAW_HARDWARE = (1<<6), | 22 | SOF_TIMESTAMPING_RAW_HARDWARE = (1<<6), |
23 | SOF_TIMESTAMPING_MASK = | 23 | SOF_TIMESTAMPING_OPT_ID = (1<<7), |
24 | (SOF_TIMESTAMPING_RAW_HARDWARE - 1) | | 24 | |
25 | SOF_TIMESTAMPING_RAW_HARDWARE | 25 | SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_ID, |
26 | SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | | ||
27 | SOF_TIMESTAMPING_LAST | ||
26 | }; | 28 | }; |
27 | 29 | ||
28 | /** | 30 | /** |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c9f68802e992..0df4f1d14c5a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3522,6 +3522,8 @@ void skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3522 | serr->ee.ee_errno = ENOMSG; | 3522 | serr->ee.ee_errno = ENOMSG; |
3523 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; | 3523 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; |
3524 | serr->ee.ee_info = SCM_TSTAMP_SND; | 3524 | serr->ee.ee_info = SCM_TSTAMP_SND; |
3525 | if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) | ||
3526 | serr->ee.ee_data = skb_shinfo(skb)->tskey; | ||
3525 | 3527 | ||
3526 | err = sock_queue_err_skb(sk, skb); | 3528 | err = sock_queue_err_skb(sk, skb); |
3527 | 3529 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 47c9377e14b9..1e0f1c63ad6b 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -848,6 +848,9 @@ set_rcvbuf: | |||
848 | ret = -EINVAL; | 848 | ret = -EINVAL; |
849 | break; | 849 | break; |
850 | } | 850 | } |
851 | if (val & SOF_TIMESTAMPING_OPT_ID && | ||
852 | !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) | ||
853 | sk->sk_tskey = 0; | ||
851 | sk->sk_tsflags = val; | 854 | sk->sk_tsflags = val; |
852 | if (val & SOF_TIMESTAMPING_RX_SOFTWARE) | 855 | if (val & SOF_TIMESTAMPING_RX_SOFTWARE) |
853 | sock_enable_timestamp(sk, | 856 | sock_enable_timestamp(sk, |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index b16556836d66..215af2b155cb 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -855,11 +855,15 @@ static int __ip_append_data(struct sock *sk, | |||
855 | unsigned int maxfraglen, fragheaderlen, maxnonfragsize; | 855 | unsigned int maxfraglen, fragheaderlen, maxnonfragsize; |
856 | int csummode = CHECKSUM_NONE; | 856 | int csummode = CHECKSUM_NONE; |
857 | struct rtable *rt = (struct rtable *)cork->dst; | 857 | struct rtable *rt = (struct rtable *)cork->dst; |
858 | u32 tskey = 0; | ||
858 | 859 | ||
859 | skb = skb_peek_tail(queue); | 860 | skb = skb_peek_tail(queue); |
860 | 861 | ||
861 | exthdrlen = !skb ? rt->dst.header_len : 0; | 862 | exthdrlen = !skb ? rt->dst.header_len : 0; |
862 | mtu = cork->fragsize; | 863 | mtu = cork->fragsize; |
864 | if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && | ||
865 | sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) | ||
866 | tskey = sk->sk_tskey++; | ||
863 | 867 | ||
864 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); | 868 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); |
865 | 869 | ||
@@ -976,6 +980,8 @@ alloc_new_skb: | |||
976 | /* only the initial fragment is time stamped */ | 980 | /* only the initial fragment is time stamped */ |
977 | skb_shinfo(skb)->tx_flags = cork->tx_flags; | 981 | skb_shinfo(skb)->tx_flags = cork->tx_flags; |
978 | cork->tx_flags = 0; | 982 | cork->tx_flags = 0; |
983 | skb_shinfo(skb)->tskey = tskey; | ||
984 | tskey = 0; | ||
979 | 985 | ||
980 | /* | 986 | /* |
981 | * Find where to start putting bytes. | 987 | * Find where to start putting bytes. |
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 |