diff options
author | Thomas Graf <tgraf@suug.ch> | 2006-11-10 17:10:15 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:22:11 -0500 |
commit | 339bf98ffc6a8d8eb16fc532ac57ffbced2f8a68 (patch) | |
tree | 499ad948863d2753ca10283dcf006ad28954538e /net/ipv6/route.c | |
parent | a94f723d595ee085f81b1788d18e031af7eeba91 (diff) |
[NETLINK]: Do precise netlink message allocations where possible
Account for the netlink message header size directly in nlmsg_new()
instead of relying on the caller calculate it correctly.
Replaces error handling of message construction functions when
constructing notifications with bug traps since a failure implies
a bug in calculating the size of the skb.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Acked-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 0ad07c9087a7..a6472cb9054c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2006,6 +2006,20 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
2006 | return ip6_route_add(&cfg); | 2006 | return ip6_route_add(&cfg); |
2007 | } | 2007 | } |
2008 | 2008 | ||
2009 | static inline size_t rt6_nlmsg_size(void) | ||
2010 | { | ||
2011 | return NLMSG_ALIGN(sizeof(struct rtmsg)) | ||
2012 | + nla_total_size(16) /* RTA_SRC */ | ||
2013 | + nla_total_size(16) /* RTA_DST */ | ||
2014 | + nla_total_size(16) /* RTA_GATEWAY */ | ||
2015 | + nla_total_size(16) /* RTA_PREFSRC */ | ||
2016 | + nla_total_size(4) /* RTA_TABLE */ | ||
2017 | + nla_total_size(4) /* RTA_IIF */ | ||
2018 | + nla_total_size(4) /* RTA_OIF */ | ||
2019 | + nla_total_size(4) /* RTA_PRIORITY */ | ||
2020 | + nla_total_size(sizeof(struct rta_cacheinfo)); | ||
2021 | } | ||
2022 | |||
2009 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | 2023 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, |
2010 | struct in6_addr *dst, struct in6_addr *src, | 2024 | struct in6_addr *dst, struct in6_addr *src, |
2011 | int iif, int type, u32 pid, u32 seq, | 2025 | int iif, int type, u32 pid, u32 seq, |
@@ -2200,7 +2214,6 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) | |||
2200 | struct sk_buff *skb; | 2214 | struct sk_buff *skb; |
2201 | u32 pid = 0, seq = 0; | 2215 | u32 pid = 0, seq = 0; |
2202 | struct nlmsghdr *nlh = NULL; | 2216 | struct nlmsghdr *nlh = NULL; |
2203 | int payload = sizeof(struct rtmsg) + 256; | ||
2204 | int err = -ENOBUFS; | 2217 | int err = -ENOBUFS; |
2205 | 2218 | ||
2206 | if (info) { | 2219 | if (info) { |
@@ -2210,15 +2223,13 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) | |||
2210 | seq = nlh->nlmsg_seq; | 2223 | seq = nlh->nlmsg_seq; |
2211 | } | 2224 | } |
2212 | 2225 | ||
2213 | skb = nlmsg_new(nlmsg_total_size(payload), gfp_any()); | 2226 | skb = nlmsg_new(rt6_nlmsg_size(), gfp_any()); |
2214 | if (skb == NULL) | 2227 | if (skb == NULL) |
2215 | goto errout; | 2228 | goto errout; |
2216 | 2229 | ||
2217 | err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); | 2230 | err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); |
2218 | if (err < 0) { | 2231 | /* failure implies BUG in rt6_nlmsg_size() */ |
2219 | kfree_skb(skb); | 2232 | BUG_ON(err < 0); |
2220 | goto errout; | ||
2221 | } | ||
2222 | 2233 | ||
2223 | err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); | 2234 | err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); |
2224 | errout: | 2235 | errout: |