History

[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.

Thomas Graf committed 20 years ago

Commit 339bf981 parent a94f72321 files · +233 −107Browse files

Unified · Split

21 files
  1. include/linux/netlink.h +1 −0
  2. include/net/fib_rules.h +1 −0
  3. include/net/netlink.h +5 −4
  4. kernel/taskstats.c +1 −2
  5. net/bridge/br_netlink.c +15 −6
  6. net/core/fib_rules.c +19 −5
  7. net/core/neighbour.c +12 −5
  8. net/core/rtnetlink.c +26 −13
  9. net/decnet/dn_rules.c +6 −0
  10. net/decnet/dn_table.c +29 −5
  11. net/ipv4/devinet.c +13 −5
  12. net/ipv4/fib_rules.c +8 −0
  13. net/ipv4/fib_semantics.c +30 −6
  14. net/ipv6/addrconf.c +32 −38
  15. net/ipv6/fib6_rules.c +7 −0
  16. net/ipv6/route.c +17 −6
  17. net/netlabel/netlabel_cipso_v4.c +1 −1
  18. net/netlabel/netlabel_mgmt.c +2 −2
  19. net/netlabel/netlabel_unlabeled.c +1 −1
  20. net/netlink/af_netlink.c +6 −7
  21. net/netlink/genetlink.c +1 −1
include/linux/netlink.h+1−0
@@ -174,6 +174,7 @@ int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol); · 173 unmodified lines
174174 */
175175 #define NLMSG_GOODORDER 0
176176 #define NLMSG_GOODSIZE (SKB_MAX_ORDER(0, NLMSG_GOODORDER))
177+#define NLMSG_DEFAULT_SIZE (NLMSG_GOODSIZE - NLMSG_HDRLEN)
177178
178179
179180 struct netlink_callback
include/net/fib_rules.h+1−0
@@ -52,6 +52,7 @@ struct fib_rules_ops · 51 unmodified lines
5252 struct nlmsghdr *,
5353 struct fib_rule_hdr *);
5454 u32 (*default_pref)(void);
55+ size_t (*nlmsg_payload)(struct fib_rule *);
5556
5657 int nlgroup;
5758 struct nla_policy *policy;
include/net/netlink.h+5−4
@@ -500,14 +500,15 @@ static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb, · 499 unmodified lines
500500
501501 /**
502502 * nlmsg_new - Allocate a new netlink message
503− * @size: maximum size of message
503+ * @payload: size of the message payload
504504 * @flags: the type of memory to allocate.
505505 *
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.
507508 */
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)
509510 {
510− return alloc_skb(size, flags);
511+ return alloc_skb(nlmsg_total_size(payload), flags);
511512 }
512513
513514 /**
kernel/taskstats.c+1−2
@@ -77,8 +77,7 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp, · 76 unmodified lines
7777 /*
7878 * If new attributes are added, please revisit this allocation
7979 */
80− size = nlmsg_total_size(genlmsg_total_size(size));
81− skb = nlmsg_new(size, GFP_KERNEL);
80+ skb = nlmsg_new(genlmsg_total_size(size), GFP_KERNEL);
8281 if (!skb)
8382 return -ENOMEM;
8483
net/bridge/br_netlink.c+15−6
@@ -15,6 +15,18 @@ · 14 unmodified lines
1515 #include <net/netlink.h>
1616 #include "br_private.h"
1717
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+
1830 /*
1931 * Create one netlink message for one interface
2032 * Contains port and master info as well as carrier and bridge state.
@@ -77,19 +89,16 @@ rtattr_failure: · 56 unmodified lines
7789 void br_ifinfo_notify(int event, struct net_bridge_port *port)
7890 {
7991 struct sk_buff *skb;
80− int payload = sizeof(struct ifinfomsg) + 128;
8192 int err = -ENOBUFS;
8293
8394 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);
8596 if (skb == NULL)
8697 goto errout;
8798
8899 err = br_fill_ifinfo(skb, port, 0, 0, event, 0);
89− if (err < 0) {
90− kfree_skb(skb);
91− goto errout;
92− }
100+ /* failure implies BUG in br_nlmsg_size() */
101+ BUG_ON(err < 0);
93102
94103 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
95104 errout:
net/core/fib_rules.c+19−5
@@ -306,6 +306,22 @@ errout: · 305 unmodified lines
306306 return err;
307307 }
308308
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+
309325 static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
310326 u32 pid, u32 seq, int type, int flags,
311327 struct fib_rules_ops *ops)
@@ -384,15 +400,13 @@ static void notify_rule_change(int event, struct fib_rule *rule, · 72 unmodified lines
384400 struct sk_buff *skb;
385401 int err = -ENOBUFS;
386402
387− skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
403+ skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL);
388404 if (skb == NULL)
389405 goto errout;
390406
391407 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops);
392− if (err < 0) {
393− kfree_skb(skb);
394− goto errout;
395− }
408+ /* failure implies BUG in fib_rule_nlmsg_size() */
409+ BUG_ON(err < 0);
396410
397411 err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
398412 errout:
net/core/neighbour.c+12−5
@@ -2410,20 +2410,27 @@ static struct file_operations neigh_stat_seq_fops = { · 2409 unmodified lines
24102410 #endif /* CONFIG_PROC_FS */
24112411
24122412 #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+
24132422 static void __neigh_notify(struct neighbour *n, int type, int flags)
24142423 {
24152424 struct sk_buff *skb;
24162425 int err = -ENOBUFS;
24172426
2418− skb = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
2427+ skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC);
24192428 if (skb == NULL)
24202429 goto errout;
24212430
24222431 err = neigh_fill_info(skb, n, 0, 0, type, flags);
2423− if (err < 0) {
2424− kfree_skb(skb);
2425− goto errout;
2426− }
2432+ /* failure implies BUG in neigh_nlmsg_size() */
2433+ BUG_ON(err < 0);
24272434
24282435 err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
24292436 errout:
net/core/rtnetlink.c+26−13
@@ -273,6 +273,25 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, · 272 unmodified lines
273273 a->tx_compressed = b->tx_compressed;
274274 };
275275
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+
276295 static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
277296 void *iwbuf, int iwbuflen, int type, u32 pid,
278297 u32 seq, u32 change, unsigned int flags)
@@ -558,7 +577,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) · 279 unmodified lines
558577 struct sk_buff *nskb;
559578 char *iw_buf = NULL, *iw = NULL;
560579 int iw_buf_len = 0;
561− int err, payload;
580+ int err;
562581
563582 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
564583 if (err < 0)
@@ -587,9 +606,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) · 22 unmodified lines
587606 }
588607 #endif /* CONFIG_NET_WIRELESS_RTNETLINK */
589608
590− payload = NLMSG_ALIGN(sizeof(struct ifinfomsg) +
591− nla_total_size(iw_buf_len));
592− nskb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL);
609+ nskb = nlmsg_new(if_nlmsg_size(iw_buf_len), GFP_KERNEL);
593610 if (nskb == NULL) {
594611 err = -ENOBUFS;
595612 goto errout;
@@ -597,10 +614,8 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) · 1 unmodified line
597614
598615 err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK,
599616 NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0);
600− if (err <= 0) {
601− kfree_skb(nskb);
602− goto errout;
603− }
617+ /* failure impilies BUG in if_nlmsg_size or wireless_rtnetlink_get */
618+ BUG_ON(err < 0);
604619
605620 err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
606621 errout:
@@ -639,15 +654,13 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) · 32 unmodified lines
639654 struct sk_buff *skb;
640655 int err = -ENOBUFS;
641656
642− skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
657+ skb = nlmsg_new(if_nlmsg_size(0), GFP_KERNEL);
643658 if (skb == NULL)
644659 goto errout;
645660
646661 err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0);
647− if (err < 0) {
648− kfree_skb(skb);
649− goto errout;
650− }
662+ /* failure implies BUG in if_nlmsg_size() */
663+ BUG_ON(err < 0);
651664
652665 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
653666 errout:
net/decnet/dn_rules.c+6−0
@@ -241,6 +241,12 @@ static u32 dn_fib_rule_default_pref(void) · 240 unmodified lines
241241 return 0;
242242 }
243243
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+
244250 int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
245251 {
246252 return fib_rules_dump(skb, cb, AF_DECnet);
net/decnet/dn_table.c+29−5
@@ -263,6 +263,32 @@ static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct dn_kern · 262 unmodified lines
263263 return 0;
264264 }
265265
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+
266292 static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
267293 u32 tb_id, u8 type, u8 scope, void *dst, int dst_len,
268294 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, · 66 unmodified lines
335361 u32 pid = req ? req->pid : 0;
336362 int err = -ENOBUFS;
337363
338− skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
364+ skb = nlmsg_new(dn_fib_nlmsg_size(DN_FIB_INFO(f), GFP_KERNEL));
339365 if (skb == NULL)
340366 goto errout;
341367
342368 err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id,
343369 f->fn_type, f->fn_scope, &f->fn_key, z,
344370 DN_FIB_INFO(f), 0);
345− if (err < 0) {
346− kfree_skb(skb);
347− goto errout;
348− }
371+ /* failure implies BUG in dn_fib_nlmsg_size() */
372+ BUG_ON(err < 0);
349373
350374 err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
351375 errout:
net/ipv4/devinet.c+13−5
@@ -1120,6 +1120,16 @@ static struct notifier_block ip_netdev_notifier = { · 1119 unmodified lines
11201120 .notifier_call =inetdev_event,
11211121 };
11221122
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+
11231133 static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
11241134 u32 pid, u32 seq, int event, unsigned int flags)
11251135 {
@@ -1208,15 +1218,13 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh, · 82 unmodified lines
12081218 u32 seq = nlh ? nlh->nlmsg_seq : 0;
12091219 int err = -ENOBUFS;
12101220
1211− skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1221+ skb = nlmsg_new(inet_nlmsg_size(), GFP_KERNEL);
12121222 if (skb == NULL)
12131223 goto errout;
12141224
12151225 err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0);
1216− if (err < 0) {
1217− kfree_skb(skb);
1218− goto errout;
1219− }
1226+ /* failure implies BUG in inet_nlmsg_size() */
1227+ BUG_ON(err < 0);
12201228
12211229 err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
12221230 errout:
net/ipv4/fib_rules.c+8−0
@@ -299,6 +299,13 @@ static u32 fib4_rule_default_pref(void) · 298 unmodified lines
299299 return 0;
300300 }
301301
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+
302309 static struct fib_rules_ops fib4_rules_ops = {
303310 .family = AF_INET,
304311 .rule_size = sizeof(struct fib4_rule),
@@ -308,6 +315,7 @@ static struct fib_rules_ops fib4_rules_ops = { · 3 unmodified lines
308315 .compare = fib4_rule_compare,
309316 .fill = fib4_rule_fill,
310317 .default_pref = fib4_rule_default_pref,
318+ .nlmsg_payload = fib4_rule_nlmsg_payload,
311319 .nlgroup = RTNLGRP_IPV4_RULE,
312320 .policy = fib4_rule_policy,
313321 .rules_list = &fib4_rules,
net/ipv4/fib_semantics.c+30−6
@@ -273,25 +273,49 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev) · 272 unmodified lines
273273 return -1;
274274 }
275275
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+
276303 void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
277304 int dst_len, u32 tb_id, struct nl_info *info)
278305 {
279306 struct sk_buff *skb;
280− int payload = sizeof(struct rtmsg) + 256;
281307 u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0;
282308 int err = -ENOBUFS;
283309
284− skb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL);
310+ skb = nlmsg_new(fib_nlmsg_size(fa->fa_info), GFP_KERNEL);
285311 if (skb == NULL)
286312 goto errout;
287313
288314 err = fib_dump_info(skb, info->pid, seq, event, tb_id,
289315 fa->fa_type, fa->fa_scope, key, dst_len,
290316 fa->fa_tos, fa->fa_info, 0);
291− if (err < 0) {
292− kfree_skb(skb);
293− goto errout;
294− }
317+ /* failure implies BUG in fib_nlmsg_size() */
318+ BUG_ON(err < 0);
295319
296320 err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE,
297321 info->nlh, GFP_KERNEL);
net/ipv6/addrconf.c+32−38
@@ -3098,10 +3098,9 @@ static inline int rt_scope(int ifa_scope) · 3097 unmodified lines
30983098
30993099 static inline int inet6_ifaddr_msgsize(void)
31003100 {
3101− return nlmsg_total_size(sizeof(struct ifaddrmsg) +
3102− nla_total_size(16) +
3103− nla_total_size(sizeof(struct ifa_cacheinfo)) +
3104− 128);
3101+ return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
3102+ + nla_total_size(16) /* IFA_ADDRESS */
3103+ + nla_total_size(sizeof(struct ifa_cacheinfo));
31053104 }
31063105
31073106 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, · 221 unmodified lines
33293328
33303329 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
33313330 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3332− if (err < 0) {
3333− kfree_skb(skb);
3334− goto errout_ifa;
3335− }
3331+ /* failure implies BUG in inet6_ifaddr_msgsize() */
3332+ BUG_ON(err < 0);
33363333
33373334 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
33383335 errout_ifa:
@@ -3351,10 +3348,8 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) · 12 unmodified lines
33513348 goto errout;
33523349
33533350 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
3354− if (err < 0) {
3355− kfree_skb(skb);
3356− goto errout;
3357− }
3351+ /* failure implies BUG in inet6_ifaddr_msgsize() */
3352+ BUG_ON(err < 0);
33583353
33593354 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
33603355 errout:
@@ -3397,16 +3392,19 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, · 36 unmodified lines
33973392 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
33983393 }
33993394
3400−/* Maximum length of ifinfomsg attributes */
3401−#define INET6_IFINFO_RTA_SPACE \
3402− RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \
3403− RTA_SPACE(MAX_ADDR_LEN) /* ADDRESS */ + \
3404− RTA_SPACE(sizeof(u32)) /* MTU */ + \
3405− RTA_SPACE(sizeof(int)) /* LINK */ + \
3406− RTA_SPACE(0) /* PROTINFO */ + \
3407− RTA_SPACE(sizeof(u32)) /* FLAGS */ + \
3408− RTA_SPACE(sizeof(struct ifla_cacheinfo)) /* CACHEINFO */ + \
3409− RTA_SPACE(sizeof(__s32[DEVCONF_MAX])) /* CONF */
3395+static inline size_t inet6_if_nlmsg_size(void)
3396+{
3397+ return NLMSG_ALIGN(sizeof(struct ifinfomsg))
3398+ + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
3399+ + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
3400+ + nla_total_size(4) /* IFLA_MTU */
3401+ + nla_total_size(4) /* IFLA_LINK */
3402+ + nla_total_size( /* IFLA_PROTINFO */
3403+ nla_total_size(4) /* IFLA_INET6_FLAGS */
3404+ + nla_total_size(sizeof(struct ifla_cacheinfo))
3405+ + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
3406+ );
3407+}
34103408
34113409 static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
34123410 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) · 88 unmodified lines
35013499 void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
35023500 {
35033501 struct sk_buff *skb;
3504− int payload = sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE;
35053502 int err = -ENOBUFS;
35063503
3507− skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC);
3504+ skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC);
35083505 if (skb == NULL)
35093506 goto errout;
35103507
35113508 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
3512− if (err < 0) {
3513− kfree_skb(skb);
3514− goto errout;
3515− }
3509+ /* failure implies BUG in inet6_if_nlmsg_size() */
3510+ BUG_ON(err < 0);
35163511
35173512 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
35183513 errout:
@@ -3520,10 +3515,12 @@ errout: · 1 unmodified line
35203515 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
35213516 }
35223517
3523−/* Maximum length of prefix_cacheinfo attributes */
3524−#define INET6_PREFIX_RTA_SPACE \
3525− RTA_SPACE(sizeof(((struct prefix_info *)NULL)->prefix)) /* ADDRESS */ + \
3526− RTA_SPACE(sizeof(struct prefix_cacheinfo)) /* CACHEINFO */
3518+static inline size_t inet6_prefix_nlmsg_size(void)
3519+{
3520+ return NLMSG_ALIGN(sizeof(struct prefixmsg))
3521+ + nla_total_size(sizeof(struct in6_addr))
3522+ + nla_total_size(sizeof(struct prefix_cacheinfo));
3523+}
35273524
35283525 static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
35293526 struct prefix_info *pinfo, u32 pid, u32 seq,
@@ -3569,18 +3566,15 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, · 39 unmodified lines
35693566 struct prefix_info *pinfo)
35703567 {
35713568 struct sk_buff *skb;
3572− int payload = sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE;
35733569 int err = -ENOBUFS;
35743570
3575− skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC);
3571+ skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC);
35763572 if (skb == NULL)
35773573 goto errout;
35783574
35793575 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
3580− if (err < 0) {
3581− kfree_skb(skb);
3582− goto errout;
3583− }
3576+ /* failure implies BUG in inet6_prefix_nlmsg_size() */
3577+ BUG_ON(err < 0);
35843578
35853579 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
35863580 errout:
net/ipv6/fib6_rules.c+7−0
@@ -232,6 +232,12 @@ static u32 fib6_rule_default_pref(void) · 231 unmodified lines
232232 return 0x3FFF;
233233 }
234234
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+
235241 static struct fib_rules_ops fib6_rules_ops = {
236242 .family = AF_INET6,
237243 .rule_size = sizeof(struct fib6_rule),
@@ -241,6 +247,7 @@ static struct fib_rules_ops fib6_rules_ops = { · 3 unmodified lines
241247 .compare = fib6_rule_compare,
242248 .fill = fib6_rule_fill,
243249 .default_pref = fib6_rule_default_pref,
250+ .nlmsg_payload = fib6_rule_nlmsg_payload,
244251 .nlgroup = RTNLGRP_IPV6_RULE,
245252 .policy = fib6_rule_policy,
246253 .rules_list = &fib6_rules,
net/ipv6/route.c+17−6
@@ -2006,6 +2006,20 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) · 2005 unmodified lines
20062006 return ip6_route_add(&cfg);
20072007 }
20082008
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+
20092023 static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
20102024 struct in6_addr *dst, struct in6_addr *src,
20112025 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) · 188 unmodified lines
22002214 struct sk_buff *skb;
22012215 u32 pid = 0, seq = 0;
22022216 struct nlmsghdr *nlh = NULL;
2203− int payload = sizeof(struct rtmsg) + 256;
22042217 int err = -ENOBUFS;
22052218
22062219 if (info) {
@@ -2210,15 +2223,13 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) · 3 unmodified lines
22102223 seq = nlh->nlmsg_seq;
22112224 }
22122225
2213− skb = nlmsg_new(nlmsg_total_size(payload), gfp_any());
2226+ skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
22142227 if (skb == NULL)
22152228 goto errout;
22162229
22172230 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
2218− if (err < 0) {
2219− kfree_skb(skb);
2220− goto errout;
2221− }
2231+ /* failure implies BUG in rt6_nlmsg_size() */
2232+ BUG_ON(err < 0);
22222233
22232234 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
22242235 errout:
net/netlabel/netlabel_cipso_v4.c+1−1
@@ -452,7 +452,7 @@ static int netlbl_cipsov4_list(struct sk_buff *skb, struct genl_info *info) · 451 unmodified lines
452452 }
453453
454454 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);
456456 if (ans_skb == NULL) {
457457 ret_val = -ENOMEM;
458458 goto list_failure;
net/netlabel/netlabel_mgmt.c+2−2
@@ -356,7 +356,7 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info) · 355 unmodified lines
356356 void *data;
357357 struct netlbl_dom_map *entry;
358358
359− ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
359+ ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
360360 if (ans_skb == NULL)
361361 return -ENOMEM;
362362 data = netlbl_netlink_hdr_put(ans_skb,
@@ -492,7 +492,7 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info) · 129 unmodified lines
492492 struct sk_buff *ans_skb = NULL;
493493 void *data;
494494
495− ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
495+ ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
496496 if (ans_skb == NULL)
497497 return -ENOMEM;
498498 data = netlbl_netlink_hdr_put(ans_skb,
net/netlabel/netlabel_unlabeled.c+1−1
@@ -138,7 +138,7 @@ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info) · 137 unmodified lines
138138 struct sk_buff *ans_skb;
139139 void *data;
140140
141− ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
141+ ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
142142 if (ans_skb == NULL)
143143 goto list_failure;
144144 data = netlbl_netlink_hdr_put(ans_skb,
net/netlink/af_netlink.c+6−7
@@ -1148,7 +1148,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, · 1147 unmodified lines
11481148 if (len > sk->sk_sndbuf - 32)
11491149 goto out;
11501150 err = -ENOBUFS;
1151− skb = nlmsg_new(len, GFP_KERNEL);
1151+ skb = alloc_skb(len, GFP_KERNEL);
11521152 if (skb==NULL)
11531153 goto out;
11541154
@@ -1435,14 +1435,13 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) · 280 unmodified lines
14351435 struct sk_buff *skb;
14361436 struct nlmsghdr *rep;
14371437 struct nlmsgerr *errmsg;
1438− int size;
1438+ size_t payload = sizeof(*errmsg);
14391439
1440− if (err == 0)
1441− size = nlmsg_total_size(sizeof(*errmsg));
1442− else
1443− size = nlmsg_total_size(sizeof(*errmsg) + nlmsg_len(nlh));
1440+ /* error messages get the original request appened */
1441+ if (err)
1442+ payload += nlmsg_len(nlh);
14441443
1445− skb = nlmsg_new(size, GFP_KERNEL);
1444+ skb = nlmsg_new(payload, GFP_KERNEL);
14461445 if (!skb) {
14471446 struct sock *sk;
14481447
net/netlink/genetlink.c+1−1
@@ -480,7 +480,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid, · 479 unmodified lines
480480 struct sk_buff *skb;
481481 int err;
482482
483− skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
483+ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
484484 if (skb == NULL)
485485 return ERR_PTR(-ENOBUFS);
486486