aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/rtnetlink.c31
-rw-r--r--net/ipv6/route.c52
2 files changed, 46 insertions, 37 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index dfc58269240a..eeff0b23e944 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -188,22 +188,27 @@ void rtnl_set_sk_err(u32 group, int error)
188 188
189int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics) 189int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics)
190{ 190{
191 struct rtattr *mx = (struct rtattr*)skb->tail; 191 struct nlattr *mx;
192 int i; 192 int i, valid = 0;
193
194 mx = nla_nest_start(skb, RTA_METRICS);
195 if (mx == NULL)
196 return -ENOBUFS;
193 197
194 RTA_PUT(skb, RTA_METRICS, 0, NULL); 198 for (i = 0; i < RTAX_MAX; i++) {
195 for (i=0; i<RTAX_MAX; i++) { 199 if (metrics[i]) {
196 if (metrics[i]) 200 valid++;
197 RTA_PUT(skb, i+1, sizeof(u32), metrics+i); 201 NLA_PUT_U32(skb, i+1, metrics[i]);
202 }
198 } 203 }
199 mx->rta_len = skb->tail - (u8*)mx;
200 if (mx->rta_len == RTA_LENGTH(0))
201 skb_trim(skb, (u8*)mx - skb->data);
202 return 0;
203 204
204rtattr_failure: 205 if (!valid)
205 skb_trim(skb, (u8*)mx - skb->data); 206 goto nla_put_failure;
206 return -1; 207
208 return nla_nest_end(skb, mx);
209
210nla_put_failure:
211 return nla_nest_cancel(skb, mx);
207} 212}
208 213
209 214
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 7bcffa6ddba3..f0a66de84331 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1936,8 +1936,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1936 int prefix, unsigned int flags) 1936 int prefix, unsigned int flags)
1937{ 1937{
1938 struct rtmsg *rtm; 1938 struct rtmsg *rtm;
1939 struct nlmsghdr *nlh; 1939 struct nlmsghdr *nlh;
1940 unsigned char *b = skb->tail;
1941 struct rta_cacheinfo ci; 1940 struct rta_cacheinfo ci;
1942 u32 table; 1941 u32 table;
1943 1942
@@ -1948,8 +1947,11 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1948 } 1947 }
1949 } 1948 }
1950 1949
1951 nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags); 1950 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags);
1952 rtm = NLMSG_DATA(nlh); 1951 if (nlh == NULL)
1952 return -ENOBUFS;
1953
1954 rtm = nlmsg_data(nlh);
1953 rtm->rtm_family = AF_INET6; 1955 rtm->rtm_family = AF_INET6;
1954 rtm->rtm_dst_len = rt->rt6i_dst.plen; 1956 rtm->rtm_dst_len = rt->rt6i_dst.plen;
1955 rtm->rtm_src_len = rt->rt6i_src.plen; 1957 rtm->rtm_src_len = rt->rt6i_src.plen;
@@ -1959,7 +1961,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1959 else 1961 else
1960 table = RT6_TABLE_UNSPEC; 1962 table = RT6_TABLE_UNSPEC;
1961 rtm->rtm_table = table; 1963 rtm->rtm_table = table;
1962 RTA_PUT_U32(skb, RTA_TABLE, table); 1964 NLA_PUT_U32(skb, RTA_TABLE, table);
1963 if (rt->rt6i_flags&RTF_REJECT) 1965 if (rt->rt6i_flags&RTF_REJECT)
1964 rtm->rtm_type = RTN_UNREACHABLE; 1966 rtm->rtm_type = RTN_UNREACHABLE;
1965 else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) 1967 else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK))
@@ -1980,31 +1982,35 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1980 rtm->rtm_flags |= RTM_F_CLONED; 1982 rtm->rtm_flags |= RTM_F_CLONED;
1981 1983
1982 if (dst) { 1984 if (dst) {
1983 RTA_PUT(skb, RTA_DST, 16, dst); 1985 NLA_PUT(skb, RTA_DST, 16, dst);
1984 rtm->rtm_dst_len = 128; 1986 rtm->rtm_dst_len = 128;
1985 } else if (rtm->rtm_dst_len) 1987 } else if (rtm->rtm_dst_len)
1986 RTA_PUT(skb, RTA_DST, 16, &rt->rt6i_dst.addr); 1988 NLA_PUT(skb, RTA_DST, 16, &rt->rt6i_dst.addr);
1987#ifdef CONFIG_IPV6_SUBTREES 1989#ifdef CONFIG_IPV6_SUBTREES
1988 if (src) { 1990 if (src) {
1989 RTA_PUT(skb, RTA_SRC, 16, src); 1991 NLA_PUT(skb, RTA_SRC, 16, src);
1990 rtm->rtm_src_len = 128; 1992 rtm->rtm_src_len = 128;
1991 } else if (rtm->rtm_src_len) 1993 } else if (rtm->rtm_src_len)
1992 RTA_PUT(skb, RTA_SRC, 16, &rt->rt6i_src.addr); 1994 NLA_PUT(skb, RTA_SRC, 16, &rt->rt6i_src.addr);
1993#endif 1995#endif
1994 if (iif) 1996 if (iif)
1995 RTA_PUT(skb, RTA_IIF, 4, &iif); 1997 NLA_PUT_U32(skb, RTA_IIF, iif);
1996 else if (dst) { 1998 else if (dst) {
1997 struct in6_addr saddr_buf; 1999 struct in6_addr saddr_buf;
1998 if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0) 2000 if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0)
1999 RTA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); 2001 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
2000 } 2002 }
2003
2001 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) 2004 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
2002 goto rtattr_failure; 2005 goto nla_put_failure;
2006
2003 if (rt->u.dst.neighbour) 2007 if (rt->u.dst.neighbour)
2004 RTA_PUT(skb, RTA_GATEWAY, 16, &rt->u.dst.neighbour->primary_key); 2008 NLA_PUT(skb, RTA_GATEWAY, 16, &rt->u.dst.neighbour->primary_key);
2009
2005 if (rt->u.dst.dev) 2010 if (rt->u.dst.dev)
2006 RTA_PUT(skb, RTA_OIF, sizeof(int), &rt->rt6i_dev->ifindex); 2011 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
2007 RTA_PUT(skb, RTA_PRIORITY, 4, &rt->rt6i_metric); 2012
2013 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
2008 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 2014 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
2009 if (rt->rt6i_expires) 2015 if (rt->rt6i_expires)
2010 ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies); 2016 ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies);
@@ -2016,14 +2022,12 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2016 ci.rta_id = 0; 2022 ci.rta_id = 0;
2017 ci.rta_ts = 0; 2023 ci.rta_ts = 0;
2018 ci.rta_tsage = 0; 2024 ci.rta_tsage = 0;
2019 RTA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci); 2025 NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
2020 nlh->nlmsg_len = skb->tail - b; 2026
2021 return skb->len; 2027 return nlmsg_end(skb, nlh);
2022 2028
2023nlmsg_failure: 2029nla_put_failure:
2024rtattr_failure: 2030 return nlmsg_cancel(skb, nlh);
2025 skb_trim(skb, b - skb->data);
2026 return -1;
2027} 2031}
2028 2032
2029int rt6_dump_route(struct rt6_info *rt, void *p_arg) 2033int rt6_dump_route(struct rt6_info *rt, void *p_arg)
@@ -2031,8 +2035,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
2031 struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg; 2035 struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg;
2032 int prefix; 2036 int prefix;
2033 2037
2034 if (arg->cb->nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(struct rtmsg))) { 2038 if (nlmsg_len(arg->cb->nlh) >= sizeof(struct rtmsg)) {
2035 struct rtmsg *rtm = NLMSG_DATA(arg->cb->nlh); 2039 struct rtmsg *rtm = nlmsg_data(arg->cb->nlh);
2036 prefix = (rtm->rtm_flags & RTM_F_PREFIX) != 0; 2040 prefix = (rtm->rtm_flags & RTM_F_PREFIX) != 0;
2037 } else 2041 } else
2038 prefix = 0; 2042 prefix = 0;