mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 04:33:26 +02:00
ipv6: icmp6: add drop reason support to icmpv6_notify()
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>
This commit is contained in:
committed by
Jakub Kicinski
parent
1fb2d41501
commit
30c89bad3e
@@ -436,7 +436,8 @@ static inline void fl6_sock_release(struct ip6_flowlabel *fl)
|
|||||||
atomic_dec(&fl->users);
|
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,
|
void icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
|
||||||
struct icmp6hdr *thdr, int len);
|
struct icmp6hdr *thdr, int len);
|
||||||
|
@@ -813,16 +813,19 @@ out_bh_enable:
|
|||||||
local_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 inet6_skb_parm *opt = IP6CB(skb);
|
||||||
|
struct net *net = dev_net(skb->dev);
|
||||||
const struct inet6_protocol *ipprot;
|
const struct inet6_protocol *ipprot;
|
||||||
|
enum skb_drop_reason reason;
|
||||||
int inner_offset;
|
int inner_offset;
|
||||||
__be16 frag_off;
|
__be16 frag_off;
|
||||||
u8 nexthdr;
|
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;
|
goto out;
|
||||||
|
|
||||||
seg6_icmp_srh(skb, opt);
|
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 */
|
/* now skip over extension headers */
|
||||||
inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
|
inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
|
||||||
&nexthdr, &frag_off);
|
&nexthdr, &frag_off);
|
||||||
if (inner_offset < 0)
|
if (inner_offset < 0) {
|
||||||
|
SKB_DR_SET(reason, IPV6_BAD_EXTHDR);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
inner_offset = sizeof(struct ipv6hdr);
|
inner_offset = sizeof(struct ipv6hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checkin header including 8 bytes of inner protocol header. */
|
/* 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;
|
goto out;
|
||||||
|
|
||||||
/* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
|
/* 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);
|
ipprot->err_handler(skb, opt, type, code, inner_offset, info);
|
||||||
|
|
||||||
raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
|
raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
|
||||||
return;
|
return SKB_CONSUMED;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
__ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
|
__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_DEST_UNREACH:
|
||||||
case ICMPV6_TIME_EXCEED:
|
case ICMPV6_TIME_EXCEED:
|
||||||
case ICMPV6_PARAMPROB:
|
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;
|
break;
|
||||||
|
|
||||||
case NDISC_ROUTER_SOLICITATION:
|
case NDISC_ROUTER_SOLICITATION:
|
||||||
@@ -995,7 +1003,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
|
|||||||
* must pass to upper level
|
* 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
|
/* until the v6 path can be better sorted assume failure and
|
||||||
|
Reference in New Issue
Block a user