aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>2016-07-14 12:28:27 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-16 23:19:43 -0400
commit43b9e127406079d187794a5140a2411fbc6df2df (patch)
tree0950c4475d02bba3959846242e9c0fe5bb758dda /net/ipv4
parenta5a18bdf7453d505783e40e47ebb84bfdd35f93b (diff)
net: ipmr/ip6mr: add support for keeping an entry age
In preparation for hardware offloading of ipmr/ip6mr we need an interface that allows to check (and later update) the age of entries. Relying on stats alone can show activity but not actual age of the entry, furthermore when there're tens of thousands of entries a lot of the hardware implementations only support "hit" bits which are cleared on read to denote that the entry was active and shouldn't be aged out, these can then be naturally translated into age timestamp and will be compatible with the software forwarding age. Using a lastuse entry doesn't affect performance because the members in that cache line are written to along with the age. Since all new users are encouraged to use ipmr via netlink, this is exported via the RTA_EXPIRES attribute. Also do a minor local variable declaration style adjustment - arrange them longest to shortest. Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> CC: Roopa Prabhu <roopa@cumulusnetworks.com> CC: Shrijeet Mukherjee <shm@cumulusnetworks.com> CC: Satish Ashok <sashok@cumulusnetworks.com> CC: Donald Sharp <sharpd@cumulusnetworks.com> CC: David S. Miller <davem@davemloft.net> CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> CC: James Morris <jmorris@namei.org> CC: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> CC: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ipmr.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 5ad48ec77710..e0d76f5f0113 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1150,6 +1150,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
1150 c->mfc_origin = mfc->mfcc_origin.s_addr; 1150 c->mfc_origin = mfc->mfcc_origin.s_addr;
1151 c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr; 1151 c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr;
1152 c->mfc_parent = mfc->mfcc_parent; 1152 c->mfc_parent = mfc->mfcc_parent;
1153 c->mfc_un.res.lastuse = jiffies;
1153 ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls); 1154 ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls);
1154 if (!mrtsock) 1155 if (!mrtsock)
1155 c->mfc_flags |= MFC_STATIC; 1156 c->mfc_flags |= MFC_STATIC;
@@ -1792,6 +1793,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
1792 vif = cache->mfc_parent; 1793 vif = cache->mfc_parent;
1793 cache->mfc_un.res.pkt++; 1794 cache->mfc_un.res.pkt++;
1794 cache->mfc_un.res.bytes += skb->len; 1795 cache->mfc_un.res.bytes += skb->len;
1796 cache->mfc_un.res.lastuse = jiffies;
1795 1797
1796 if (cache->mfc_origin == htonl(INADDR_ANY) && true_vifi >= 0) { 1798 if (cache->mfc_origin == htonl(INADDR_ANY) && true_vifi >= 0) {
1797 struct mfc_cache *cache_proxy; 1799 struct mfc_cache *cache_proxy;
@@ -2071,10 +2073,10 @@ drop:
2071static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, 2073static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2072 struct mfc_cache *c, struct rtmsg *rtm) 2074 struct mfc_cache *c, struct rtmsg *rtm)
2073{ 2075{
2074 int ct;
2075 struct rtnexthop *nhp;
2076 struct nlattr *mp_attr;
2077 struct rta_mfc_stats mfcs; 2076 struct rta_mfc_stats mfcs;
2077 struct nlattr *mp_attr;
2078 struct rtnexthop *nhp;
2079 int ct;
2078 2080
2079 /* If cache is unresolved, don't try to parse IIF and OIF */ 2081 /* If cache is unresolved, don't try to parse IIF and OIF */
2080 if (c->mfc_parent >= MAXVIFS) 2082 if (c->mfc_parent >= MAXVIFS)
@@ -2106,7 +2108,10 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2106 mfcs.mfcs_packets = c->mfc_un.res.pkt; 2108 mfcs.mfcs_packets = c->mfc_un.res.pkt;
2107 mfcs.mfcs_bytes = c->mfc_un.res.bytes; 2109 mfcs.mfcs_bytes = c->mfc_un.res.bytes;
2108 mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; 2110 mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
2109 if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) < 0) 2111 if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
2112 nla_put_u64_64bit(skb, RTA_EXPIRES,
2113 jiffies_to_clock_t(c->mfc_un.res.lastuse),
2114 RTA_PAD))
2110 return -EMSGSIZE; 2115 return -EMSGSIZE;
2111 2116
2112 rtm->rtm_type = RTN_MULTICAST; 2117 rtm->rtm_type = RTN_MULTICAST;