[IPV6] SNMP: Fix {In,Out}NoRoutes statistics.

A packet which is being discarded because of no routes in the
forwarding path should not be counted as OutNoRoutes but as
InNoRoutes.
Additionally, on this occasion, a packet whose destinaion is
not valid should be counted as InAddrErrors separately.

Based on patch from Mitsuru Chinen <mitch@linux.vnet.ibm.com>.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by YOSHIFUJI Hideaki and committed by David S. Miller 612f09e8 661697f7

+19 -10
+19 -10
net/ipv6/route.c
··· 1766 1766 * Drop the packet on the floor 1767 1767 */ 1768 1768 1769 - static inline int ip6_pkt_drop(struct sk_buff *skb, int code) 1769 + static inline int ip6_pkt_drop(struct sk_buff *skb, int code, 1770 + int ipstats_mib_noroutes) 1770 1771 { 1771 - int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); 1772 - if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) 1773 - IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); 1774 - 1775 - IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTNOROUTES); 1772 + int type; 1773 + switch (ipstats_mib_noroutes) { 1774 + case IPSTATS_MIB_INNOROUTES: 1775 + type = ipv6_addr_type(&skb->nh.ipv6h->daddr); 1776 + if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) { 1777 + IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); 1778 + break; 1779 + } 1780 + /* FALLTHROUGH */ 1781 + case IPSTATS_MIB_OUTNOROUTES: 1782 + IP6_INC_STATS(ip6_dst_idev(skb->dst), ipstats_mib_noroutes); 1783 + break; 1784 + } 1776 1785 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); 1777 1786 kfree_skb(skb); 1778 1787 return 0; ··· 1789 1780 1790 1781 static int ip6_pkt_discard(struct sk_buff *skb) 1791 1782 { 1792 - return ip6_pkt_drop(skb, ICMPV6_NOROUTE); 1783 + return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES); 1793 1784 } 1794 1785 1795 1786 static int ip6_pkt_discard_out(struct sk_buff *skb) 1796 1787 { 1797 1788 skb->dev = skb->dst->dev; 1798 - return ip6_pkt_discard(skb); 1789 + return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); 1799 1790 } 1800 1791 1801 1792 #ifdef CONFIG_IPV6_MULTIPLE_TABLES 1802 1793 1803 1794 static int ip6_pkt_prohibit(struct sk_buff *skb) 1804 1795 { 1805 - return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED); 1796 + return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); 1806 1797 } 1807 1798 1808 1799 static int ip6_pkt_prohibit_out(struct sk_buff *skb) 1809 1800 { 1810 1801 skb->dev = skb->dst->dev; 1811 - return ip6_pkt_prohibit(skb); 1802 + return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); 1812 1803 } 1813 1804 1814 1805 static int ip6_pkt_blk_hole(struct sk_buff *skb)