Commit 7304fe46 authored by Duan Jiong's avatar Duan Jiong Committed by David S. Miller

net: fix the counter ICMP_MIB_INERRORS/ICMP6_MIB_INERRORS

When dealing with ICMPv[46] Error Message, function icmp_socket_deliver()
and icmpv6_notify() do some valid checks on packet's length, but then some
protocols check packet's length redaudantly. So remove those duplicated
statements, and increase counter ICMP_MIB_INERRORS/ICMP6_MIB_INERRORS in
function icmp_socket_deliver() and icmpv6_notify() respectively.

In addition, add missed counter in udp6/udplite6 when socket is NULL.
Signed-off-by: default avatarDuan Jiong <duanj.fnst@cn.fujitsu.com>
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 299ee123
...@@ -663,8 +663,10 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info) ...@@ -663,8 +663,10 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
/* Checkin full IP header plus 8 bytes of protocol to /* Checkin full IP header plus 8 bytes of protocol to
* avoid additional coding at protocol handlers. * avoid additional coding at protocol handlers.
*/ */
if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) {
ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS);
return; return;
}
raw_icmp_error(skb, protocol, info); raw_icmp_error(skb, protocol, info);
......
...@@ -344,11 +344,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) ...@@ -344,11 +344,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
int err; int err;
struct net *net = dev_net(icmp_skb->dev); struct net *net = dev_net(icmp_skb->dev);
if (icmp_skb->len < (iph->ihl << 2) + 8) {
ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
return;
}
sk = inet_lookup(net, &tcp_hashinfo, iph->daddr, th->dest, sk = inet_lookup(net, &tcp_hashinfo, iph->daddr, th->dest,
iph->saddr, th->source, inet_iif(icmp_skb)); iph->saddr, th->source, inet_iif(icmp_skb));
if (!sk) { if (!sk) {
......
...@@ -626,9 +626,10 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) ...@@ -626,9 +626,10 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
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))) if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
return; goto out;
nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr; nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
if (ipv6_ext_hdr(nexthdr)) { if (ipv6_ext_hdr(nexthdr)) {
...@@ -636,14 +637,14 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) ...@@ -636,14 +637,14 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
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)
return; 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)) if (!pskb_may_pull(skb, inner_offset+8))
return; goto out;
/* BUGGG_FUTURE: we should try to parse exthdrs in this packet. /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
Without this we will not able f.e. to make source routed Without this we will not able f.e. to make source routed
...@@ -652,13 +653,15 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) ...@@ -652,13 +653,15 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
--ANK (980726) --ANK (980726)
*/ */
rcu_read_lock();
ipprot = rcu_dereference(inet6_protos[nexthdr]); ipprot = rcu_dereference(inet6_protos[nexthdr]);
if (ipprot && ipprot->err_handler) if (ipprot && ipprot->err_handler)
ipprot->err_handler(skb, NULL, type, code, inner_offset, info); ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
rcu_read_unlock();
raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info); raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
return;
out:
ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
} }
/* /*
......
...@@ -533,11 +533,15 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -533,11 +533,15 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct udphdr *uh = (struct udphdr*)(skb->data+offset); struct udphdr *uh = (struct udphdr*)(skb->data+offset);
struct sock *sk; struct sock *sk;
int err; int err;
struct net *net = dev_net(skb->dev);
sk = __udp6_lib_lookup(dev_net(skb->dev), daddr, uh->dest, sk = __udp6_lib_lookup(net, daddr, uh->dest,
saddr, uh->source, inet6_iif(skb), udptable); saddr, uh->source, inet6_iif(skb), udptable);
if (sk == NULL) if (sk == NULL) {
ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
ICMP6_MIB_INERRORS);
return; return;
}
if (type == ICMPV6_PKT_TOOBIG) { if (type == ICMPV6_PKT_TOOBIG) {
if (!ip6_sk_accept_pmtu(sk)) if (!ip6_sk_accept_pmtu(sk))
......
...@@ -575,11 +575,6 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) ...@@ -575,11 +575,6 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
int err; int err;
struct net *net = dev_net(skb->dev); struct net *net = dev_net(skb->dev);
if (skb->len < ihlen + 8) {
ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
return;
}
/* Fix up skb to look at the embedded net header. */ /* Fix up skb to look at the embedded net header. */
saveip = skb->network_header; saveip = skb->network_header;
savesctp = skb->transport_header; savesctp = skb->transport_header;
......
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