aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/rtnetlink.h3
-rw-r--r--net/core/rtnetlink.c20
-rw-r--r--net/decnet/dn_route.c16
-rw-r--r--net/ipv4/route.c26
-rw-r--r--net/ipv6/route.c19
5 files changed, 45 insertions, 39 deletions
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 33b3d0ab3a91..493297acdae8 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -585,6 +585,9 @@ extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
585 struct nlmsghdr *nlh, gfp_t flags); 585 struct nlmsghdr *nlh, gfp_t flags);
586extern void rtnl_set_sk_err(u32 group, int error); 586extern void rtnl_set_sk_err(u32 group, int error);
587extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics); 587extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
588extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
589 u32 id, u32 ts, u32 tsage, long expires,
590 u32 error);
588 591
589extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data); 592extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data);
590 593
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 0cb4d9e53a07..e76539a5eb5e 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -212,6 +212,26 @@ nla_put_failure:
212 return nla_nest_cancel(skb, mx); 212 return nla_nest_cancel(skb, mx);
213} 213}
214 214
215int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id,
216 u32 ts, u32 tsage, long expires, u32 error)
217{
218 struct rta_cacheinfo ci = {
219 .rta_lastuse = jiffies_to_clock_t(jiffies - dst->lastuse),
220 .rta_used = dst->__use,
221 .rta_clntref = atomic_read(&(dst->__refcnt)),
222 .rta_error = error,
223 .rta_id = id,
224 .rta_ts = ts,
225 .rta_tsage = tsage,
226 };
227
228 if (expires)
229 ci.rta_expires = jiffies_to_clock_t(expires);
230
231 return nla_put(skb, RTA_CACHEINFO, sizeof(ci), &ci);
232}
233
234EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
215 235
216static void set_operstate(struct net_device *dev, unsigned char transition) 236static void set_operstate(struct net_device *dev, unsigned char transition)
217{ 237{
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 4eb985236aee..9881933167bd 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1469,7 +1469,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
1469 struct rtmsg *r; 1469 struct rtmsg *r;
1470 struct nlmsghdr *nlh; 1470 struct nlmsghdr *nlh;
1471 unsigned char *b = skb->tail; 1471 unsigned char *b = skb->tail;
1472 struct rta_cacheinfo ci; 1472 long expires;
1473 1473
1474 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); 1474 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
1475 r = NLMSG_DATA(nlh); 1475 r = NLMSG_DATA(nlh);
@@ -1502,16 +1502,10 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
1502 RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway); 1502 RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway);
1503 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) 1503 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
1504 goto rtattr_failure; 1504 goto rtattr_failure;
1505 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 1505 expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0;
1506 ci.rta_used = rt->u.dst.__use; 1506 if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, expires,
1507 ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt); 1507 rt->u.dst.error) < 0)
1508 if (rt->u.dst.expires) 1508 goto rtattr_failure;
1509 ci.rta_expires = jiffies_to_clock_t(rt->u.dst.expires - jiffies);
1510 else
1511 ci.rta_expires = 0;
1512 ci.rta_error = rt->u.dst.error;
1513 ci.rta_id = ci.rta_ts = ci.rta_tsage = 0;
1514 RTA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
1515 if (rt->fl.iif) 1509 if (rt->fl.iif)
1516 RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); 1510 RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif);
1517 1511
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ee00b6506ab4..9f3924c4905e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2629,7 +2629,8 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2629 struct rtable *rt = (struct rtable*)skb->dst; 2629 struct rtable *rt = (struct rtable*)skb->dst;
2630 struct rtmsg *r; 2630 struct rtmsg *r;
2631 struct nlmsghdr *nlh; 2631 struct nlmsghdr *nlh;
2632 struct rta_cacheinfo ci; 2632 long expires;
2633 u32 id = 0, ts = 0, tsage = 0, error;
2633 2634
2634 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); 2635 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
2635 if (nlh == NULL) 2636 if (nlh == NULL)
@@ -2676,20 +2677,13 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2676 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) 2677 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
2677 goto nla_put_failure; 2678 goto nla_put_failure;
2678 2679
2679 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 2680 error = rt->u.dst.error;
2680 ci.rta_used = rt->u.dst.__use; 2681 expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0;
2681 ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt);
2682 if (rt->u.dst.expires)
2683 ci.rta_expires = jiffies_to_clock_t(rt->u.dst.expires - jiffies);
2684 else
2685 ci.rta_expires = 0;
2686 ci.rta_error = rt->u.dst.error;
2687 ci.rta_id = ci.rta_ts = ci.rta_tsage = 0;
2688 if (rt->peer) { 2682 if (rt->peer) {
2689 ci.rta_id = rt->peer->ip_id_count; 2683 id = rt->peer->ip_id_count;
2690 if (rt->peer->tcp_ts_stamp) { 2684 if (rt->peer->tcp_ts_stamp) {
2691 ci.rta_ts = rt->peer->tcp_ts; 2685 ts = rt->peer->tcp_ts;
2692 ci.rta_tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp; 2686 tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp;
2693 } 2687 }
2694 } 2688 }
2695 2689
@@ -2708,7 +2702,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2708 } else { 2702 } else {
2709 if (err == -EMSGSIZE) 2703 if (err == -EMSGSIZE)
2710 goto nla_put_failure; 2704 goto nla_put_failure;
2711 ci.rta_error = err; 2705 error = err;
2712 } 2706 }
2713 } 2707 }
2714 } else 2708 } else
@@ -2716,7 +2710,9 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2716 NLA_PUT_U32(skb, RTA_IIF, rt->fl.iif); 2710 NLA_PUT_U32(skb, RTA_IIF, rt->fl.iif);
2717 } 2711 }
2718 2712
2719 NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci); 2713 if (rtnl_put_cacheinfo(skb, &rt->u.dst, id, ts, tsage,
2714 expires, error) < 0)
2715 goto nla_put_failure;
2720 2716
2721 return nlmsg_end(skb, nlh); 2717 return nlmsg_end(skb, nlh);
2722 2718
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 0bf17a3cf085..9f80518aacbd 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2027,7 +2027,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2027{ 2027{
2028 struct rtmsg *rtm; 2028 struct rtmsg *rtm;
2029 struct nlmsghdr *nlh; 2029 struct nlmsghdr *nlh;
2030 struct rta_cacheinfo ci; 2030 long expires;
2031 u32 table; 2031 u32 table;
2032 2032
2033 if (prefix) { /* user wants prefix routes only */ 2033 if (prefix) { /* user wants prefix routes only */
@@ -2101,18 +2101,11 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2101 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); 2101 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
2102 2102
2103 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); 2103 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
2104 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 2104
2105 if (rt->rt6i_expires) 2105 expires = rt->rt6i_expires ? rt->rt6i_expires - jiffies : 0;
2106 ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies); 2106 if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0,
2107 else 2107 expires, rt->u.dst.error) < 0)
2108 ci.rta_expires = 0; 2108 goto nla_put_failure;
2109 ci.rta_used = rt->u.dst.__use;
2110 ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt);
2111 ci.rta_error = rt->u.dst.error;
2112 ci.rta_id = 0;
2113 ci.rta_ts = 0;
2114 ci.rta_tsage = 0;
2115 NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
2116 2109
2117 return nlmsg_end(skb, nlh); 2110 return nlmsg_end(skb, nlh);
2118 2111