Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 339bf98f authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller
Browse files

[NETLINK]: Do precise netlink message allocations where possible



Account for the netlink message header size directly in nlmsg_new()
instead of relying on the caller calculate it correctly.

Replaces error handling of message construction functions when
constructing notifications with bug traps since a failure implies
a bug in calculating the size of the skb.

Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Acked-by: default avatarPaul Moore <paul.moore@hp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a94f723d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol);
 */
#define NLMSG_GOODORDER 0
#define NLMSG_GOODSIZE (SKB_MAX_ORDER(0, NLMSG_GOODORDER))
#define NLMSG_DEFAULT_SIZE (NLMSG_GOODSIZE - NLMSG_HDRLEN)


struct netlink_callback
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ struct fib_rules_ops
					struct nlmsghdr *,
					struct fib_rule_hdr *);
	u32			(*default_pref)(void);
	size_t			(*nlmsg_payload)(struct fib_rule *);

	int			nlgroup;
	struct nla_policy	*policy;
+5 −4
Original line number Diff line number Diff line
@@ -500,14 +500,15 @@ static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,

/**
 * nlmsg_new - Allocate a new netlink message
 * @size: maximum size of message
 * @payload: size of the message payload
 * @flags: the type of memory to allocate.
 *
 * Use NLMSG_GOODSIZE if size isn't know and you need a good default size.
 * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known
 * and a good default is needed.
 */
static inline struct sk_buff *nlmsg_new(int size, gfp_t flags)
static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags)
{
	return alloc_skb(size, flags);
	return alloc_skb(nlmsg_total_size(payload), flags);
}

/**
+1 −2
Original line number Diff line number Diff line
@@ -77,8 +77,7 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp,
	/*
	 * If new attributes are added, please revisit this allocation
	 */
	size = nlmsg_total_size(genlmsg_total_size(size));
	skb = nlmsg_new(size, GFP_KERNEL);
	skb = nlmsg_new(genlmsg_total_size(size), GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

+15 −6
Original line number Diff line number Diff line
@@ -15,6 +15,18 @@
#include <net/netlink.h>
#include "br_private.h"

static inline size_t br_nlmsg_size(void)
{
	return NLMSG_ALIGN(sizeof(struct ifinfomsg))
	       + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
	       + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
	       + nla_total_size(4) /* IFLA_MASTER */
	       + nla_total_size(4) /* IFLA_MTU */
	       + nla_total_size(4) /* IFLA_LINK */
	       + nla_total_size(1) /* IFLA_OPERSTATE */
	       + nla_total_size(1); /* IFLA_PROTINFO */
}

/*
 * Create one netlink message for one interface
 * Contains port and master info as well as carrier and bridge state.
@@ -77,19 +89,16 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por
void br_ifinfo_notify(int event, struct net_bridge_port *port)
{
	struct sk_buff *skb;
	int payload = sizeof(struct ifinfomsg) + 128;
	int err = -ENOBUFS;

	pr_debug("bridge notify event=%d\n", event);
	skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC);
	skb = nlmsg_new(br_nlmsg_size(), GFP_ATOMIC);
	if (skb == NULL)
		goto errout;

	err = br_fill_ifinfo(skb, port, 0, 0, event, 0);
	if (err < 0) {
		kfree_skb(skb);
		goto errout;
	}
	/* failure implies BUG in br_nlmsg_size() */
	BUG_ON(err < 0);

	err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
errout:
Loading