On 2/20/22 10:34 PM, Dongli Zhang wrote: > diff --git a/drivers/net/tun.c b/drivers/net/tun.c > index aa27268..bf7d8cd 100644 > --- a/drivers/net/tun.c > +++ b/drivers/net/tun.c > @@ -1062,13 +1062,16 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) > struct netdev_queue *queue; > struct tun_file *tfile; > int len = skb->len; > + enum skb_drop_reason drop_reason; this function is already honoring reverse xmas tree style, so this needs to be moved up. > > rcu_read_lock(); > tfile = rcu_dereference(tun->tfiles[txq]); > > /* Drop packet if interface is not attached */ > - if (!tfile) > + if (!tfile) { > + drop_reason = SKB_DROP_REASON_DEV_READY; > goto drop; > + } > > if (!rcu_dereference(tun->steering_prog)) > tun_automq_xmit(tun, skb); > @@ -1078,22 +1081,32 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) > /* Drop if the filter does not like it. > * This is a noop if the filter is disabled. > * Filter can be enabled only for the TAP devices. */ > - if (!check_filter(&tun->txflt, skb)) > + if (!check_filter(&tun->txflt, skb)) { > + drop_reason = SKB_DROP_REASON_DEV_FILTER; > goto drop; > + } > > if (tfile->socket.sk->sk_filter && > - sk_filter(tfile->socket.sk, skb)) > + sk_filter(tfile->socket.sk, skb)) { > + drop_reason = SKB_DROP_REASON_SOCKET_FILTER; > goto drop; > + } > > len = run_ebpf_filter(tun, skb, len); > - if (len == 0) > + if (len == 0) { > + drop_reason = SKB_DROP_REASON_BPF_FILTER; how does this bpf filter differ from SKB_DROP_REASON_SOCKET_FILTER? I think the reason code needs to be a little clearer on the distinction.