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/core/neighbour.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/core/neighbour.c')
-rw-r--r-- | net/core/neighbour.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index b4b478353b2..0e097ba14d7 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -2410,20 +2410,27 @@ static struct file_operations neigh_stat_seq_fops = { | |||
2410 | #endif /* CONFIG_PROC_FS */ | 2410 | #endif /* CONFIG_PROC_FS */ |
2411 | 2411 | ||
2412 | #ifdef CONFIG_ARPD | 2412 | #ifdef CONFIG_ARPD |
2413 | static inline size_t neigh_nlmsg_size(void) | ||
2414 | { | ||
2415 | return NLMSG_ALIGN(sizeof(struct ndmsg)) | ||
2416 | + nla_total_size(MAX_ADDR_LEN) /* NDA_DST */ | ||
2417 | + nla_total_size(MAX_ADDR_LEN) /* NDA_LLADDR */ | ||
2418 | + nla_total_size(sizeof(struct nda_cacheinfo)) | ||
2419 | + nla_total_size(4); /* NDA_PROBES */ | ||
2420 | } | ||
2421 | |||
2413 | static void __neigh_notify(struct neighbour *n, int type, int flags) | 2422 | static void __neigh_notify(struct neighbour *n, int type, int flags) |
2414 | { | 2423 | { |
2415 | struct sk_buff *skb; | 2424 | struct sk_buff *skb; |
2416 | int err = -ENOBUFS; | 2425 | int err = -ENOBUFS; |
2417 | 2426 | ||
2418 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); | 2427 | skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC); |
2419 | if (skb == NULL) | 2428 | if (skb == NULL) |
2420 | goto errout; | 2429 | goto errout; |
2421 | 2430 | ||
2422 | err = neigh_fill_info(skb, n, 0, 0, type, flags); | 2431 | err = neigh_fill_info(skb, n, 0, 0, type, flags); |
2423 | if (err < 0) { | 2432 | /* failure implies BUG in neigh_nlmsg_size() */ |
2424 | kfree_skb(skb); | 2433 | BUG_ON(err < 0); |
2425 | goto errout; | ||
2426 | } | ||
2427 | 2434 | ||
2428 | err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); | 2435 | err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); |
2429 | errout: | 2436 | errout: |