diff options
-rw-r--r-- | include/linux/netlink.h | 1 | ||||
-rw-r--r-- | include/net/fib_rules.h | 1 | ||||
-rw-r--r-- | include/net/netlink.h | 9 | ||||
-rw-r--r-- | kernel/taskstats.c | 3 | ||||
-rw-r--r-- | net/bridge/br_netlink.c | 21 | ||||
-rw-r--r-- | net/core/fib_rules.c | 24 | ||||
-rw-r--r-- | net/core/neighbour.c | 17 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 39 | ||||
-rw-r--r-- | net/decnet/dn_rules.c | 6 | ||||
-rw-r--r-- | net/decnet/dn_table.c | 34 | ||||
-rw-r--r-- | net/ipv4/devinet.c | 18 | ||||
-rw-r--r-- | net/ipv4/fib_rules.c | 8 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 36 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 70 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 7 | ||||
-rw-r--r-- | net/ipv6/route.c | 23 | ||||
-rw-r--r-- | net/netlabel/netlabel_cipso_v4.c | 2 | ||||
-rw-r--r-- | net/netlabel/netlabel_mgmt.c | 4 | ||||
-rw-r--r-- | net/netlabel/netlabel_unlabeled.c | 2 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 13 | ||||
-rw-r--r-- | net/netlink/genetlink.c | 2 |
21 files changed, 233 insertions, 107 deletions
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 66411622e06e..e61e1e138421 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -174,6 +174,7 @@ int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol); | |||
174 | */ | 174 | */ |
175 | #define NLMSG_GOODORDER 0 | 175 | #define NLMSG_GOODORDER 0 |
176 | #define NLMSG_GOODSIZE (SKB_MAX_ORDER(0, NLMSG_GOODORDER)) | 176 | #define NLMSG_GOODSIZE (SKB_MAX_ORDER(0, NLMSG_GOODORDER)) |
177 | #define NLMSG_DEFAULT_SIZE (NLMSG_GOODSIZE - NLMSG_HDRLEN) | ||
177 | 178 | ||
178 | 179 | ||
179 | struct netlink_callback | 180 | struct netlink_callback |
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index e4ba781d289f..bc3c26494c3d 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h | |||
@@ -52,6 +52,7 @@ struct fib_rules_ops | |||
52 | struct nlmsghdr *, | 52 | struct nlmsghdr *, |
53 | struct fib_rule_hdr *); | 53 | struct fib_rule_hdr *); |
54 | u32 (*default_pref)(void); | 54 | u32 (*default_pref)(void); |
55 | size_t (*nlmsg_payload)(struct fib_rule *); | ||
55 | 56 | ||
56 | int nlgroup; | 57 | int nlgroup; |
57 | struct nla_policy *policy; | 58 | struct nla_policy *policy; |
diff --git a/include/net/netlink.h b/include/net/netlink.h index ce5cba19c393..30021339157c 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h | |||
@@ -500,14 +500,15 @@ static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb, | |||
500 | 500 | ||
501 | /** | 501 | /** |
502 | * nlmsg_new - Allocate a new netlink message | 502 | * nlmsg_new - Allocate a new netlink message |
503 | * @size: maximum size of message | 503 | * @payload: size of the message payload |
504 | * @flags: the type of memory to allocate. | 504 | * @flags: the type of memory to allocate. |
505 | * | 505 | * |
506 | * Use NLMSG_GOODSIZE if size isn't know and you need a good default size. | 506 | * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known |
507 | * and a good default is needed. | ||
507 | */ | 508 | */ |
508 | static inline struct sk_buff *nlmsg_new(int size, gfp_t flags) | 509 | static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags) |
509 | { | 510 | { |
510 | return alloc_skb(size, flags); | 511 | return alloc_skb(nlmsg_total_size(payload), flags); |
511 | } | 512 | } |
512 | 513 | ||
513 | /** | 514 | /** |
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index f45c5e70773c..4f3f0e48c845 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
@@ -77,8 +77,7 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp, | |||
77 | /* | 77 | /* |
78 | * If new attributes are added, please revisit this allocation | 78 | * If new attributes are added, please revisit this allocation |
79 | */ | 79 | */ |
80 | size = nlmsg_total_size(genlmsg_total_size(size)); | 80 | skb = nlmsg_new(genlmsg_total_size(size), GFP_KERNEL); |
81 | skb = nlmsg_new(size, GFP_KERNEL); | ||
82 | if (!skb) | 81 | if (!skb) |
83 | return -ENOMEM; | 82 | return -ENOMEM; |
84 | 83 | ||
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 8f661195d09d..15d6efbe7519 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -15,6 +15,18 @@ | |||
15 | #include <net/netlink.h> | 15 | #include <net/netlink.h> |
16 | #include "br_private.h" | 16 | #include "br_private.h" |
17 | 17 | ||
18 | static inline size_t br_nlmsg_size(void) | ||
19 | { | ||
20 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) | ||
21 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ | ||
22 | + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ | ||
23 | + nla_total_size(4) /* IFLA_MASTER */ | ||
24 | + nla_total_size(4) /* IFLA_MTU */ | ||
25 | + nla_total_size(4) /* IFLA_LINK */ | ||
26 | + nla_total_size(1) /* IFLA_OPERSTATE */ | ||
27 | + nla_total_size(1); /* IFLA_PROTINFO */ | ||
28 | } | ||
29 | |||
18 | /* | 30 | /* |
19 | * Create one netlink message for one interface | 31 | * Create one netlink message for one interface |
20 | * Contains port and master info as well as carrier and bridge state. | 32 | * Contains port and master info as well as carrier and bridge state. |
@@ -77,19 +89,16 @@ rtattr_failure: | |||
77 | void br_ifinfo_notify(int event, struct net_bridge_port *port) | 89 | void br_ifinfo_notify(int event, struct net_bridge_port *port) |
78 | { | 90 | { |
79 | struct sk_buff *skb; | 91 | struct sk_buff *skb; |
80 | int payload = sizeof(struct ifinfomsg) + 128; | ||
81 | int err = -ENOBUFS; | 92 | int err = -ENOBUFS; |
82 | 93 | ||
83 | pr_debug("bridge notify event=%d\n", event); | 94 | pr_debug("bridge notify event=%d\n", event); |
84 | skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); | 95 | skb = nlmsg_new(br_nlmsg_size(), GFP_ATOMIC); |
85 | if (skb == NULL) | 96 | if (skb == NULL) |
86 | goto errout; | 97 | goto errout; |
87 | 98 | ||
88 | err = br_fill_ifinfo(skb, port, 0, 0, event, 0); | 99 | err = br_fill_ifinfo(skb, port, 0, 0, event, 0); |
89 | if (err < 0) { | 100 | /* failure implies BUG in br_nlmsg_size() */ |
90 | kfree_skb(skb); | 101 | BUG_ON(err < 0); |
91 | goto errout; | ||
92 | } | ||
93 | 102 | ||
94 | err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); | 103 | err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); |
95 | errout: | 104 | errout: |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 4148e274a204..1df6cd4568d3 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -306,6 +306,22 @@ errout: | |||
306 | return err; | 306 | return err; |
307 | } | 307 | } |
308 | 308 | ||
309 | static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops, | ||
310 | struct fib_rule *rule) | ||
311 | { | ||
312 | size_t payload = NLMSG_ALIGN(sizeof(struct fib_rule_hdr)) | ||
313 | + nla_total_size(IFNAMSIZ) /* FRA_IFNAME */ | ||
314 | + nla_total_size(4) /* FRA_PRIORITY */ | ||
315 | + nla_total_size(4) /* FRA_TABLE */ | ||
316 | + nla_total_size(4) /* FRA_FWMARK */ | ||
317 | + nla_total_size(4); /* FRA_FWMASK */ | ||
318 | |||
319 | if (ops->nlmsg_payload) | ||
320 | payload += ops->nlmsg_payload(rule); | ||
321 | |||
322 | return payload; | ||
323 | } | ||
324 | |||
309 | static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, | 325 | static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, |
310 | u32 pid, u32 seq, int type, int flags, | 326 | u32 pid, u32 seq, int type, int flags, |
311 | struct fib_rules_ops *ops) | 327 | struct fib_rules_ops *ops) |
@@ -384,15 +400,13 @@ static void notify_rule_change(int event, struct fib_rule *rule, | |||
384 | struct sk_buff *skb; | 400 | struct sk_buff *skb; |
385 | int err = -ENOBUFS; | 401 | int err = -ENOBUFS; |
386 | 402 | ||
387 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 403 | skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL); |
388 | if (skb == NULL) | 404 | if (skb == NULL) |
389 | goto errout; | 405 | goto errout; |
390 | 406 | ||
391 | err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); | 407 | err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); |
392 | if (err < 0) { | 408 | /* failure implies BUG in fib_rule_nlmsg_size() */ |
393 | kfree_skb(skb); | 409 | BUG_ON(err < 0); |
394 | goto errout; | ||
395 | } | ||
396 | 410 | ||
397 | err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL); | 411 | err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL); |
398 | errout: | 412 | errout: |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index b4b478353b27..0e097ba14d73 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: |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 02f3c7947898..50d6cb40c6e3 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -273,6 +273,25 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | |||
273 | a->tx_compressed = b->tx_compressed; | 273 | a->tx_compressed = b->tx_compressed; |
274 | }; | 274 | }; |
275 | 275 | ||
276 | static inline size_t if_nlmsg_size(int iwbuflen) | ||
277 | { | ||
278 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) | ||
279 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ | ||
280 | + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */ | ||
281 | + nla_total_size(sizeof(struct rtnl_link_ifmap)) | ||
282 | + nla_total_size(sizeof(struct rtnl_link_stats)) | ||
283 | + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ | ||
284 | + nla_total_size(MAX_ADDR_LEN) /* IFLA_BROADCAST */ | ||
285 | + nla_total_size(4) /* IFLA_TXQLEN */ | ||
286 | + nla_total_size(4) /* IFLA_WEIGHT */ | ||
287 | + nla_total_size(4) /* IFLA_MTU */ | ||
288 | + nla_total_size(4) /* IFLA_LINK */ | ||
289 | + nla_total_size(4) /* IFLA_MASTER */ | ||
290 | + nla_total_size(1) /* IFLA_OPERSTATE */ | ||
291 | + nla_total_size(1) /* IFLA_LINKMODE */ | ||
292 | + nla_total_size(iwbuflen); | ||
293 | } | ||
294 | |||
276 | static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | 295 | static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, |
277 | void *iwbuf, int iwbuflen, int type, u32 pid, | 296 | void *iwbuf, int iwbuflen, int type, u32 pid, |
278 | u32 seq, u32 change, unsigned int flags) | 297 | u32 seq, u32 change, unsigned int flags) |
@@ -558,7 +577,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
558 | struct sk_buff *nskb; | 577 | struct sk_buff *nskb; |
559 | char *iw_buf = NULL, *iw = NULL; | 578 | char *iw_buf = NULL, *iw = NULL; |
560 | int iw_buf_len = 0; | 579 | int iw_buf_len = 0; |
561 | int err, payload; | 580 | int err; |
562 | 581 | ||
563 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); | 582 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); |
564 | if (err < 0) | 583 | if (err < 0) |
@@ -587,9 +606,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
587 | } | 606 | } |
588 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ | 607 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ |
589 | 608 | ||
590 | payload = NLMSG_ALIGN(sizeof(struct ifinfomsg) + | 609 | nskb = nlmsg_new(if_nlmsg_size(iw_buf_len), GFP_KERNEL); |
591 | nla_total_size(iw_buf_len)); | ||
592 | nskb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL); | ||
593 | if (nskb == NULL) { | 610 | if (nskb == NULL) { |
594 | err = -ENOBUFS; | 611 | err = -ENOBUFS; |
595 | goto errout; | 612 | goto errout; |
@@ -597,10 +614,8 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
597 | 614 | ||
598 | err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK, | 615 | err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK, |
599 | NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0); | 616 | NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0); |
600 | if (err <= 0) { | 617 | /* failure impilies BUG in if_nlmsg_size or wireless_rtnetlink_get */ |
601 | kfree_skb(nskb); | 618 | BUG_ON(err < 0); |
602 | goto errout; | ||
603 | } | ||
604 | 619 | ||
605 | err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); | 620 | err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); |
606 | errout: | 621 | errout: |
@@ -639,15 +654,13 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) | |||
639 | struct sk_buff *skb; | 654 | struct sk_buff *skb; |
640 | int err = -ENOBUFS; | 655 | int err = -ENOBUFS; |
641 | 656 | ||
642 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 657 | skb = nlmsg_new(if_nlmsg_size(0), GFP_KERNEL); |
643 | if (skb == NULL) | 658 | if (skb == NULL) |
644 | goto errout; | 659 | goto errout; |
645 | 660 | ||
646 | err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0); | 661 | err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0); |
647 | if (err < 0) { | 662 | /* failure implies BUG in if_nlmsg_size() */ |
648 | kfree_skb(skb); | 663 | BUG_ON(err < 0); |
649 | goto errout; | ||
650 | } | ||
651 | 664 | ||
652 | err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); | 665 | err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); |
653 | errout: | 666 | errout: |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index e32d0c3d5a96..b7dfd04a9638 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -241,6 +241,12 @@ static u32 dn_fib_rule_default_pref(void) | |||
241 | return 0; | 241 | return 0; |
242 | } | 242 | } |
243 | 243 | ||
244 | static size_t dn_fib_rule_nlmsg_payload(struct fib_rule *rule) | ||
245 | { | ||
246 | return nla_total_size(2) /* dst */ | ||
247 | + nla_total_size(2); /* src */ | ||
248 | } | ||
249 | |||
244 | int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb) | 250 | int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb) |
245 | { | 251 | { |
246 | return fib_rules_dump(skb, cb, AF_DECnet); | 252 | return fib_rules_dump(skb, cb, AF_DECnet); |
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 317904bb5896..e74b744254ab 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c | |||
@@ -263,6 +263,32 @@ static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct dn_kern | |||
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
265 | 265 | ||
266 | static inline size_t dn_fib_nlmsg_size(struct dn_fib_info *fi) | ||
267 | { | ||
268 | size_t payload = NLMSG_ALIGN(struct rtmsg) | ||
269 | + nla_total_size(4) /* RTA_TABLE */ | ||
270 | + nla_total_size(2) /* RTA_DST */ | ||
271 | + nla_total_size(4); /* RTA_PRIORITY */ | ||
272 | |||
273 | /* space for nested metrics */ | ||
274 | payload += nla_total_size((RTAX_MAX * nla_total_size(4))); | ||
275 | |||
276 | if (fi->fib_nhs) { | ||
277 | /* Also handles the special case fib_nhs == 1 */ | ||
278 | |||
279 | /* each nexthop is packed in an attribute */ | ||
280 | size_t nhsize = nla_total_size(sizeof(struct rtnexthop)); | ||
281 | |||
282 | /* may contain a gateway attribute */ | ||
283 | nhsize += nla_total_size(4); | ||
284 | |||
285 | /* all nexthops are packed in a nested attribute */ | ||
286 | payload += nla_total_size(fi->fib_nhs * nhsize); | ||
287 | } | ||
288 | |||
289 | return payload; | ||
290 | } | ||
291 | |||
266 | static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | 292 | static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, |
267 | u32 tb_id, u8 type, u8 scope, void *dst, int dst_len, | 293 | u32 tb_id, u8 type, u8 scope, void *dst, int dst_len, |
268 | struct dn_fib_info *fi, unsigned int flags) | 294 | struct dn_fib_info *fi, unsigned int flags) |
@@ -335,17 +361,15 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id, | |||
335 | u32 pid = req ? req->pid : 0; | 361 | u32 pid = req ? req->pid : 0; |
336 | int err = -ENOBUFS; | 362 | int err = -ENOBUFS; |
337 | 363 | ||
338 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 364 | skb = nlmsg_new(dn_fib_nlmsg_size(DN_FIB_INFO(f), GFP_KERNEL)); |
339 | if (skb == NULL) | 365 | if (skb == NULL) |
340 | goto errout; | 366 | goto errout; |
341 | 367 | ||
342 | err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, | 368 | err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, |
343 | f->fn_type, f->fn_scope, &f->fn_key, z, | 369 | f->fn_type, f->fn_scope, &f->fn_key, z, |
344 | DN_FIB_INFO(f), 0); | 370 | DN_FIB_INFO(f), 0); |
345 | if (err < 0) { | 371 | /* failure implies BUG in dn_fib_nlmsg_size() */ |
346 | kfree_skb(skb); | 372 | BUG_ON(err < 0); |
347 | goto errout; | ||
348 | } | ||
349 | 373 | ||
350 | err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL); | 374 | err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL); |
351 | errout: | 375 | errout: |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 7602c79a389b..f38cbbae0ae3 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1120,6 +1120,16 @@ static struct notifier_block ip_netdev_notifier = { | |||
1120 | .notifier_call =inetdev_event, | 1120 | .notifier_call =inetdev_event, |
1121 | }; | 1121 | }; |
1122 | 1122 | ||
1123 | static inline size_t inet_nlmsg_size(void) | ||
1124 | { | ||
1125 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) | ||
1126 | + nla_total_size(4) /* IFA_ADDRESS */ | ||
1127 | + nla_total_size(4) /* IFA_LOCAL */ | ||
1128 | + nla_total_size(4) /* IFA_BROADCAST */ | ||
1129 | + nla_total_size(4) /* IFA_ANYCAST */ | ||
1130 | + nla_total_size(IFNAMSIZ); /* IFA_LABEL */ | ||
1131 | } | ||
1132 | |||
1123 | static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, | 1133 | static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, |
1124 | u32 pid, u32 seq, int event, unsigned int flags) | 1134 | u32 pid, u32 seq, int event, unsigned int flags) |
1125 | { | 1135 | { |
@@ -1208,15 +1218,13 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh, | |||
1208 | u32 seq = nlh ? nlh->nlmsg_seq : 0; | 1218 | u32 seq = nlh ? nlh->nlmsg_seq : 0; |
1209 | int err = -ENOBUFS; | 1219 | int err = -ENOBUFS; |
1210 | 1220 | ||
1211 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 1221 | skb = nlmsg_new(inet_nlmsg_size(), GFP_KERNEL); |
1212 | if (skb == NULL) | 1222 | if (skb == NULL) |
1213 | goto errout; | 1223 | goto errout; |
1214 | 1224 | ||
1215 | err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0); | 1225 | err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0); |
1216 | if (err < 0) { | 1226 | /* failure implies BUG in inet_nlmsg_size() */ |
1217 | kfree_skb(skb); | 1227 | BUG_ON(err < 0); |
1218 | goto errout; | ||
1219 | } | ||
1220 | 1228 | ||
1221 | err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL); | 1229 | err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL); |
1222 | errout: | 1230 | errout: |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index fd4a8cd4c06e..b837c33e0404 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -299,6 +299,13 @@ static u32 fib4_rule_default_pref(void) | |||
299 | return 0; | 299 | return 0; |
300 | } | 300 | } |
301 | 301 | ||
302 | static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule) | ||
303 | { | ||
304 | return nla_total_size(4) /* dst */ | ||
305 | + nla_total_size(4) /* src */ | ||
306 | + nla_total_size(4); /* flow */ | ||
307 | } | ||
308 | |||
302 | static struct fib_rules_ops fib4_rules_ops = { | 309 | static struct fib_rules_ops fib4_rules_ops = { |
303 | .family = AF_INET, | 310 | .family = AF_INET, |
304 | .rule_size = sizeof(struct fib4_rule), | 311 | .rule_size = sizeof(struct fib4_rule), |
@@ -308,6 +315,7 @@ static struct fib_rules_ops fib4_rules_ops = { | |||
308 | .compare = fib4_rule_compare, | 315 | .compare = fib4_rule_compare, |
309 | .fill = fib4_rule_fill, | 316 | .fill = fib4_rule_fill, |
310 | .default_pref = fib4_rule_default_pref, | 317 | .default_pref = fib4_rule_default_pref, |
318 | .nlmsg_payload = fib4_rule_nlmsg_payload, | ||
311 | .nlgroup = RTNLGRP_IPV4_RULE, | 319 | .nlgroup = RTNLGRP_IPV4_RULE, |
312 | .policy = fib4_rule_policy, | 320 | .policy = fib4_rule_policy, |
313 | .rules_list = &fib4_rules, | 321 | .rules_list = &fib4_rules, |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 884d176e0082..e63b8a98fb4d 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -273,25 +273,49 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev) | |||
273 | return -1; | 273 | return -1; |
274 | } | 274 | } |
275 | 275 | ||
276 | static inline size_t fib_nlmsg_size(struct fib_info *fi) | ||
277 | { | ||
278 | size_t payload = NLMSG_ALIGN(sizeof(struct rtmsg)) | ||
279 | + nla_total_size(4) /* RTA_TABLE */ | ||
280 | + nla_total_size(4) /* RTA_DST */ | ||
281 | + nla_total_size(4) /* RTA_PRIORITY */ | ||
282 | + nla_total_size(4); /* RTA_PREFSRC */ | ||
283 | |||
284 | /* space for nested metrics */ | ||
285 | payload += nla_total_size((RTAX_MAX * nla_total_size(4))); | ||
286 | |||
287 | if (fi->fib_nhs) { | ||
288 | /* Also handles the special case fib_nhs == 1 */ | ||
289 | |||
290 | /* each nexthop is packed in an attribute */ | ||
291 | size_t nhsize = nla_total_size(sizeof(struct rtnexthop)); | ||
292 | |||
293 | /* may contain flow and gateway attribute */ | ||
294 | nhsize += 2 * nla_total_size(4); | ||
295 | |||
296 | /* all nexthops are packed in a nested attribute */ | ||
297 | payload += nla_total_size(fi->fib_nhs * nhsize); | ||
298 | } | ||
299 | |||
300 | return payload; | ||
301 | } | ||
302 | |||
276 | void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, | 303 | void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, |
277 | int dst_len, u32 tb_id, struct nl_info *info) | 304 | int dst_len, u32 tb_id, struct nl_info *info) |
278 | { | 305 | { |
279 | struct sk_buff *skb; | 306 | struct sk_buff *skb; |
280 | int payload = sizeof(struct rtmsg) + 256; | ||
281 | u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; | 307 | u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; |
282 | int err = -ENOBUFS; | 308 | int err = -ENOBUFS; |
283 | 309 | ||
284 | skb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL); | 310 | skb = nlmsg_new(fib_nlmsg_size(fa->fa_info), GFP_KERNEL); |
285 | if (skb == NULL) | 311 | if (skb == NULL) |
286 | goto errout; | 312 | goto errout; |
287 | 313 | ||
288 | err = fib_dump_info(skb, info->pid, seq, event, tb_id, | 314 | err = fib_dump_info(skb, info->pid, seq, event, tb_id, |
289 | fa->fa_type, fa->fa_scope, key, dst_len, | 315 | fa->fa_type, fa->fa_scope, key, dst_len, |
290 | fa->fa_tos, fa->fa_info, 0); | 316 | fa->fa_tos, fa->fa_info, 0); |
291 | if (err < 0) { | 317 | /* failure implies BUG in fib_nlmsg_size() */ |
292 | kfree_skb(skb); | 318 | BUG_ON(err < 0); |
293 | goto errout; | ||
294 | } | ||
295 | 319 | ||
296 | err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE, | 320 | err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE, |
297 | info->nlh, GFP_KERNEL); | 321 | info->nlh, GFP_KERNEL); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 6a98f68348cb..967ea320a9ca 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3098,10 +3098,9 @@ static inline int rt_scope(int ifa_scope) | |||
3098 | 3098 | ||
3099 | static inline int inet6_ifaddr_msgsize(void) | 3099 | static inline int inet6_ifaddr_msgsize(void) |
3100 | { | 3100 | { |
3101 | return nlmsg_total_size(sizeof(struct ifaddrmsg) + | 3101 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) |
3102 | nla_total_size(16) + | 3102 | + nla_total_size(16) /* IFA_ADDRESS */ |
3103 | nla_total_size(sizeof(struct ifa_cacheinfo)) + | 3103 | + nla_total_size(sizeof(struct ifa_cacheinfo)); |
3104 | 128); | ||
3105 | } | 3104 | } |
3106 | 3105 | ||
3107 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | 3106 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, |
@@ -3329,10 +3328,8 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3329 | 3328 | ||
3330 | err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, | 3329 | err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, |
3331 | nlh->nlmsg_seq, RTM_NEWADDR, 0); | 3330 | nlh->nlmsg_seq, RTM_NEWADDR, 0); |
3332 | if (err < 0) { | 3331 | /* failure implies BUG in inet6_ifaddr_msgsize() */ |
3333 | kfree_skb(skb); | 3332 | BUG_ON(err < 0); |
3334 | goto errout_ifa; | ||
3335 | } | ||
3336 | 3333 | ||
3337 | err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); | 3334 | err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); |
3338 | errout_ifa: | 3335 | errout_ifa: |
@@ -3351,10 +3348,8 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | |||
3351 | goto errout; | 3348 | goto errout; |
3352 | 3349 | ||
3353 | err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0); | 3350 | err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0); |
3354 | if (err < 0) { | 3351 | /* failure implies BUG in inet6_ifaddr_msgsize() */ |
3355 | kfree_skb(skb); | 3352 | BUG_ON(err < 0); |
3356 | goto errout; | ||
3357 | } | ||
3358 | 3353 | ||
3359 | err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3354 | err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3360 | errout: | 3355 | errout: |
@@ -3397,16 +3392,19 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, | |||
3397 | array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; | 3392 | array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; |
3398 | } | 3393 | } |
3399 | 3394 | ||
3400 | /* Maximum length of ifinfomsg attributes */ | 3395 | static inline size_t inet6_if_nlmsg_size(void) |
3401 | #define INET6_IFINFO_RTA_SPACE \ | 3396 | { |
3402 | RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \ | 3397 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) |
3403 | RTA_SPACE(MAX_ADDR_LEN) /* ADDRESS */ + \ | 3398 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ |
3404 | RTA_SPACE(sizeof(u32)) /* MTU */ + \ | 3399 | + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ |
3405 | RTA_SPACE(sizeof(int)) /* LINK */ + \ | 3400 | + nla_total_size(4) /* IFLA_MTU */ |
3406 | RTA_SPACE(0) /* PROTINFO */ + \ | 3401 | + nla_total_size(4) /* IFLA_LINK */ |
3407 | RTA_SPACE(sizeof(u32)) /* FLAGS */ + \ | 3402 | + nla_total_size( /* IFLA_PROTINFO */ |
3408 | RTA_SPACE(sizeof(struct ifla_cacheinfo)) /* CACHEINFO */ + \ | 3403 | nla_total_size(4) /* IFLA_INET6_FLAGS */ |
3409 | RTA_SPACE(sizeof(__s32[DEVCONF_MAX])) /* CONF */ | 3404 | + nla_total_size(sizeof(struct ifla_cacheinfo)) |
3405 | + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ | ||
3406 | ); | ||
3407 | } | ||
3410 | 3408 | ||
3411 | static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, | 3409 | static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, |
3412 | u32 pid, u32 seq, int event, unsigned int flags) | 3410 | u32 pid, u32 seq, int event, unsigned int flags) |
@@ -3501,18 +3499,15 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
3501 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | 3499 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) |
3502 | { | 3500 | { |
3503 | struct sk_buff *skb; | 3501 | struct sk_buff *skb; |
3504 | int payload = sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE; | ||
3505 | int err = -ENOBUFS; | 3502 | int err = -ENOBUFS; |
3506 | 3503 | ||
3507 | skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); | 3504 | skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC); |
3508 | if (skb == NULL) | 3505 | if (skb == NULL) |
3509 | goto errout; | 3506 | goto errout; |
3510 | 3507 | ||
3511 | err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0); | 3508 | err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0); |
3512 | if (err < 0) { | 3509 | /* failure implies BUG in inet6_if_nlmsg_size() */ |
3513 | kfree_skb(skb); | 3510 | BUG_ON(err < 0); |
3514 | goto errout; | ||
3515 | } | ||
3516 | 3511 | ||
3517 | err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3512 | err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3518 | errout: | 3513 | errout: |
@@ -3520,10 +3515,12 @@ errout: | |||
3520 | rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err); | 3515 | rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err); |
3521 | } | 3516 | } |
3522 | 3517 | ||
3523 | /* Maximum length of prefix_cacheinfo attributes */ | 3518 | static inline size_t inet6_prefix_nlmsg_size(void) |
3524 | #define INET6_PREFIX_RTA_SPACE \ | 3519 | { |
3525 | RTA_SPACE(sizeof(((struct prefix_info *)NULL)->prefix)) /* ADDRESS */ + \ | 3520 | return NLMSG_ALIGN(sizeof(struct prefixmsg)) |
3526 | RTA_SPACE(sizeof(struct prefix_cacheinfo)) /* CACHEINFO */ | 3521 | + nla_total_size(sizeof(struct in6_addr)) |
3522 | + nla_total_size(sizeof(struct prefix_cacheinfo)); | ||
3523 | } | ||
3527 | 3524 | ||
3528 | static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, | 3525 | static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, |
3529 | struct prefix_info *pinfo, u32 pid, u32 seq, | 3526 | struct prefix_info *pinfo, u32 pid, u32 seq, |
@@ -3569,18 +3566,15 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3569 | struct prefix_info *pinfo) | 3566 | struct prefix_info *pinfo) |
3570 | { | 3567 | { |
3571 | struct sk_buff *skb; | 3568 | struct sk_buff *skb; |
3572 | int payload = sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE; | ||
3573 | int err = -ENOBUFS; | 3569 | int err = -ENOBUFS; |
3574 | 3570 | ||
3575 | skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); | 3571 | skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC); |
3576 | if (skb == NULL) | 3572 | if (skb == NULL) |
3577 | goto errout; | 3573 | goto errout; |
3578 | 3574 | ||
3579 | err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0); | 3575 | err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0); |
3580 | if (err < 0) { | 3576 | /* failure implies BUG in inet6_prefix_nlmsg_size() */ |
3581 | kfree_skb(skb); | 3577 | BUG_ON(err < 0); |
3582 | goto errout; | ||
3583 | } | ||
3584 | 3578 | ||
3585 | err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); | 3579 | err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); |
3586 | errout: | 3580 | errout: |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 25804cb69cf0..d587dde5897e 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -232,6 +232,12 @@ static u32 fib6_rule_default_pref(void) | |||
232 | return 0x3FFF; | 232 | return 0x3FFF; |
233 | } | 233 | } |
234 | 234 | ||
235 | static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) | ||
236 | { | ||
237 | return nla_total_size(16) /* dst */ | ||
238 | + nla_total_size(16); /* src */ | ||
239 | } | ||
240 | |||
235 | static struct fib_rules_ops fib6_rules_ops = { | 241 | static struct fib_rules_ops fib6_rules_ops = { |
236 | .family = AF_INET6, | 242 | .family = AF_INET6, |
237 | .rule_size = sizeof(struct fib6_rule), | 243 | .rule_size = sizeof(struct fib6_rule), |
@@ -241,6 +247,7 @@ static struct fib_rules_ops fib6_rules_ops = { | |||
241 | .compare = fib6_rule_compare, | 247 | .compare = fib6_rule_compare, |
242 | .fill = fib6_rule_fill, | 248 | .fill = fib6_rule_fill, |
243 | .default_pref = fib6_rule_default_pref, | 249 | .default_pref = fib6_rule_default_pref, |
250 | .nlmsg_payload = fib6_rule_nlmsg_payload, | ||
244 | .nlgroup = RTNLGRP_IPV6_RULE, | 251 | .nlgroup = RTNLGRP_IPV6_RULE, |
245 | .policy = fib6_rule_policy, | 252 | .policy = fib6_rule_policy, |
246 | .rules_list = &fib6_rules, | 253 | .rules_list = &fib6_rules, |
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: |
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index a6ce1d6d5c59..f1788bd290f8 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
@@ -452,7 +452,7 @@ static int netlbl_cipsov4_list(struct sk_buff *skb, struct genl_info *info) | |||
452 | } | 452 | } |
453 | 453 | ||
454 | list_start: | 454 | list_start: |
455 | ans_skb = nlmsg_new(NLMSG_GOODSIZE * nlsze_mult, GFP_KERNEL); | 455 | ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE * nlsze_mult, GFP_KERNEL); |
456 | if (ans_skb == NULL) { | 456 | if (ans_skb == NULL) { |
457 | ret_val = -ENOMEM; | 457 | ret_val = -ENOMEM; |
458 | goto list_failure; | 458 | goto list_failure; |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 53c9079ad2c3..c529622ff0b7 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
@@ -356,7 +356,7 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info) | |||
356 | void *data; | 356 | void *data; |
357 | struct netlbl_dom_map *entry; | 357 | struct netlbl_dom_map *entry; |
358 | 358 | ||
359 | ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 359 | ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
360 | if (ans_skb == NULL) | 360 | if (ans_skb == NULL) |
361 | return -ENOMEM; | 361 | return -ENOMEM; |
362 | data = netlbl_netlink_hdr_put(ans_skb, | 362 | data = netlbl_netlink_hdr_put(ans_skb, |
@@ -492,7 +492,7 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info) | |||
492 | struct sk_buff *ans_skb = NULL; | 492 | struct sk_buff *ans_skb = NULL; |
493 | void *data; | 493 | void *data; |
494 | 494 | ||
495 | ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 495 | ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
496 | if (ans_skb == NULL) | 496 | if (ans_skb == NULL) |
497 | return -ENOMEM; | 497 | return -ENOMEM; |
498 | data = netlbl_netlink_hdr_put(ans_skb, | 498 | data = netlbl_netlink_hdr_put(ans_skb, |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 1833ad233b39..219dccade4e1 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -138,7 +138,7 @@ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info) | |||
138 | struct sk_buff *ans_skb; | 138 | struct sk_buff *ans_skb; |
139 | void *data; | 139 | void *data; |
140 | 140 | ||
141 | ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 141 | ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
142 | if (ans_skb == NULL) | 142 | if (ans_skb == NULL) |
143 | goto list_failure; | 143 | goto list_failure; |
144 | data = netlbl_netlink_hdr_put(ans_skb, | 144 | data = netlbl_netlink_hdr_put(ans_skb, |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index d527c8977b1f..f61d81b3c61c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1148,7 +1148,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1148 | if (len > sk->sk_sndbuf - 32) | 1148 | if (len > sk->sk_sndbuf - 32) |
1149 | goto out; | 1149 | goto out; |
1150 | err = -ENOBUFS; | 1150 | err = -ENOBUFS; |
1151 | skb = nlmsg_new(len, GFP_KERNEL); | 1151 | skb = alloc_skb(len, GFP_KERNEL); |
1152 | if (skb==NULL) | 1152 | if (skb==NULL) |
1153 | goto out; | 1153 | goto out; |
1154 | 1154 | ||
@@ -1435,14 +1435,13 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) | |||
1435 | struct sk_buff *skb; | 1435 | struct sk_buff *skb; |
1436 | struct nlmsghdr *rep; | 1436 | struct nlmsghdr *rep; |
1437 | struct nlmsgerr *errmsg; | 1437 | struct nlmsgerr *errmsg; |
1438 | int size; | 1438 | size_t payload = sizeof(*errmsg); |
1439 | 1439 | ||
1440 | if (err == 0) | 1440 | /* error messages get the original request appened */ |
1441 | size = nlmsg_total_size(sizeof(*errmsg)); | 1441 | if (err) |
1442 | else | 1442 | payload += nlmsg_len(nlh); |
1443 | size = nlmsg_total_size(sizeof(*errmsg) + nlmsg_len(nlh)); | ||
1444 | 1443 | ||
1445 | skb = nlmsg_new(size, GFP_KERNEL); | 1444 | skb = nlmsg_new(payload, GFP_KERNEL); |
1446 | if (!skb) { | 1445 | if (!skb) { |
1447 | struct sock *sk; | 1446 | struct sock *sk; |
1448 | 1447 | ||
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 49bc2db7982b..70d60c818897 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -480,7 +480,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid, | |||
480 | struct sk_buff *skb; | 480 | struct sk_buff *skb; |
481 | int err; | 481 | int err; |
482 | 482 | ||
483 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 483 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
484 | if (skb == NULL) | 484 | if (skb == NULL) |
485 | return ERR_PTR(-ENOBUFS); | 485 | return ERR_PTR(-ENOBUFS); |
486 | 486 | ||