aboutsummaryrefslogtreecommitdiffstats
path: root/net/decnet/dn_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/decnet/dn_table.c')
-rw-r--r--net/decnet/dn_table.c76
1 files changed, 45 insertions, 31 deletions
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index 650f3380c98a..16c986ab1228 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -297,61 +297,75 @@ static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
297{ 297{
298 struct rtmsg *rtm; 298 struct rtmsg *rtm;
299 struct nlmsghdr *nlh; 299 struct nlmsghdr *nlh;
300 unsigned char *b = skb_tail_pointer(skb);
301 300
302 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags); 301 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
303 rtm = NLMSG_DATA(nlh); 302 if (!nlh)
303 return -EMSGSIZE;
304
305 rtm = nlmsg_data(nlh);
304 rtm->rtm_family = AF_DECnet; 306 rtm->rtm_family = AF_DECnet;
305 rtm->rtm_dst_len = dst_len; 307 rtm->rtm_dst_len = dst_len;
306 rtm->rtm_src_len = 0; 308 rtm->rtm_src_len = 0;
307 rtm->rtm_tos = 0; 309 rtm->rtm_tos = 0;
308 rtm->rtm_table = tb_id; 310 rtm->rtm_table = tb_id;
309 RTA_PUT_U32(skb, RTA_TABLE, tb_id);
310 rtm->rtm_flags = fi->fib_flags; 311 rtm->rtm_flags = fi->fib_flags;
311 rtm->rtm_scope = scope; 312 rtm->rtm_scope = scope;
312 rtm->rtm_type = type; 313 rtm->rtm_type = type;
313 if (rtm->rtm_dst_len)
314 RTA_PUT(skb, RTA_DST, 2, dst);
315 rtm->rtm_protocol = fi->fib_protocol; 314 rtm->rtm_protocol = fi->fib_protocol;
316 if (fi->fib_priority) 315
317 RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority); 316 if (nla_put_u32(skb, RTA_TABLE, tb_id) < 0)
317 goto errout;
318
319 if (rtm->rtm_dst_len &&
320 nla_put(skb, RTA_DST, 2, dst) < 0)
321 goto errout;
322
323 if (fi->fib_priority &&
324 nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority) < 0)
325 goto errout;
326
318 if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) 327 if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
319 goto rtattr_failure; 328 goto errout;
329
320 if (fi->fib_nhs == 1) { 330 if (fi->fib_nhs == 1) {
321 if (fi->fib_nh->nh_gw) 331 if (fi->fib_nh->nh_gw &&
322 RTA_PUT(skb, RTA_GATEWAY, 2, &fi->fib_nh->nh_gw); 332 nla_put_le16(skb, RTA_GATEWAY, fi->fib_nh->nh_gw) < 0)
323 if (fi->fib_nh->nh_oif) 333 goto errout;
324 RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif); 334
335 if (fi->fib_nh->nh_oif &&
336 nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif) < 0)
337 goto errout;
325 } 338 }
339
326 if (fi->fib_nhs > 1) { 340 if (fi->fib_nhs > 1) {
327 struct rtnexthop *nhp; 341 struct rtnexthop *nhp;
328 struct rtattr *mp_head; 342 struct nlattr *mp_head;
329 if (skb_tailroom(skb) <= RTA_SPACE(0)) 343
330 goto rtattr_failure; 344 if (!(mp_head = nla_nest_start(skb, RTA_MULTIPATH)))
331 mp_head = (struct rtattr *)skb_put(skb, RTA_SPACE(0)); 345 goto errout;
332 346
333 for_nexthops(fi) { 347 for_nexthops(fi) {
334 if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) 348 if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp))))
335 goto rtattr_failure; 349 goto errout;
336 nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); 350
337 nhp->rtnh_flags = nh->nh_flags & 0xFF; 351 nhp->rtnh_flags = nh->nh_flags & 0xFF;
338 nhp->rtnh_hops = nh->nh_weight - 1; 352 nhp->rtnh_hops = nh->nh_weight - 1;
339 nhp->rtnh_ifindex = nh->nh_oif; 353 nhp->rtnh_ifindex = nh->nh_oif;
340 if (nh->nh_gw) 354
341 RTA_PUT(skb, RTA_GATEWAY, 2, &nh->nh_gw); 355 if (nh->nh_gw &&
356 nla_put_le16(skb, RTA_GATEWAY, nh->nh_gw) < 0)
357 goto errout;
358
342 nhp->rtnh_len = skb_tail_pointer(skb) - (unsigned char *)nhp; 359 nhp->rtnh_len = skb_tail_pointer(skb) - (unsigned char *)nhp;
343 } endfor_nexthops(fi); 360 } endfor_nexthops(fi);
344 mp_head->rta_type = RTA_MULTIPATH;
345 mp_head->rta_len = skb_tail_pointer(skb) - (u8 *)mp_head;
346 }
347 361
348 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 362 nla_nest_end(skb, mp_head);
349 return skb->len; 363 }
350 364
365 return nlmsg_end(skb, nlh);
351 366
352nlmsg_failure: 367errout:
353rtattr_failure: 368 nlmsg_cancel(skb, nlh);
354 nlmsg_trim(skb, b);
355 return -EMSGSIZE; 369 return -EMSGSIZE;
356} 370}
357 371
@@ -476,7 +490,7 @@ int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
476 return 0; 490 return 0;
477 491
478 if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) && 492 if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
479 ((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED) 493 ((struct rtmsg *)nlmsg_data(cb->nlh))->rtm_flags&RTM_F_CLONED)
480 return dn_cache_dump(skb, cb); 494 return dn_cache_dump(skb, cb);
481 495
482 s_h = cb->args[0]; 496 s_h = cb->args[0];