diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2009-02-12 00:03:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-16 01:43:35 -0500 |
commit | 20d4947353be60e909e6b1a79d241457edd6833f (patch) | |
tree | 939ced518fc52e57df9ee9efb0cd14b6e26a3bc4 /include/net/sock.h | |
parent | ac45f602ee3d1b6f326f68bc0c2591ceebf05ba4 (diff) |
net: socket infrastructure for SO_TIMESTAMPING
The overlap with the old SO_TIMESTAMP[NS] options is handled so
that time stamping in software (net_enable_timestamp()) is
enabled when SO_TIMESTAMP[NS] and/or SO_TIMESTAMPING_RX_SOFTWARE
is set. It's disabled if all of these are off.
Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/sock.h')
-rw-r--r-- | include/net/sock.h | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index ded6854e3e4a..cc9d5bcb06f7 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -158,7 +158,7 @@ struct sock_common { | |||
158 | * @sk_allocation: allocation mode | 158 | * @sk_allocation: allocation mode |
159 | * @sk_sndbuf: size of send buffer in bytes | 159 | * @sk_sndbuf: size of send buffer in bytes |
160 | * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, | 160 | * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, |
161 | * %SO_OOBINLINE settings | 161 | * %SO_OOBINLINE settings, %SO_TIMESTAMPING settings |
162 | * @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets | 162 | * @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets |
163 | * @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO) | 163 | * @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO) |
164 | * @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4) | 164 | * @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4) |
@@ -488,6 +488,13 @@ enum sock_flags { | |||
488 | SOCK_RCVTSTAMPNS, /* %SO_TIMESTAMPNS setting */ | 488 | SOCK_RCVTSTAMPNS, /* %SO_TIMESTAMPNS setting */ |
489 | SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */ | 489 | SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */ |
490 | SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */ | 490 | SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */ |
491 | SOCK_TIMESTAMPING_TX_HARDWARE, /* %SOF_TIMESTAMPING_TX_HARDWARE */ | ||
492 | SOCK_TIMESTAMPING_TX_SOFTWARE, /* %SOF_TIMESTAMPING_TX_SOFTWARE */ | ||
493 | SOCK_TIMESTAMPING_RX_HARDWARE, /* %SOF_TIMESTAMPING_RX_HARDWARE */ | ||
494 | SOCK_TIMESTAMPING_RX_SOFTWARE, /* %SOF_TIMESTAMPING_RX_SOFTWARE */ | ||
495 | SOCK_TIMESTAMPING_SOFTWARE, /* %SOF_TIMESTAMPING_SOFTWARE */ | ||
496 | SOCK_TIMESTAMPING_RAW_HARDWARE, /* %SOF_TIMESTAMPING_RAW_HARDWARE */ | ||
497 | SOCK_TIMESTAMPING_SYS_HARDWARE, /* %SOF_TIMESTAMPING_SYS_HARDWARE */ | ||
491 | }; | 498 | }; |
492 | 499 | ||
493 | static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) | 500 | static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) |
@@ -1346,14 +1353,45 @@ static __inline__ void | |||
1346 | sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) | 1353 | sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) |
1347 | { | 1354 | { |
1348 | ktime_t kt = skb->tstamp; | 1355 | ktime_t kt = skb->tstamp; |
1356 | struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); | ||
1349 | 1357 | ||
1350 | if (sock_flag(sk, SOCK_RCVTSTAMP)) | 1358 | /* |
1359 | * generate control messages if | ||
1360 | * - receive time stamping in software requested (SOCK_RCVTSTAMP | ||
1361 | * or SOCK_TIMESTAMPING_RX_SOFTWARE) | ||
1362 | * - software time stamp available and wanted | ||
1363 | * (SOCK_TIMESTAMPING_SOFTWARE) | ||
1364 | * - hardware time stamps available and wanted | ||
1365 | * (SOCK_TIMESTAMPING_SYS_HARDWARE or | ||
1366 | * SOCK_TIMESTAMPING_RAW_HARDWARE) | ||
1367 | */ | ||
1368 | if (sock_flag(sk, SOCK_RCVTSTAMP) || | ||
1369 | sock_flag(sk, SOCK_TIMESTAMPING_RX_SOFTWARE) || | ||
1370 | (kt.tv64 && sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE)) || | ||
1371 | (hwtstamps->hwtstamp.tv64 && | ||
1372 | sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE)) || | ||
1373 | (hwtstamps->syststamp.tv64 && | ||
1374 | sock_flag(sk, SOCK_TIMESTAMPING_SYS_HARDWARE))) | ||
1351 | __sock_recv_timestamp(msg, sk, skb); | 1375 | __sock_recv_timestamp(msg, sk, skb); |
1352 | else | 1376 | else |
1353 | sk->sk_stamp = kt; | 1377 | sk->sk_stamp = kt; |
1354 | } | 1378 | } |
1355 | 1379 | ||
1356 | /** | 1380 | /** |
1381 | * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped | ||
1382 | * @msg: outgoing packet | ||
1383 | * @sk: socket sending this packet | ||
1384 | * @shtx: filled with instructions for time stamping | ||
1385 | * | ||
1386 | * Currently only depends on SOCK_TIMESTAMPING* flags. Returns error code if | ||
1387 | * parameters are invalid. | ||
1388 | */ | ||
1389 | extern int sock_tx_timestamp(struct msghdr *msg, | ||
1390 | struct sock *sk, | ||
1391 | union skb_shared_tx *shtx); | ||
1392 | |||
1393 | |||
1394 | /** | ||
1357 | * sk_eat_skb - Release a skb if it is no longer needed | 1395 | * sk_eat_skb - Release a skb if it is no longer needed |
1358 | * @sk: socket to eat this skb from | 1396 | * @sk: socket to eat this skb from |
1359 | * @skb: socket buffer to eat | 1397 | * @skb: socket buffer to eat |
@@ -1421,7 +1459,7 @@ static inline struct sock *skb_steal_sock(struct sk_buff *skb) | |||
1421 | return NULL; | 1459 | return NULL; |
1422 | } | 1460 | } |
1423 | 1461 | ||
1424 | extern void sock_enable_timestamp(struct sock *sk); | 1462 | extern void sock_enable_timestamp(struct sock *sk, int flag); |
1425 | extern int sock_get_timestamp(struct sock *, struct timeval __user *); | 1463 | extern int sock_get_timestamp(struct sock *, struct timeval __user *); |
1426 | extern int sock_get_timestampns(struct sock *, struct timespec __user *); | 1464 | extern int sock_get_timestampns(struct sock *, struct timespec __user *); |
1427 | 1465 | ||