diff options
author | Anders Berggren <anders@halon.se> | 2011-02-28 15:32:11 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-28 15:32:11 -0500 |
commit | a693e69897e7811e2790295f38a0ce3a92c4b45c (patch) | |
tree | 2c3cd9d7288821a7b71dc7f4481462150f41de63 /net | |
parent | eaaa3a7c4da2bdc48e536bb750860253150cb931 (diff) |
net: TX timestamps for IPv6 UDP packets
Enabling TX timestamps (SO_TIMESTAMPING) for IPv6 UDP packets, in
the same fashion as for IPv4. Necessary in order for NICs such as
Intel 82580 to timestamp IPv6 packets.
Signed-off-by: Anders Berggren <anders@halon.se>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/ip6_output.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 25a2647f9942..065b3f7614fb 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1118,6 +1118,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1118 | int err; | 1118 | int err; |
1119 | int offset = 0; | 1119 | int offset = 0; |
1120 | int csummode = CHECKSUM_NONE; | 1120 | int csummode = CHECKSUM_NONE; |
1121 | __u8 tx_flags = 0; | ||
1121 | 1122 | ||
1122 | if (flags&MSG_PROBE) | 1123 | if (flags&MSG_PROBE) |
1123 | return 0; | 1124 | return 0; |
@@ -1202,6 +1203,13 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1202 | } | 1203 | } |
1203 | } | 1204 | } |
1204 | 1205 | ||
1206 | /* For UDP, check if TX timestamp is enabled */ | ||
1207 | if (sk->sk_type == SOCK_DGRAM) { | ||
1208 | err = sock_tx_timestamp(sk, &tx_flags); | ||
1209 | if (err) | ||
1210 | goto error; | ||
1211 | } | ||
1212 | |||
1205 | /* | 1213 | /* |
1206 | * Let's try using as much space as possible. | 1214 | * Let's try using as much space as possible. |
1207 | * Use MTU if total length of the message fits into the MTU. | 1215 | * Use MTU if total length of the message fits into the MTU. |
@@ -1306,6 +1314,12 @@ alloc_new_skb: | |||
1306 | sk->sk_allocation); | 1314 | sk->sk_allocation); |
1307 | if (unlikely(skb == NULL)) | 1315 | if (unlikely(skb == NULL)) |
1308 | err = -ENOBUFS; | 1316 | err = -ENOBUFS; |
1317 | else { | ||
1318 | /* Only the initial fragment | ||
1319 | * is time stamped. | ||
1320 | */ | ||
1321 | tx_flags = 0; | ||
1322 | } | ||
1309 | } | 1323 | } |
1310 | if (skb == NULL) | 1324 | if (skb == NULL) |
1311 | goto error; | 1325 | goto error; |
@@ -1317,6 +1331,9 @@ alloc_new_skb: | |||
1317 | /* reserve for fragmentation */ | 1331 | /* reserve for fragmentation */ |
1318 | skb_reserve(skb, hh_len+sizeof(struct frag_hdr)); | 1332 | skb_reserve(skb, hh_len+sizeof(struct frag_hdr)); |
1319 | 1333 | ||
1334 | if (sk->sk_type == SOCK_DGRAM) | ||
1335 | skb_shinfo(skb)->tx_flags = tx_flags; | ||
1336 | |||
1320 | /* | 1337 | /* |
1321 | * Find where to start putting bytes | 1338 | * Find where to start putting bytes |
1322 | */ | 1339 | */ |