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 |
