Merge tag 'powerpc-4.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[cascardo/linux.git] / net / ipv6 / ip6mr.c
index 487ef3b..6122f9c 100644 (file)
@@ -921,6 +921,7 @@ static void ip6mr_update_thresholds(struct mr6_table *mrt, struct mfc6_cache *ca
                                cache->mfc_un.res.maxvif = vifi + 1;
                }
        }
+       cache->mfc_un.res.lastuse = jiffies;
 }
 
 static int mif6_add(struct net *net, struct mr6_table *mrt,
@@ -1592,14 +1593,15 @@ static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk)
        if (likely(mrt->mroute6_sk == NULL)) {
                mrt->mroute6_sk = sk;
                net->ipv6.devconf_all->mc_forwarding++;
-               inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
-                                            NETCONFA_IFINDEX_ALL,
-                                            net->ipv6.devconf_all);
-       }
-       else
+       } else {
                err = -EADDRINUSE;
+       }
        write_unlock_bh(&mrt_lock);
 
+       if (!err)
+               inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
+                                            NETCONFA_IFINDEX_ALL,
+                                            net->ipv6.devconf_all);
        rtnl_unlock();
 
        return err;
@@ -1617,11 +1619,11 @@ int ip6mr_sk_done(struct sock *sk)
                        write_lock_bh(&mrt_lock);
                        mrt->mroute6_sk = NULL;
                        net->ipv6.devconf_all->mc_forwarding--;
+                       write_unlock_bh(&mrt_lock);
                        inet6_netconf_notify_devconf(net,
                                                     NETCONFA_MC_FORWARDING,
                                                     NETCONFA_IFINDEX_ALL,
                                                     net->ipv6.devconf_all);
-                       write_unlock_bh(&mrt_lock);
 
                        mroute_clean_tables(mrt, false);
                        err = 0;
@@ -2091,6 +2093,7 @@ static void ip6_mr_forward(struct net *net, struct mr6_table *mrt,
        vif = cache->mf6c_parent;
        cache->mfc_un.res.pkt++;
        cache->mfc_un.res.bytes += skb->len;
+       cache->mfc_un.res.lastuse = jiffies;
 
        if (ipv6_addr_any(&cache->mf6c_origin) && true_vifi >= 0) {
                struct mfc6_cache *cache_proxy;
@@ -2233,10 +2236,10 @@ int ip6_mr_input(struct sk_buff *skb)
 static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
                               struct mfc6_cache *c, struct rtmsg *rtm)
 {
-       int ct;
-       struct rtnexthop *nhp;
-       struct nlattr *mp_attr;
        struct rta_mfc_stats mfcs;
+       struct nlattr *mp_attr;
+       struct rtnexthop *nhp;
+       int ct;
 
        /* If cache is unresolved, don't try to parse IIF and OIF */
        if (c->mf6c_parent >= MAXMIFS)
@@ -2269,7 +2272,10 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
        mfcs.mfcs_packets = c->mfc_un.res.pkt;
        mfcs.mfcs_bytes = c->mfc_un.res.bytes;
        mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
-       if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) < 0)
+       if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
+           nla_put_u64_64bit(skb, RTA_EXPIRES,
+                             jiffies_to_clock_t(c->mfc_un.res.lastuse),
+                             RTA_PAD))
                return -EMSGSIZE;
 
        rtm->rtm_type = RTN_MULTICAST;