On Thu, Feb 10, 2022 at 1:12 PM Jakub Kicinski <kuba@xxxxxxxxxx> wrote: > > On Thu, 10 Feb 2022 11:19:49 +0800 Menglong Dong wrote: > > I'm doing the job of using kfree_skb_reason() for the TCP layer, > > and I have some puzzles. > > > > When collecting drop reason for tcp_v4_inbound_md5_hash() in > > tcp_v4_rcv(), I come up with 2 ways: > > > > First way: pass the address of reason to tcp_v4_inbound_md5_hash() > > like this: > > > > static bool tcp_v4_inbound_md5_hash(const struct sock *sk, > > const struct sk_buff *skb, > > - int dif, int sdif) > > + int dif, int sdif, > > + enum skb_drop_reason *reason) > > > > This can work, but many functions like tcp_v4_inbound_md5_hash() > > need to do such a change. > > > > Second way: introduce a 'drop_reason' field to 'struct sk_buff'. Therefore, > > drop reason can be set by 'skb->drop_reason = SKB_DROP_REASON_XXX' > > anywhere. > > > > For TCP, there are many cases where you can't get a drop reason in > > the place where skb is freed, so I think there needs to be a way to > > deeply collect drop reasons. The second can resolve this problem > > easily, but extra fields may have performance problems. > > > > Do you have some better ideas? > > On a quick look tcp_v4_inbound_md5_hash() returns a drop / no drop > decision, so you could just change the return type to enum > skb_drop_reason. SKB_DROP_REASON_NOT_SPECIFIED is 0 is false, > so if (reason) goto drop; logic will hold up. Yeah, that's an idea. But some functions are more complex, such as tcp_rcv_state_process() and tcp_rcv_state_process()->tcp_v4_conn_request(). The return value of tcp_rcv_state_process() can't be reused, and it's hard to add a function param of type 'enum skb_drop_reason *' to tcp_v4_conn_request(). There are some nice drop reasons in tcp_v4_conn_request(), it's a pity to give up them. How about introducing a field to 'struct sock' for drop reasons? As sk is locked during the packet process in tcp_v4_do_rcv(), this seems to work. Thanks! Menglong Dong