]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv6/route.c
[PATCH] ext4 balloc: fix off-by-one against grp_goal
[linux-2.6-omap-h63xx.git] / net / ipv6 / route.c
index 0ad07c9087a75d8e0a6735665bb5cfaf1e8db3e1..9f80518aacbdf5069a10484c8235aec80ac0cbe6 100644 (file)
@@ -440,7 +440,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
        if (pref == ICMPV6_ROUTER_PREF_INVALID)
                pref = ICMPV6_ROUTER_PREF_MEDIUM;
 
-       lifetime = htonl(rinfo->lifetime);
+       lifetime = ntohl(rinfo->lifetime);
        if (lifetime == 0xffffffff) {
                /* infinity */
        } else if (lifetime > 0x7fffffff/HZ) {
@@ -2006,6 +2006,20 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        return ip6_route_add(&cfg);
 }
 
+static inline size_t rt6_nlmsg_size(void)
+{
+       return NLMSG_ALIGN(sizeof(struct rtmsg))
+              + nla_total_size(16) /* RTA_SRC */
+              + nla_total_size(16) /* RTA_DST */
+              + nla_total_size(16) /* RTA_GATEWAY */
+              + nla_total_size(16) /* RTA_PREFSRC */
+              + nla_total_size(4) /* RTA_TABLE */
+              + nla_total_size(4) /* RTA_IIF */
+              + nla_total_size(4) /* RTA_OIF */
+              + nla_total_size(4) /* RTA_PRIORITY */
+              + nla_total_size(sizeof(struct rta_cacheinfo));
+}
+
 static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
                         struct in6_addr *dst, struct in6_addr *src,
                         int iif, int type, u32 pid, u32 seq,
@@ -2013,7 +2027,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
 {
        struct rtmsg *rtm;
        struct nlmsghdr *nlh;
-       struct rta_cacheinfo ci;
+       long expires;
        u32 table;
 
        if (prefix) {   /* user wants prefix routes only */
@@ -2087,18 +2101,11 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
                NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
 
        NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
-       ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
-       if (rt->rt6i_expires)
-               ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies);
-       else
-               ci.rta_expires = 0;
-       ci.rta_used = rt->u.dst.__use;
-       ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt);
-       ci.rta_error = rt->u.dst.error;
-       ci.rta_id = 0;
-       ci.rta_ts = 0;
-       ci.rta_tsage = 0;
-       NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
+
+       expires = rt->rt6i_expires ? rt->rt6i_expires - jiffies : 0;
+       if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0,
+                              expires, rt->u.dst.error) < 0)
+               goto nla_put_failure;
 
        return nlmsg_end(skb, nlh);
 
@@ -2200,7 +2207,6 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
        struct sk_buff *skb;
        u32 pid = 0, seq = 0;
        struct nlmsghdr *nlh = NULL;
-       int payload = sizeof(struct rtmsg) + 256;
        int err = -ENOBUFS;
 
        if (info) {
@@ -2210,15 +2216,13 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
                        seq = nlh->nlmsg_seq;
        }
 
-       skb = nlmsg_new(nlmsg_total_size(payload), gfp_any());
+       skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
        if (skb == NULL)
                goto errout;
 
        err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
-       if (err < 0) {
-               kfree_skb(skb);
-               goto errout;
-       }
+       /* failure implies BUG in rt6_nlmsg_size() */
+       BUG_ON(err < 0);
 
        err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
 errout: