[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 * Drop the packet on the floor 1767 */ 1768 1769 - static inline int ip6_pkt_drop(struct sk_buff *skb, int code) 1770 { 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); 1776 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); 1777 kfree_skb(skb); 1778 return 0; ··· 1789 1790 static int ip6_pkt_discard(struct sk_buff *skb) 1791 { 1792 - return ip6_pkt_drop(skb, ICMPV6_NOROUTE); 1793 } 1794 1795 static int ip6_pkt_discard_out(struct sk_buff *skb) 1796 { 1797 skb->dev = skb->dst->dev; 1798 - return ip6_pkt_discard(skb); 1799 } 1800 1801 #ifdef CONFIG_IPV6_MULTIPLE_TABLES 1802 1803 static int ip6_pkt_prohibit(struct sk_buff *skb) 1804 { 1805 - return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED); 1806 } 1807 1808 static int ip6_pkt_prohibit_out(struct sk_buff *skb) 1809 { 1810 skb->dev = skb->dst->dev; 1811 - return ip6_pkt_prohibit(skb); 1812 } 1813 1814 static int ip6_pkt_blk_hole(struct sk_buff *skb)
··· 1766 * Drop the packet on the floor 1767 */ 1768 1769 + static inline int ip6_pkt_drop(struct sk_buff *skb, int code, 1770 + int ipstats_mib_noroutes) 1771 { 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 + } 1785 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); 1786 kfree_skb(skb); 1787 return 0; ··· 1780 1781 static int ip6_pkt_discard(struct sk_buff *skb) 1782 { 1783 + return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES); 1784 } 1785 1786 static int ip6_pkt_discard_out(struct sk_buff *skb) 1787 { 1788 skb->dev = skb->dst->dev; 1789 + return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); 1790 } 1791 1792 #ifdef CONFIG_IPV6_MULTIPLE_TABLES 1793 1794 static int ip6_pkt_prohibit(struct sk_buff *skb) 1795 { 1796 + return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); 1797 } 1798 1799 static int ip6_pkt_prohibit_out(struct sk_buff *skb) 1800 { 1801 skb->dev = skb->dst->dev; 1802 + return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); 1803 } 1804 1805 static int ip6_pkt_blk_hole(struct sk_buff *skb)