summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c7
-rw-r--r--net/ipv6/af_inet6.c5
-rw-r--r--net/ipv6/icmp.c12
-rw-r--r--net/ipv6/ip6_output.c7
-rw-r--r--net/ipv6/mcast.c12
-rw-r--r--net/ipv6/ndisc.c21
-rw-r--r--net/ipv6/proc.c92
7 files changed, 94 insertions, 62 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a68c626567f2..9c2e94f1c637 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -261,9 +261,15 @@ static int snmp6_alloc_dev(struct inet6_dev *idev)
sizeof(struct icmpv6_mib),
__alignof__(struct icmpv6_mib)) < 0)
goto err_icmp;
+ if (snmp_mib_init((void **)idev->stats.icmpv6msg,
+ sizeof(struct icmpv6msg_mib),
+ __alignof__(struct icmpv6msg_mib)) < 0)
+ goto err_icmpmsg;
return 0;
+err_icmpmsg:
+ snmp_mib_free((void **)idev->stats.icmpv6);
err_icmp:
snmp_mib_free((void **)idev->stats.ipv6);
err_ip:
@@ -272,6 +278,7 @@ err_ip:
static int snmp6_free_dev(struct inet6_dev *idev)
{
+ snmp_mib_free((void **)idev->stats.icmpv6msg);
snmp_mib_free((void **)idev->stats.icmpv6);
snmp_mib_free((void **)idev->stats.ipv6);
return 0;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e5c5aad44bb1..bc929381fa46 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -719,6 +719,9 @@ static int __init init_ipv6_mibs(void)
if (snmp_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib),
__alignof__(struct icmpv6_mib)) < 0)
goto err_icmp_mib;
+ if (snmp_mib_init((void **)icmpv6msg_statistics,
+ sizeof (struct icmpv6msg_mib), __alignof__(struct icmpv6_mib)) < 0)
+ goto err_icmpmsg_mib;
if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib),
__alignof__(struct udp_mib)) < 0)
goto err_udp_mib;
@@ -730,6 +733,8 @@ static int __init init_ipv6_mibs(void)
err_udplite_mib:
snmp_mib_free((void **)udp_stats_in6);
err_udp_mib:
+ snmp_mib_free((void **)icmpv6msg_statistics);
+err_icmpmsg_mib:
snmp_mib_free((void **)icmpv6_statistics);
err_icmp_mib:
snmp_mib_free((void **)ipv6_statistics);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 6a6714d154ed..47b8ce232e84 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -69,6 +69,8 @@
DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly;
EXPORT_SYMBOL(icmpv6_statistics);
+DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics) __read_mostly;
+EXPORT_SYMBOL(icmpv6msg_statistics);
/*
* The ICMP socket(s). This is the most convenient way to flow control
@@ -456,8 +458,6 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
}
err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
- if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
- ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_OUTDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
out_put:
@@ -547,9 +547,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
}
err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
- ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTECHOREPLIES);
- ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
-
out_put:
if (likely(idev != NULL))
in6_dev_put(idev);
@@ -656,10 +653,7 @@ static int icmpv6_rcv(struct sk_buff **pskb)
type = hdr->icmp6_type;
- if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
- ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
- else if (type >= ICMPV6_ECHO_REQUEST && type <= NDISC_REDIRECT)
- ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INECHOS, type - ICMPV6_ECHO_REQUEST);
+ ICMP6MSGIN_INC_STATS_BH(idev, type);
switch (type) {
case ICMPV6_ECHO_REQUEST:
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index e46d4683eab0..011082ed921a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1399,6 +1399,13 @@ int ip6_push_pending_frames(struct sock *sk)
skb->dst = dst_clone(&rt->u.dst);
IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
+ if (proto == IPPROTO_ICMPV6) {
+ struct inet6_dev *idev = ip6_dst_idev(skb->dst);
+
+ ICMP6MSGOUT_INC_STATS_BH(idev, icmp6_hdr(skb)->icmp6_type);
+ ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
+ }
+
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
if (err) {
if (err > 0)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index e2ab43c989d4..86d908b1caea 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1479,10 +1479,11 @@ static void mld_sendpack(struct sk_buff *skb)
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
mld_dev_queue_xmit);
if (!err) {
- ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS);
- IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
+ ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT);
+ ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
+ IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTMCASTPKTS);
} else
- IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
+ IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTDISCARDS);
if (likely(idev != NULL))
in6_dev_put(idev);
@@ -1822,10 +1823,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
mld_dev_queue_xmit);
if (!err) {
- if (type == ICMPV6_MGM_REDUCTION)
- ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS);
- else
- ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBRESPONSES);
+ ICMP6MSGOUT_INC_STATS(idev, type);
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
} else
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index d2d44dc22f19..7ea5a502ca08 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -431,7 +431,7 @@ static void __ndisc_send(struct net_device *dev,
struct neighbour *neigh,
struct in6_addr *daddr, struct in6_addr *saddr,
struct icmp6hdr *icmp6h, struct in6_addr *target,
- int llinfo, int icmp6_mib_outnd)
+ int llinfo)
{
struct flowi fl;
struct dst_entry *dst;
@@ -441,9 +441,11 @@ static void __ndisc_send(struct net_device *dev,
struct inet6_dev *idev;
int len;
int err;
- u8 *opt;
+ u8 *opt, type;
+
+ type = icmp6h->icmp6_type;
- ndisc_flow_init(&fl, icmp6h->icmp6_type, saddr, daddr,
+ ndisc_flow_init(&fl, type, saddr, daddr,
dev->ifindex);
dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
@@ -504,7 +506,7 @@ static void __ndisc_send(struct net_device *dev,
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
if (!err) {
- ICMP6_INC_STATS(idev, icmp6_mib_outnd);
+ ICMP6MSGOUT_INC_STATS(idev, type);
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
}
@@ -542,8 +544,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
__ndisc_send(dev, neigh, daddr, src_addr,
&icmp6h, solicited_addr,
- inc_opt ? ND_OPT_TARGET_LL_ADDR : 0,
- ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
+ inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
}
void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
@@ -564,8 +565,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
__ndisc_send(dev, neigh, daddr, saddr,
&icmp6h, solicit,
- !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0,
- ICMP6_MIB_OUTNEIGHBORSOLICITS);
+ !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
}
void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
@@ -599,8 +599,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
#endif
__ndisc_send(dev, NULL, daddr, saddr,
&icmp6h, NULL,
- send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0,
- ICMP6_MIB_OUTROUTERSOLICITS);
+ send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
}
@@ -1455,7 +1454,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
if (!err) {
- ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
+ ICMP6MSGOUT_INC_STATS(idev, NDISC_REDIRECT);
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
}
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index a712a2289484..db945018579e 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -86,47 +86,33 @@ static struct snmp_mib snmp6_ipstats_list[] = {
};
static struct snmp_mib snmp6_icmp6_list[] = {
-/* icmpv6 mib according to RFC 2466
-
- Exceptions: {In|Out}AdminProhibs are removed, because I see
- no good reasons to account them separately
- of another dest.unreachs.
- OutErrs is zero identically.
- OutEchos too.
- OutRouterAdvertisements too.
- OutGroupMembQueries too.
- */
+/* icmpv6 mib according to RFC 2466 */
SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS),
SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS),
- SNMP_MIB_ITEM("Icmp6InDestUnreachs", ICMP6_MIB_INDESTUNREACHS),
- SNMP_MIB_ITEM("Icmp6InPktTooBigs", ICMP6_MIB_INPKTTOOBIGS),
- SNMP_MIB_ITEM("Icmp6InTimeExcds", ICMP6_MIB_INTIMEEXCDS),
- SNMP_MIB_ITEM("Icmp6InParmProblems", ICMP6_MIB_INPARMPROBLEMS),
- SNMP_MIB_ITEM("Icmp6InEchos", ICMP6_MIB_INECHOS),
- SNMP_MIB_ITEM("Icmp6InEchoReplies", ICMP6_MIB_INECHOREPLIES),
- SNMP_MIB_ITEM("Icmp6InGroupMembQueries", ICMP6_MIB_INGROUPMEMBQUERIES),
- SNMP_MIB_ITEM("Icmp6InGroupMembResponses", ICMP6_MIB_INGROUPMEMBRESPONSES),
- SNMP_MIB_ITEM("Icmp6InGroupMembReductions", ICMP6_MIB_INGROUPMEMBREDUCTIONS),
- SNMP_MIB_ITEM("Icmp6InRouterSolicits", ICMP6_MIB_INROUTERSOLICITS),
- SNMP_MIB_ITEM("Icmp6InRouterAdvertisements", ICMP6_MIB_INROUTERADVERTISEMENTS),
- SNMP_MIB_ITEM("Icmp6InNeighborSolicits", ICMP6_MIB_INNEIGHBORSOLICITS),
- SNMP_MIB_ITEM("Icmp6InNeighborAdvertisements", ICMP6_MIB_INNEIGHBORADVERTISEMENTS),
- SNMP_MIB_ITEM("Icmp6InRedirects", ICMP6_MIB_INREDIRECTS),
SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS),
- SNMP_MIB_ITEM("Icmp6OutDestUnreachs", ICMP6_MIB_OUTDESTUNREACHS),
- SNMP_MIB_ITEM("Icmp6OutPktTooBigs", ICMP6_MIB_OUTPKTTOOBIGS),
- SNMP_MIB_ITEM("Icmp6OutTimeExcds", ICMP6_MIB_OUTTIMEEXCDS),
- SNMP_MIB_ITEM("Icmp6OutParmProblems", ICMP6_MIB_OUTPARMPROBLEMS),
- SNMP_MIB_ITEM("Icmp6OutEchoReplies", ICMP6_MIB_OUTECHOREPLIES),
- SNMP_MIB_ITEM("Icmp6OutRouterSolicits", ICMP6_MIB_OUTROUTERSOLICITS),
- SNMP_MIB_ITEM("Icmp6OutNeighborSolicits", ICMP6_MIB_OUTNEIGHBORSOLICITS),
- SNMP_MIB_ITEM("Icmp6OutNeighborAdvertisements", ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS),
- SNMP_MIB_ITEM("Icmp6OutRedirects", ICMP6_MIB_OUTREDIRECTS),
- SNMP_MIB_ITEM("Icmp6OutGroupMembResponses", ICMP6_MIB_OUTGROUPMEMBRESPONSES),
- SNMP_MIB_ITEM("Icmp6OutGroupMembReductions", ICMP6_MIB_OUTGROUPMEMBREDUCTIONS),
SNMP_MIB_SENTINEL
};
+/* RFC 4293 v6 ICMPMsgStatsTable; named items for RFC 2466 compatibility */
+static char *icmp6type2name[256] = {
+ [ICMPV6_DEST_UNREACH] = "DestUnreachs",
+ [ICMPV6_PKT_TOOBIG] = "PktTooBigs",
+ [ICMPV6_TIME_EXCEED] = "TimeExcds",
+ [ICMPV6_PARAMPROB] = "ParmProblems",
+ [ICMPV6_ECHO_REQUEST] = "EchoRequest",
+ [ICMPV6_ECHO_REPLY] = "EchoReplies",
+ [ICMPV6_MGM_QUERY] = "GroupMembQueries",
+ [ICMPV6_MGM_REPORT] = "GroupMembResponses",
+ [ICMPV6_MGM_REDUCTION] = "GroupMembReductions",
+ [ICMPV6_MLD2_REPORT] = "MLDv2Reports",
+ [NDISC_ROUTER_ADVERTISEMENT] = "RouterAdvertisements",
+ [NDISC_ROUTER_SOLICITATION] = "RouterSolicits",
+ [NDISC_NEIGHBOUR_ADVERTISEMENT] = "NeighborAdvertisements",
+ [NDISC_NEIGHBOUR_SOLICITATION] = "NeighborSolicits",
+ [NDISC_REDIRECT] = "NeighborRedirects",
+};
+
+
static struct snmp_mib snmp6_udp6_list[] = {
SNMP_MIB_ITEM("Udp6InDatagrams", UDP_MIB_INDATAGRAMS),
SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS),
@@ -143,6 +129,40 @@ static struct snmp_mib snmp6_udplite6_list[] = {
SNMP_MIB_SENTINEL
};
+static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib)
+{
+ static char name[32];
+ int i;
+
+ /* print by name -- deprecated items */
+ for (i = 0; i < ICMP6MSG_MIB_MAX; i++) {
+ int icmptype;
+ char *p;
+
+ icmptype = i & 0xff;
+ p = icmp6type2name[icmptype];
+ if (!p) /* don't print un-named types here */
+ continue;
+ (void) snprintf(name, sizeof(name)-1, "Icmp6%s%s",
+ i & 0x100 ? "Out" : "In", p);
+ seq_printf(seq, "%-32s\t%lu\n", name,
+ snmp_fold_field(mib, i));
+ }
+
+ /* print by number (nonzero only) - ICMPMsgStat format */
+ for (i = 0; i < ICMP6MSG_MIB_MAX; i++) {
+ unsigned long val;
+
+ val = snmp_fold_field(mib, i);
+ if (!val)
+ continue;
+ (void) snprintf(name, sizeof(name)-1, "Icmp6%sType%u",
+ i & 0x100 ? "Out" : "In", i & 0xff);
+ seq_printf(seq, "%-32s\t%lu\n", name, val);
+ }
+ return;
+}
+
static inline void
snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist)
{
@@ -160,9 +180,11 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list);
snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list);
+ snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg);
} else {
snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
+ snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics);
snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
}