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 66411622e0..e61e1e1384 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 e4ba781d28..bc3c26494c 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 ce5cba19c3..3002133915 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 f45c5e7077..4f3f0e48c8 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 8f661195d0..15d6efbe75 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 4148e274a2..1df6cd4568 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 b4b478353b..0e097ba14d 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 02f3c79478..50d6cb40c6 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 e32d0c3d5a..b7dfd04a96 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 317904bb58..e74b744254 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 7602c79a38..f38cbbae0a 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 fd4a8cd4c0..b837c33e04 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 884d176e00..e63b8a98fb 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 6a98f68348..967ea320a9 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 25804cb69c..d587dde589 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 0ad07c9087..a6472cb905 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 a6ce1d6d5c..f1788bd290 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 53c9079ad2..c529622ff0 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 1833ad233b..219dccade4 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 d527c8977b..f61d81b3c6 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 49bc2db798..70d60c8188 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 | ||
