lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Thu,  9 May 2019 08:55:42 -0700
From:   David Ahern <dsahern@...nel.org>
To:     davem@...emloft.net
Cc:     netdev@...r.kernel.org, eric.dumazet@...il.com,
        David Ahern <dsahern@...il.com>
Subject: [PATCH RFC net-next] netlink: Add support for timestamping messages

From: David Ahern <dsahern@...il.com>

Add support for timestamping netlink messages. If a socket wants a
timestamp, it is added when the skb clone is queued to the socket.

Allow userspace to know the actual time an event happened. In a
busy system there can be a long lag between when the event happened
and when the message is read from the socket. Further, this allows
separate netlink sockets for various RTNLGRP's where the timestamp
can be used to sort the messages if needed.

Signed-off-by: David Ahern <dsahern@...il.com>
---
one question I have is whether it would be better to add the timestamp
when the skb is created so it is the same for all sockets as opposed to
setting the time per socket.

 net/netlink/af_netlink.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 216ab915dd54..5e29ebfc701e 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1343,6 +1343,8 @@ int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
 		return err;
 	}
 
+	if (sock_flag(sk, SOCK_RCVTSTAMP))
+		__net_timestamp(skb);
 	err = netlink_attachskb(sk, skb, &timeo, ssk);
 	if (err == 1)
 		goto retry;
@@ -1469,6 +1471,9 @@ static void do_one_broadcast(struct sock *sk,
 		p->skb2 = NULL;
 		goto out;
 	}
+
+	if (sock_flag(sk, SOCK_RCVTSTAMP))
+		__net_timestamp(p->skb2);
 	NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
 	if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
 		NETLINK_CB(p->skb2).nsid_is_set = true;
@@ -1848,6 +1853,47 @@ static void netlink_cmsg_listen_all_nsid(struct sock *sk, struct msghdr *msg,
 		 &NETLINK_CB(skb).nsid);
 }
 
+/* based on tcp_recv_timestamp */
+static void netlink_cmsg_timestamp(struct msghdr *msg, struct sk_buff *skb,
+				   struct sock *sk)
+{
+	int new_tstamp;
+
+	if (!skb_get_ktime(skb))
+		return;
+
+	new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
+	if (sock_flag(sk, SOCK_RCVTSTAMPNS)) {
+		if (new_tstamp) {
+			struct __kernel_timespec kts;
+
+			skb_get_new_timestampns(skb, &kts);
+			put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
+				 sizeof(kts), &kts);
+		} else {
+			struct timespec ts;
+
+			skb_get_timestampns(skb, &ts);
+			put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
+				 sizeof(ts), &ts);
+		}
+	} else {
+		if (new_tstamp) {
+			struct __kernel_sock_timeval stv;
+
+			skb_get_new_timestamp(skb, &stv);
+			put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
+				 sizeof(stv), &stv);
+		} else {
+			struct __kernel_old_timeval tv;
+
+			skb_get_timestamp(skb, &tv);
+			put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
+				 sizeof(tv), &tv);
+		}
+	}
+}
+
 static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
 {
 	struct sock *sk = sock->sk;
@@ -1996,6 +2042,8 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 		netlink_cmsg_recv_pktinfo(msg, skb);
 	if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID)
 		netlink_cmsg_listen_all_nsid(sk, msg, skb);
+	if (sock_flag(sk, SOCK_RCVTSTAMP))
+		netlink_cmsg_timestamp(msg, skb, sk);
 
 	memset(&scm, 0, sizeof(scm));
 	scm.creds = *NETLINK_CREDS(skb);
-- 
2.11.0

Powered by blists - more mailing lists