Bridge driver today has no support to forward the userspace timestamp
packets and ends up resetting the timestamp. ETF qdisc checks the
packet coming from userspace and encounters to be 0 thereby dropping
time sensitive packets. These changes will allow userspace timestamps
packets to be forwarded from the bridge to NIC drivers.
Setting the same bit (mono_delivery_time) to avoid dropping of
userspace tstamp packets in the forwarding path.
Existing functionality of mono_delivery_time remains unaltered here,
instead just extended with userspace tstamp support for bridge
forwarding path.
Signed-off-by: Abhishek Chauhan <quic_abchauha@quicinc.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://lore.kernel.org/r/20240301201348.2815102-1-quic_abchauha@quicinc.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 
  *     @decrypted: Decrypted SKB
  *     @slow_gro: state present at GRO time, slower prepare step required
  *     @mono_delivery_time: When set, skb->tstamp has the
- *             delivery_time in mono clock base (i.e. EDT).  Otherwise, the
- *             skb->tstamp has the (rcv) timestamp at ingress and
- *             delivery_time at egress.
+ *             delivery_time in mono clock base (i.e., EDT) or a clock base chosen
+ *             by SO_TXTIME. If zero, skb->tstamp has the (rcv) timestamp at
+ *             ingress.
  *     @napi_id: id of the NAPI struct this skb came from
  *     @sender_cpu: (aka @napi_id) source CPU in XPS
  *     @alloc_cpu: CPU which did the skb allocation.
 
        skb->priority = (cork->tos != -1) ? cork->priority: READ_ONCE(sk->sk_priority);
        skb->mark = cork->mark;
        skb->tstamp = cork->transmit_time;
+       skb->mono_delivery_time = !!skb->tstamp;
        /*
         * Steal rt from cork.dst to avoid a pair of atomic_inc/atomic_dec
         * on dst refcount
 
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = sockc->mark;
        skb->tstamp = sockc->transmit_time;
+       skb->mono_delivery_time = !!skb->tstamp;
        skb_dst_set(skb, &rt->dst);
        *rtp = NULL;
 
 
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = cork->base.mark;
        skb->tstamp = cork->base.transmit_time;
-
+       skb->mono_delivery_time = !!skb->tstamp;
        ip6_cork_steal_dst(skb, cork);
        IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
        if (proto == IPPROTO_ICMPV6) {
 
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = sockc->mark;
        skb->tstamp = sockc->transmit_time;
-
+       skb->mono_delivery_time = !!skb->tstamp;
        skb_put(skb, length);
        skb_reset_network_header(skb);
        iph = ipv6_hdr(skb);
 
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = READ_ONCE(sk->sk_mark);
        skb->tstamp = sockc.transmit_time;
-
+       skb->mono_delivery_time = !!skb->tstamp;
        skb_setup_tx_timestamp(skb, sockc.tsflags);
 
        if (unlikely(extra_len == 4))
        skb->priority = READ_ONCE(po->sk.sk_priority);
        skb->mark = READ_ONCE(po->sk.sk_mark);
        skb->tstamp = sockc->transmit_time;
+       skb->mono_delivery_time = !!skb->tstamp;
        skb_setup_tx_timestamp(skb, sockc->tsflags);
        skb_zcopy_set_nouarg(skb, ph.raw);
 
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = sockc.mark;
        skb->tstamp = sockc.transmit_time;
+       skb->mono_delivery_time = !!skb->tstamp;
 
        if (unlikely(extra_len == 4))
                skb->no_fcs = 1;