@@ -813,16 +813,19 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
813813 local_bh_enable ();
814814}
815815
816- void icmpv6_notify (struct sk_buff * skb , u8 type , u8 code , __be32 info )
816+ enum skb_drop_reason icmpv6_notify (struct sk_buff * skb , u8 type ,
817+ u8 code , __be32 info )
817818{
818819 struct inet6_skb_parm * opt = IP6CB (skb );
820+ struct net * net = dev_net (skb -> dev );
819821 const struct inet6_protocol * ipprot ;
822+ enum skb_drop_reason reason ;
820823 int inner_offset ;
821824 __be16 frag_off ;
822825 u8 nexthdr ;
823- struct net * net = dev_net (skb -> dev );
824826
825- if (!pskb_may_pull (skb , sizeof (struct ipv6hdr )))
827+ reason = pskb_may_pull_reason (skb , sizeof (struct ipv6hdr ));
828+ if (reason != SKB_NOT_DROPPED_YET )
826829 goto out ;
827830
828831 seg6_icmp_srh (skb , opt );
@@ -832,14 +835,17 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
832835 /* now skip over extension headers */
833836 inner_offset = ipv6_skip_exthdr (skb , sizeof (struct ipv6hdr ),
834837 & nexthdr , & frag_off );
835- if (inner_offset < 0 )
838+ if (inner_offset < 0 ) {
839+ SKB_DR_SET (reason , IPV6_BAD_EXTHDR );
836840 goto out ;
841+ }
837842 } else {
838843 inner_offset = sizeof (struct ipv6hdr );
839844 }
840845
841846 /* Checkin header including 8 bytes of inner protocol header. */
842- if (!pskb_may_pull (skb , inner_offset + 8 ))
847+ reason = pskb_may_pull_reason (skb , inner_offset + 8 );
848+ if (reason != SKB_NOT_DROPPED_YET )
843849 goto out ;
844850
845851 /* 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)
854860 ipprot -> err_handler (skb , opt , type , code , inner_offset , info );
855861
856862 raw6_icmp_error (skb , nexthdr , type , code , inner_offset , info );
857- return ;
863+ return SKB_CONSUMED ;
858864
859865out :
860866 __ICMP6_INC_STATS (net , __in6_dev_get (skb -> dev ), ICMP6_MIB_INERRORS );
867+ return reason ;
861868}
862869
863870/*
@@ -953,15 +960,16 @@ static int icmpv6_rcv(struct sk_buff *skb)
953960 case ICMPV6_DEST_UNREACH :
954961 case ICMPV6_TIME_EXCEED :
955962 case ICMPV6_PARAMPROB :
956- icmpv6_notify (skb , type , hdr -> icmp6_code , hdr -> icmp6_mtu );
963+ reason = icmpv6_notify (skb , type , hdr -> icmp6_code ,
964+ hdr -> icmp6_mtu );
957965 break ;
958966
959967 case NDISC_ROUTER_SOLICITATION :
960968 case NDISC_ROUTER_ADVERTISEMENT :
961969 case NDISC_NEIGHBOUR_SOLICITATION :
962970 case NDISC_NEIGHBOUR_ADVERTISEMENT :
963971 case NDISC_REDIRECT :
964- ndisc_rcv (skb );
972+ reason = ndisc_rcv (skb );
965973 break ;
966974
967975 case ICMPV6_MGM_QUERY :
@@ -995,7 +1003,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
9951003 * must pass to upper level
9961004 */
9971005
998- icmpv6_notify (skb , type , hdr -> icmp6_code , hdr -> icmp6_mtu );
1006+ reason = icmpv6_notify (skb , type , hdr -> icmp6_code ,
1007+ hdr -> icmp6_mtu );
9991008 }
10001009
10011010 /* until the v6 path can be better sorted assume failure and
0 commit comments