diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2009-02-12 05:03:38 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-15 22:43:35 -0800 |
commit | 20d4947353be60e909e6b1a79d241457edd6833f (patch) | |
tree | 939ced518fc52e57df9ee9efb0cd14b6e26a3bc4 /include/net/sock.h | |
parent | ac45f602ee3d1b6f326f68bc0c2591ceebf05ba4 (diff) | |
download | lwn-20d4947353be60e909e6b1a79d241457edd6833f.tar.gz lwn-20d4947353be60e909e6b1a79d241457edd6833f.zip |
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 { * @sk_allocation: allocation mode * @sk_sndbuf: size of send buffer in bytes * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, - * %SO_OOBINLINE settings + * %SO_OOBINLINE settings, %SO_TIMESTAMPING settings * @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets * @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO) * @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4) @@ -488,6 +488,13 @@ enum sock_flags { SOCK_RCVTSTAMPNS, /* %SO_TIMESTAMPNS setting */ SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */ SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */ + SOCK_TIMESTAMPING_TX_HARDWARE, /* %SOF_TIMESTAMPING_TX_HARDWARE */ + SOCK_TIMESTAMPING_TX_SOFTWARE, /* %SOF_TIMESTAMPING_TX_SOFTWARE */ + SOCK_TIMESTAMPING_RX_HARDWARE, /* %SOF_TIMESTAMPING_RX_HARDWARE */ + SOCK_TIMESTAMPING_RX_SOFTWARE, /* %SOF_TIMESTAMPING_RX_SOFTWARE */ + SOCK_TIMESTAMPING_SOFTWARE, /* %SOF_TIMESTAMPING_SOFTWARE */ + SOCK_TIMESTAMPING_RAW_HARDWARE, /* %SOF_TIMESTAMPING_RAW_HARDWARE */ + SOCK_TIMESTAMPING_SYS_HARDWARE, /* %SOF_TIMESTAMPING_SYS_HARDWARE */ }; static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) @@ -1346,14 +1353,45 @@ static __inline__ void sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { ktime_t kt = skb->tstamp; + struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); - if (sock_flag(sk, SOCK_RCVTSTAMP)) + /* + * generate control messages if + * - receive time stamping in software requested (SOCK_RCVTSTAMP + * or SOCK_TIMESTAMPING_RX_SOFTWARE) + * - software time stamp available and wanted + * (SOCK_TIMESTAMPING_SOFTWARE) + * - hardware time stamps available and wanted + * (SOCK_TIMESTAMPING_SYS_HARDWARE or + * SOCK_TIMESTAMPING_RAW_HARDWARE) + */ + if (sock_flag(sk, SOCK_RCVTSTAMP) || + sock_flag(sk, SOCK_TIMESTAMPING_RX_SOFTWARE) || + (kt.tv64 && sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE)) || + (hwtstamps->hwtstamp.tv64 && + sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE)) || + (hwtstamps->syststamp.tv64 && + sock_flag(sk, SOCK_TIMESTAMPING_SYS_HARDWARE))) __sock_recv_timestamp(msg, sk, skb); else sk->sk_stamp = kt; } /** + * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped + * @msg: outgoing packet + * @sk: socket sending this packet + * @shtx: filled with instructions for time stamping + * + * Currently only depends on SOCK_TIMESTAMPING* flags. Returns error code if + * parameters are invalid. + */ +extern int sock_tx_timestamp(struct msghdr *msg, + struct sock *sk, + union skb_shared_tx *shtx); + + +/** * sk_eat_skb - Release a skb if it is no longer needed * @sk: socket to eat this skb from * @skb: socket buffer to eat @@ -1421,7 +1459,7 @@ static inline struct sock *skb_steal_sock(struct sk_buff *skb) return NULL; } -extern void sock_enable_timestamp(struct sock *sk); +extern void sock_enable_timestamp(struct sock *sk, int flag); extern int sock_get_timestamp(struct sock *, struct timeval __user *); extern int sock_get_timestampns(struct sock *, struct timespec __user *); |