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.
Unified · Split
| @@ -288,6 +288,7 @@ enum rtattr_type_t { · 287 unmodified lines | ||
| 288 | 288 | RTA_MP_ALGO, /* no longer used */ |
| 289 | 289 | RTA_TABLE, |
| 290 | 290 | RTA_MARK, |
| 291 | + RTA_MFC_STATS, | |
| 291 | 292 | __RTA_MAX |
| 292 | 293 | }; |
| 293 | 294 | |
| @@ -408,6 +409,12 @@ struct rta_session { · 114 unmodified lines | ||
| 408 | 409 | } u; |
| 409 | 410 | }; |
| 410 | 411 | |
| 412 | +struct rta_mfc_stats { | |
| 413 | + __u64 mfcs_packets; | |
| 414 | + __u64 mfcs_bytes; | |
| 415 | + __u64 mfcs_wrong_if; | |
| 416 | +}; | |
| 417 | + | |
| 411 | 418 | /**** |
| 412 | 419 | * General form of address family dependent message. |
| 413 | 420 | ****/ |
| @@ -2046,6 +2046,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, · 2045 unmodified lines | ||
| 2046 | 2046 | int ct; |
| 2047 | 2047 | struct rtnexthop *nhp; |
| 2048 | 2048 | struct nlattr *mp_attr; |
| 2049 | + struct rta_mfc_stats mfcs; | |
| 2049 | 2050 | |
| 2050 | 2051 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
| 2051 | 2052 | if (c->mfc_parent >= MAXVIFS) |
| @@ -2074,6 +2075,12 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, · 22 unmodified lines | ||
| 2074 | 2075 | |
| 2075 | 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 | 2084 | rtm->rtm_type = RTN_MULTICAST; |
| 2078 | 2085 | return 1; |
| 2079 | 2086 | } |
| @@ -2120,6 +2120,7 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, · 2119 unmodified lines | ||
| 2120 | 2120 | int ct; |
| 2121 | 2121 | struct rtnexthop *nhp; |
| 2122 | 2122 | struct nlattr *mp_attr; |
| 2123 | + struct rta_mfc_stats mfcs; | |
| 2123 | 2124 | |
| 2124 | 2125 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
| 2125 | 2126 | if (c->mf6c_parent >= MAXMIFS) |
| @@ -2149,6 +2150,12 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, · 23 unmodified lines | ||
| 2149 | 2150 | |
| 2150 | 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 | 2159 | rtm->rtm_type = RTN_MULTICAST; |
| 2153 | 2160 | return 1; |
| 2154 | 2161 | } |