From: Menglong Dong <[email protected]>
Replace kfree_skb() with kfree_skb_reason() in ip_rcv_core(). Three new
drop reasons are introduced:
SKB_DROP_REASON_OTHERHOST
SKB_DROP_REASON_IP_CSUM
SKB_DROP_REASON_IP_INHDR
Signed-off-by: Menglong Dong <[email protected]>
---
include/linux/skbuff.h | 3 +++
include/trace/events/skb.h | 3 +++
net/ipv4/ip_input.c | 15 +++++++++++----
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1bcd690b8ae1..f3028028b83e 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -321,6 +321,9 @@ enum skb_drop_reason {
SKB_DROP_REASON_TCP_FILTER,
SKB_DROP_REASON_UDP_CSUM,
SKB_DROP_REASON_NETFILTER_DROP,
+ SKB_DROP_REASON_OTHERHOST,
+ SKB_DROP_REASON_IP_CSUM,
+ SKB_DROP_REASON_IP_INHDR,
SKB_DROP_REASON_MAX,
};
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index beed7bb2bc0e..d1b0d9690e62 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -17,6 +17,9 @@
EM(SKB_DROP_REASON_TCP_FILTER, TCP_FILTER) \
EM(SKB_DROP_REASON_UDP_CSUM, UDP_CSUM) \
EM(SKB_DROP_REASON_NETFILTER_DROP, NETFILTER_DROP) \
+ EM(SKB_DROP_REASON_OTHERHOST, OTHERHOST) \
+ EM(SKB_DROP_REASON_IP_CSUM, IP_CSUM) \
+ EM(SKB_DROP_REASON_IP_INHDR, IP_INHDR) \
EMe(SKB_DROP_REASON_MAX, MAX)
#undef EM
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 3a025c011971..ab9bee4bbf0a 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -436,13 +436,18 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
{
const struct iphdr *iph;
+ int drop_reason;
u32 len;
+ drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
+
/* When the interface is in promisc. mode, drop all the crap
* that it receives, do not try to analyse it.
*/
- if (skb->pkt_type == PACKET_OTHERHOST)
+ if (skb->pkt_type == PACKET_OTHERHOST) {
+ drop_reason = SKB_DROP_REASON_OTHERHOST;
goto drop;
+ }
__IP_UPD_PO_STATS(net, IPSTATS_MIB_IN, skb->len);
@@ -478,7 +483,7 @@ static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
IPSTATS_MIB_NOECTPKTS + (iph->tos & INET_ECN_MASK),
max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));
- if (!pskb_may_pull(skb, iph->ihl*4))
+ if (!pskb_may_pull(skb, iph->ihl * 4))
goto inhdr_error;
iph = ip_hdr(skb);
@@ -490,7 +495,7 @@ static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
if (skb->len < len) {
__IP_INC_STATS(net, IPSTATS_MIB_INTRUNCATEDPKTS);
goto drop;
- } else if (len < (iph->ihl*4))
+ } else if (len < (iph->ihl * 4))
goto inhdr_error;
/* Our transport medium may have padded the buffer out. Now we know it
@@ -516,11 +521,13 @@ static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
return skb;
csum_error:
+ drop_reason = SKB_DROP_REASON_IP_CSUM;
__IP_INC_STATS(net, IPSTATS_MIB_CSUMERRORS);
inhdr_error:
+ drop_reason = drop_reason ?: SKB_DROP_REASON_IP_INHDR;
__IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
drop:
- kfree_skb(skb);
+ kfree_skb_reason(skb, drop_reason);
out:
return NULL;
}
--
2.34.1
On 1/24/22 6:15 AM, [email protected] wrote:
> @@ -478,7 +483,7 @@ static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
> IPSTATS_MIB_NOECTPKTS + (iph->tos & INET_ECN_MASK),
> max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));
>
> - if (!pskb_may_pull(skb, iph->ihl*4))
> + if (!pskb_may_pull(skb, iph->ihl * 4))
unrelated cleanup
> goto inhdr_error;
>
> iph = ip_hdr(skb);
> @@ -490,7 +495,7 @@ static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
> if (skb->len < len) {
> __IP_INC_STATS(net, IPSTATS_MIB_INTRUNCATEDPKTS);
> goto drop;
> - } else if (len < (iph->ihl*4))
> + } else if (len < (iph->ihl * 4))
ditto
> goto inhdr_error;
>
> /* Our transport medium may have padded the buffer out. Now we know it
On Wed, Jan 26, 2022 at 10:10 AM David Ahern <[email protected]> wrote:
>
> On 1/24/22 6:15 AM, [email protected] wrote:
> > @@ -478,7 +483,7 @@ static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
> > IPSTATS_MIB_NOECTPKTS + (iph->tos & INET_ECN_MASK),
> > max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));
> >
> > - if (!pskb_may_pull(skb, iph->ihl*4))
> > + if (!pskb_may_pull(skb, iph->ihl * 4))
>
> unrelated cleanup
>
Haha, you got me :/
> > goto inhdr_error;
> >
> > iph = ip_hdr(skb);
> > @@ -490,7 +495,7 @@ static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
> > if (skb->len < len) {
> > __IP_INC_STATS(net, IPSTATS_MIB_INTRUNCATEDPKTS);
> > goto drop;
> > - } else if (len < (iph->ihl*4))
> > + } else if (len < (iph->ihl * 4))
>
> ditto
>
> > goto inhdr_error;
> >
> > /* Our transport medium may have padded the buffer out. Now we know it
>