aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuan Jiong <duanj.fnst@cn.fujitsu.com>2014-07-31 05:54:32 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-01 01:04:18 -0400
commit7304fe4681634a8e0511a5922c972aa132ffb43d (patch)
tree97d39043b738e7cd135efcd242dc2430919da2da
parent299ee123e19889d511092347f5fc14db0f10e3a6 (diff)
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: Duan Jiong <duanj.fnst@cn.fujitsu.com> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/icmp.c4
-rw-r--r--net/ipv4/tcp_ipv4.c5
-rw-r--r--net/ipv6/icmp.c13
-rw-r--r--net/ipv6/udp.c8
-rw-r--r--net/sctp/input.c5
5 files changed, 17 insertions, 18 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 42b7bcf8045b..092400ef88d0 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -663,8 +663,10 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
663 /* Checkin full IP header plus 8 bytes of protocol to 663 /* Checkin full IP header plus 8 bytes of protocol to
664 * avoid additional coding at protocol handlers. 664 * avoid additional coding at protocol handlers.
665 */ 665 */
666 if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) 666 if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) {
667 ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS);
667 return; 668 return;
669 }
668 670
669 raw_icmp_error(skb, protocol, info); 671 raw_icmp_error(skb, protocol, info);
670 672
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 1edc739b9da5..d0ba39537d5c 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -344,11 +344,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
344 int err; 344 int err;
345 struct net *net = dev_net(icmp_skb->dev); 345 struct net *net = dev_net(icmp_skb->dev);
346 346
347 if (icmp_skb->len < (iph->ihl << 2) + 8) {
348 ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
349 return;
350 }
351
352 sk = inet_lookup(net, &tcp_hashinfo, iph->daddr, th->dest, 347 sk = inet_lookup(net, &tcp_hashinfo, iph->daddr, th->dest,
353 iph->saddr, th->source, inet_iif(icmp_skb)); 348 iph->saddr, th->source, inet_iif(icmp_skb));
354 if (!sk) { 349 if (!sk) {
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index f6c84a6eb238..06ba3e58320b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -626,9 +626,10 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
626 int inner_offset; 626 int inner_offset;
627 __be16 frag_off; 627 __be16 frag_off;
628 u8 nexthdr; 628 u8 nexthdr;
629 struct net *net = dev_net(skb->dev);
629 630
630 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 631 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
631 return; 632 goto out;
632 633
633 nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr; 634 nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
634 if (ipv6_ext_hdr(nexthdr)) { 635 if (ipv6_ext_hdr(nexthdr)) {
@@ -636,14 +637,14 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
636 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), 637 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
637 &nexthdr, &frag_off); 638 &nexthdr, &frag_off);
638 if (inner_offset<0) 639 if (inner_offset<0)
639 return; 640 goto out;
640 } else { 641 } else {
641 inner_offset = sizeof(struct ipv6hdr); 642 inner_offset = sizeof(struct ipv6hdr);
642 } 643 }
643 644
644 /* Checkin header including 8 bytes of inner protocol header. */ 645 /* Checkin header including 8 bytes of inner protocol header. */
645 if (!pskb_may_pull(skb, inner_offset+8)) 646 if (!pskb_may_pull(skb, inner_offset+8))
646 return; 647 goto out;
647 648
648 /* BUGGG_FUTURE: we should try to parse exthdrs in this packet. 649 /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
649 Without this we will not able f.e. to make source routed 650 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 --ANK (980726) 653 --ANK (980726)
653 */ 654 */
654 655
655 rcu_read_lock();
656 ipprot = rcu_dereference(inet6_protos[nexthdr]); 656 ipprot = rcu_dereference(inet6_protos[nexthdr]);
657 if (ipprot && ipprot->err_handler) 657 if (ipprot && ipprot->err_handler)
658 ipprot->err_handler(skb, NULL, type, code, inner_offset, info); 658 ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
659 rcu_read_unlock();
660 659
661 raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info); 660 raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
661 return;
662
663out:
664 ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
662} 665}
663 666
664/* 667/*
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 5b6091de5868..c6941a1ac977 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -533,11 +533,15 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
533 struct udphdr *uh = (struct udphdr*)(skb->data+offset); 533 struct udphdr *uh = (struct udphdr*)(skb->data+offset);
534 struct sock *sk; 534 struct sock *sk;
535 int err; 535 int err;
536 struct net *net = dev_net(skb->dev);
536 537
537 sk = __udp6_lib_lookup(dev_net(skb->dev), daddr, uh->dest, 538 sk = __udp6_lib_lookup(net, daddr, uh->dest,
538 saddr, uh->source, inet6_iif(skb), udptable); 539 saddr, uh->source, inet6_iif(skb), udptable);
539 if (sk == NULL) 540 if (sk == NULL) {
541 ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
542 ICMP6_MIB_INERRORS);
540 return; 543 return;
544 }
541 545
542 if (type == ICMPV6_PKT_TOOBIG) { 546 if (type == ICMPV6_PKT_TOOBIG) {
543 if (!ip6_sk_accept_pmtu(sk)) 547 if (!ip6_sk_accept_pmtu(sk))
diff --git a/net/sctp/input.c b/net/sctp/input.c
index f2e2cbd2d750..c1b991294516 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -575,11 +575,6 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
575 int err; 575 int err;
576 struct net *net = dev_net(skb->dev); 576 struct net *net = dev_net(skb->dev);
577 577
578 if (skb->len < ihlen + 8) {
579 ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
580 return;
581 }
582
583 /* Fix up skb to look at the embedded net header. */ 578 /* Fix up skb to look at the embedded net header. */
584 saveip = skb->network_header; 579 saveip = skb->network_header;
585 savesctp = skb->transport_header; 580 savesctp = skb->transport_header;