net: Get rcv tstamp if needed in nfnetlink_{log, queue}.c
authorMartin KaFai Lau <kafai@fb.com>
Wed, 2 Mar 2022 19:56:15 +0000 (11:56 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 Mar 2022 14:38:48 +0000 (14:38 +0000)
If skb has the (rcv) timestamp available, nfnetlink_{log, queue}.c
logs/outputs it to the userspace.  When the locally generated skb is
looping from egress to ingress over a virtual interface (e.g. veth,
loopback...),  skb->tstamp may have the delivery time before it is
known that will be delivered locally and received by another sk.  Like
handling the delivery time in network tapping,  use ktime_get_real() to
get the (rcv) timestamp.  The earlier added helper skb_tstamp_cond() is
used to do this.  false is passed to the second 'cond' arg such
that doing ktime_get_real() or not only depends on the
netstamp_needed_key static key.

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue.c

index ae9c0756bba595fbbe1de724c90be59a2c4eb209..d97eb280cb2e829c15f7b8ca3b1c2da7b7728b8b 100644 (file)
@@ -460,6 +460,7 @@ __build_packet_message(struct nfnl_log_net *log,
        sk_buff_data_t old_tail = inst->skb->tail;
        struct sock *sk;
        const unsigned char *hwhdrp;
+       ktime_t tstamp;
 
        nlh = nfnl_msg_put(inst->skb, 0, 0,
                           nfnl_msg_type(NFNL_SUBSYS_ULOG, NFULNL_MSG_PACKET),
@@ -588,9 +589,10 @@ __build_packet_message(struct nfnl_log_net *log,
                        goto nla_put_failure;
        }
 
-       if (hooknum <= NF_INET_FORWARD && skb->tstamp) {
+       tstamp = skb_tstamp_cond(skb, false);
+       if (hooknum <= NF_INET_FORWARD && tstamp) {
                struct nfulnl_msg_packet_timestamp ts;
-               struct timespec64 kts = ktime_to_timespec64(skb->tstamp);
+               struct timespec64 kts = ktime_to_timespec64(tstamp);
                ts.sec = cpu_to_be64(kts.tv_sec);
                ts.usec = cpu_to_be64(kts.tv_nsec / NSEC_PER_USEC);
 
index 8c15978d9258f1d338997637d4fad0961cd042c3..db9b5357f2cab9bfa3f851b12231c9520e7f5e56 100644 (file)
@@ -392,6 +392,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
        bool csum_verify;
        char *secdata = NULL;
        u32 seclen = 0;
+       ktime_t tstamp;
 
        size = nlmsg_total_size(sizeof(struct nfgenmsg))
                + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
@@ -407,7 +408,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
                + nla_total_size(sizeof(u_int32_t))     /* skbinfo */
                + nla_total_size(sizeof(u_int32_t));    /* cap_len */
 
-       if (entskb->tstamp)
+       tstamp = skb_tstamp_cond(entskb, false);
+       if (tstamp)
                size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp));
 
        size += nfqnl_get_bridge_size(entry);
@@ -582,9 +584,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
        if (nfqnl_put_bridge(entry, skb) < 0)
                goto nla_put_failure;
 
-       if (entry->state.hook <= NF_INET_FORWARD && entskb->tstamp) {
+       if (entry->state.hook <= NF_INET_FORWARD && tstamp) {
                struct nfqnl_msg_packet_timestamp ts;
-               struct timespec64 kts = ktime_to_timespec64(entskb->tstamp);
+               struct timespec64 kts = ktime_to_timespec64(tstamp);
 
                ts.sec = cpu_to_be64(kts.tv_sec);
                ts.usec = cpu_to_be64(kts.tv_nsec / NSEC_PER_USEC);