aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2012-12-03 20:13:37 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-04 13:08:10 -0500
commitadfa85e45dac616ff4f8bfceff1621ccafc0b1ff (patch)
tree1d9880ca13a79fbd386bd5bbd48d3031211f8fa3
parent70b386a0cc65041fb01aacf5d4b8d1fa49fc8ce9 (diff)
ipmr/ip6mr: advertise mfc stats via rtnetlink
These statistics can be checked only via /proc/net/ip_mr_cache or SIOCGETSGCNT[_IN6] and thus only for the table RT_TABLE_DEFAULT. Advertising them via rtnetlink allows to get statistics for all cache entries, whatever the table is. Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/uapi/linux/rtnetlink.h7
-rw-r--r--net/ipv4/ipmr.c7
-rw-r--r--net/ipv6/ip6mr.c7
3 files changed, 21 insertions, 0 deletions
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 3dee071770d5..80abe27dc2a7 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -288,6 +288,7 @@ enum rtattr_type_t {
288 RTA_MP_ALGO, /* no longer used */ 288 RTA_MP_ALGO, /* no longer used */
289 RTA_TABLE, 289 RTA_TABLE,
290 RTA_MARK, 290 RTA_MARK,
291 RTA_MFC_STATS,
291 __RTA_MAX 292 __RTA_MAX
292}; 293};
293 294
@@ -408,6 +409,12 @@ struct rta_session {
408 } u; 409 } u;
409}; 410};
410 411
412struct rta_mfc_stats {
413 __u64 mfcs_packets;
414 __u64 mfcs_bytes;
415 __u64 mfcs_wrong_if;
416};
417
411/**** 418/****
412 * General form of address family dependent message. 419 * General form of address family dependent message.
413 ****/ 420 ****/
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 0c452e3fdc1b..c5617d646b93 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -2046,6 +2046,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2046 int ct; 2046 int ct;
2047 struct rtnexthop *nhp; 2047 struct rtnexthop *nhp;
2048 struct nlattr *mp_attr; 2048 struct nlattr *mp_attr;
2049 struct rta_mfc_stats mfcs;
2049 2050
2050 /* If cache is unresolved, don't try to parse IIF and OIF */ 2051 /* If cache is unresolved, don't try to parse IIF and OIF */
2051 if (c->mfc_parent >= MAXVIFS) 2052 if (c->mfc_parent >= MAXVIFS)
@@ -2074,6 +2075,12 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2074 2075
2075 nla_nest_end(skb, mp_attr); 2076 nla_nest_end(skb, mp_attr);
2076 2077
2078 mfcs.mfcs_packets = c->mfc_un.res.pkt;
2079 mfcs.mfcs_bytes = c->mfc_un.res.bytes;
2080 mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
2081 if (nla_put(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs) < 0)
2082 return -EMSGSIZE;
2083
2077 rtm->rtm_type = RTN_MULTICAST; 2084 rtm->rtm_type = RTN_MULTICAST;
2078 return 1; 2085 return 1;
2079} 2086}
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 23f364a9efb5..4220a7b93386 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -2120,6 +2120,7 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
2120 int ct; 2120 int ct;
2121 struct rtnexthop *nhp; 2121 struct rtnexthop *nhp;
2122 struct nlattr *mp_attr; 2122 struct nlattr *mp_attr;
2123 struct rta_mfc_stats mfcs;
2123 2124
2124 /* If cache is unresolved, don't try to parse IIF and OIF */ 2125 /* If cache is unresolved, don't try to parse IIF and OIF */
2125 if (c->mf6c_parent >= MAXMIFS) 2126 if (c->mf6c_parent >= MAXMIFS)
@@ -2149,6 +2150,12 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
2149 2150
2150 nla_nest_end(skb, mp_attr); 2151 nla_nest_end(skb, mp_attr);
2151 2152
2153 mfcs.mfcs_packets = c->mfc_un.res.pkt;
2154 mfcs.mfcs_bytes = c->mfc_un.res.bytes;
2155 mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
2156 if (nla_put(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs) < 0)
2157 return -EMSGSIZE;
2158
2152 rtm->rtm_type = RTN_MULTICAST; 2159 rtm->rtm_type = RTN_MULTICAST;
2153 return 1; 2160 return 1;
2154} 2161}