ipv6: icmp6: add drop reason support to icmpv6_notify()
authorEric Dumazet <edumazet@google.com>
Fri, 10 Feb 2023 18:47:07 +0000 (18:47 +0000)
committerJakub Kicinski <kuba@kernel.org>
Tue, 14 Feb 2023 03:55:32 +0000 (19:55 -0800)
Accurately reports what happened in icmpv6_notify() when handling
a packet.

This makes use of the new IPV6_BAD_EXTHDR drop reason.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/ipv6.h
net/ipv6/icmp.c

index 03f3af02a9a645b49c1de1272caf5d8d8277d0c1..7332296eca44b84dca1bbecb545f6824a0e8ed3d 100644 (file)
@@ -436,7 +436,8 @@ static inline void fl6_sock_release(struct ip6_flowlabel *fl)
                atomic_dec(&fl->users);
 }
 
-void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info);
+enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type,
+                                  u8 code, __be32 info);
 
 void icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
                                struct icmp6hdr *thdr, int len);
index c9346515e24dabce3aae642bfca4fb4eae4c3533..40bb5dedac09e4e4f3bd15944538c4324d028674 100644 (file)
@@ -813,16 +813,19 @@ out_bh_enable:
        local_bh_enable();
 }
 
-void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
+enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type,
+                                  u8 code, __be32 info)
 {
        struct inet6_skb_parm *opt = IP6CB(skb);
+       struct net *net = dev_net(skb->dev);
        const struct inet6_protocol *ipprot;
+       enum skb_drop_reason reason;
        int inner_offset;
        __be16 frag_off;
        u8 nexthdr;
-       struct net *net = dev_net(skb->dev);
 
-       if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+       reason = pskb_may_pull_reason(skb, sizeof(struct ipv6hdr));
+       if (reason != SKB_NOT_DROPPED_YET)
                goto out;
 
        seg6_icmp_srh(skb, opt);
@@ -832,14 +835,17 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
                /* now skip over extension headers */
                inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
                                                &nexthdr, &frag_off);
-               if (inner_offset < 0)
+               if (inner_offset < 0) {
+                       SKB_DR_SET(reason, IPV6_BAD_EXTHDR);
                        goto out;
+               }
        } else {
                inner_offset = sizeof(struct ipv6hdr);
        }
 
        /* Checkin header including 8 bytes of inner protocol header. */
-       if (!pskb_may_pull(skb, inner_offset+8))
+       reason = pskb_may_pull_reason(skb, inner_offset + 8);
+       if (reason != SKB_NOT_DROPPED_YET)
                goto out;
 
        /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
@@ -854,10 +860,11 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
                ipprot->err_handler(skb, opt, type, code, inner_offset, info);
 
        raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
-       return;
+       return SKB_CONSUMED;
 
 out:
        __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
+       return reason;
 }
 
 /*
@@ -953,7 +960,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
        case ICMPV6_DEST_UNREACH:
        case ICMPV6_TIME_EXCEED:
        case ICMPV6_PARAMPROB:
-               icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
+               reason = icmpv6_notify(skb, type, hdr->icmp6_code,
+                                      hdr->icmp6_mtu);
                break;
 
        case NDISC_ROUTER_SOLICITATION:
@@ -995,7 +1003,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
                 * must pass to upper level
                 */
 
-               icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
+               reason = icmpv6_notify(skb, type, hdr->icmp6_code,
+                                      hdr->icmp6_mtu);
        }
 
        /* until the v6 path can be better sorted assume failure and