Commit cf06eef0 authored by David S. Miller's avatar David S. Miller

Merge branch 'icmp6-drop-reason'

Eric Dumazet says:

====================
ipv6: icmp6: better drop reason support

This series aims to have more precise drop reason reports for icmp6.

This should reduce false positives on most usual cases.

This can be extended as needed later.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents dd1b5278 ac03694b
...@@ -76,6 +76,8 @@ ...@@ -76,6 +76,8 @@
FN(IPV6_NDISC_FRAG) \ FN(IPV6_NDISC_FRAG) \
FN(IPV6_NDISC_HOP_LIMIT) \ FN(IPV6_NDISC_HOP_LIMIT) \
FN(IPV6_NDISC_BAD_CODE) \ FN(IPV6_NDISC_BAD_CODE) \
FN(IPV6_NDISC_BAD_OPTIONS) \
FN(IPV6_NDISC_NS_OTHERHOST) \
FNe(MAX) FNe(MAX)
/** /**
...@@ -330,6 +332,12 @@ enum skb_drop_reason { ...@@ -330,6 +332,12 @@ enum skb_drop_reason {
SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT, SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT,
/** @SKB_DROP_REASON_IPV6_NDISC_BAD_CODE: invalid NDISC icmp6 code. */ /** @SKB_DROP_REASON_IPV6_NDISC_BAD_CODE: invalid NDISC icmp6 code. */
SKB_DROP_REASON_IPV6_NDISC_BAD_CODE, SKB_DROP_REASON_IPV6_NDISC_BAD_CODE,
/** @SKB_DROP_REASON_IPV6_NDISC_BAD_OPTIONS: invalid NDISC options. */
SKB_DROP_REASON_IPV6_NDISC_BAD_OPTIONS,
/** @SKB_DROP_REASON_IPV6_NDISC_NS_OTHERHOST: NEIGHBOUR SOLICITATION
* for another host.
*/
SKB_DROP_REASON_IPV6_NDISC_NS_OTHERHOST,
/** /**
* @SKB_DROP_REASON_MAX: the maximum of drop reason, which shouldn't be * @SKB_DROP_REASON_MAX: the maximum of drop reason, which shouldn't be
* used as a real 'reason' * used as a real 'reason'
......
...@@ -705,7 +705,7 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type, ...@@ -705,7 +705,7 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
} }
EXPORT_SYMBOL(ip6_err_gen_icmpv6_unreach); EXPORT_SYMBOL(ip6_err_gen_icmpv6_unreach);
static void icmpv6_echo_reply(struct sk_buff *skb) static enum skb_drop_reason icmpv6_echo_reply(struct sk_buff *skb)
{ {
struct net *net = dev_net(skb->dev); struct net *net = dev_net(skb->dev);
struct sock *sk; struct sock *sk;
...@@ -719,18 +719,19 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ...@@ -719,18 +719,19 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
struct dst_entry *dst; struct dst_entry *dst;
struct ipcm6_cookie ipc6; struct ipcm6_cookie ipc6;
u32 mark = IP6_REPLY_MARK(net, skb->mark); u32 mark = IP6_REPLY_MARK(net, skb->mark);
SKB_DR(reason);
bool acast; bool acast;
u8 type; u8 type;
if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) && if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) &&
net->ipv6.sysctl.icmpv6_echo_ignore_multicast) net->ipv6.sysctl.icmpv6_echo_ignore_multicast)
return; return reason;
saddr = &ipv6_hdr(skb)->daddr; saddr = &ipv6_hdr(skb)->daddr;
acast = ipv6_anycast_destination(skb_dst(skb), saddr); acast = ipv6_anycast_destination(skb_dst(skb), saddr);
if (acast && net->ipv6.sysctl.icmpv6_echo_ignore_anycast) if (acast && net->ipv6.sysctl.icmpv6_echo_ignore_anycast)
return; return reason;
if (!ipv6_unicast_destination(skb) && if (!ipv6_unicast_destination(skb) &&
!(net->ipv6.sysctl.anycast_src_echo_reply && acast)) !(net->ipv6.sysctl.anycast_src_echo_reply && acast))
...@@ -804,6 +805,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ...@@ -804,6 +805,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
} else { } else {
icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
skb->len + sizeof(struct icmp6hdr)); skb->len + sizeof(struct icmp6hdr));
reason = SKB_CONSUMED;
} }
out_dst_release: out_dst_release:
dst_release(dst); dst_release(dst);
...@@ -811,6 +813,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ...@@ -811,6 +813,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
icmpv6_xmit_unlock(sk); icmpv6_xmit_unlock(sk);
out_bh_enable: out_bh_enable:
local_bh_enable(); local_bh_enable();
return reason;
} }
enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type, enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type,
...@@ -929,12 +932,12 @@ static int icmpv6_rcv(struct sk_buff *skb) ...@@ -929,12 +932,12 @@ static int icmpv6_rcv(struct sk_buff *skb)
switch (type) { switch (type) {
case ICMPV6_ECHO_REQUEST: case ICMPV6_ECHO_REQUEST:
if (!net->ipv6.sysctl.icmpv6_echo_ignore_all) if (!net->ipv6.sysctl.icmpv6_echo_ignore_all)
icmpv6_echo_reply(skb); reason = icmpv6_echo_reply(skb);
break; break;
case ICMPV6_EXT_ECHO_REQUEST: case ICMPV6_EXT_ECHO_REQUEST:
if (!net->ipv6.sysctl.icmpv6_echo_ignore_all && if (!net->ipv6.sysctl.icmpv6_echo_ignore_all &&
READ_ONCE(net->ipv4.sysctl_icmp_echo_enable_probe)) READ_ONCE(net->ipv4.sysctl_icmp_echo_enable_probe))
icmpv6_echo_reply(skb); reason = icmpv6_echo_reply(skb);
break; break;
case ICMPV6_ECHO_REPLY: case ICMPV6_ECHO_REPLY:
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment