diff options
Diffstat (limited to 'net/decnet/dn_table.c')
-rw-r--r-- | net/decnet/dn_table.c | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 92ec7417a4d9..16c986ab1228 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -297,62 +297,75 @@ static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, { struct rtmsg *rtm; struct nlmsghdr *nlh; - unsigned char *b = skb_tail_pointer(skb); nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags); if (!nlh) - goto out_nlmsg_trim; + return -EMSGSIZE; + rtm = nlmsg_data(nlh); rtm->rtm_family = AF_DECnet; rtm->rtm_dst_len = dst_len; rtm->rtm_src_len = 0; rtm->rtm_tos = 0; rtm->rtm_table = tb_id; - RTA_PUT_U32(skb, RTA_TABLE, tb_id); rtm->rtm_flags = fi->fib_flags; rtm->rtm_scope = scope; rtm->rtm_type = type; - if (rtm->rtm_dst_len) - RTA_PUT(skb, RTA_DST, 2, dst); rtm->rtm_protocol = fi->fib_protocol; - if (fi->fib_priority) - RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority); + + if (nla_put_u32(skb, RTA_TABLE, tb_id) < 0) + goto errout; + + if (rtm->rtm_dst_len && + nla_put(skb, RTA_DST, 2, dst) < 0) + goto errout; + + if (fi->fib_priority && + nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority) < 0) + goto errout; + if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) - goto rtattr_failure; + goto errout; + if (fi->fib_nhs == 1) { - if (fi->fib_nh->nh_gw) - RTA_PUT(skb, RTA_GATEWAY, 2, &fi->fib_nh->nh_gw); - if (fi->fib_nh->nh_oif) - RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif); + if (fi->fib_nh->nh_gw && + nla_put_le16(skb, RTA_GATEWAY, fi->fib_nh->nh_gw) < 0) + goto errout; + + if (fi->fib_nh->nh_oif && + nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif) < 0) + goto errout; } + if (fi->fib_nhs > 1) { struct rtnexthop *nhp; - struct rtattr *mp_head; - if (skb_tailroom(skb) <= RTA_SPACE(0)) - goto rtattr_failure; - mp_head = (struct rtattr *)skb_put(skb, RTA_SPACE(0)); + struct nlattr *mp_head; + + if (!(mp_head = nla_nest_start(skb, RTA_MULTIPATH))) + goto errout; for_nexthops(fi) { - if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) - goto rtattr_failure; - nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); + if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp)))) + goto errout; + nhp->rtnh_flags = nh->nh_flags & 0xFF; nhp->rtnh_hops = nh->nh_weight - 1; nhp->rtnh_ifindex = nh->nh_oif; - if (nh->nh_gw) - RTA_PUT(skb, RTA_GATEWAY, 2, &nh->nh_gw); + + if (nh->nh_gw && + nla_put_le16(skb, RTA_GATEWAY, nh->nh_gw) < 0) + goto errout; + nhp->rtnh_len = skb_tail_pointer(skb) - (unsigned char *)nhp; } endfor_nexthops(fi); - mp_head->rta_type = RTA_MULTIPATH; - mp_head->rta_len = skb_tail_pointer(skb) - (u8 *)mp_head; + + nla_nest_end(skb, mp_head); } - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - return skb->len; + return nlmsg_end(skb, nlh); -out_nlmsg_trim: -rtattr_failure: - nlmsg_trim(skb, b); +errout: + nlmsg_cancel(skb, nlh); return -EMSGSIZE; } |