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

Commit c90c39da authored by Johannes Berg's avatar Johannes Berg Committed by David S. Miller
Browse files

genetlink: introduce and use genl_family_attrbuf()



This helper function allows family implementations to access
their family's attrbuf. This gets rid of the attrbuf usage
in families, and also adds locking validation, since it's not
valid to use the attrbuf with parallel_ops or outside of the
dumpit callback.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4fe77d82
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -73,6 +73,8 @@ struct genl_family {
	struct module		*module;
};

struct nlattr **genl_family_attrbuf(struct genl_family *family);

/**
 * struct genl_info - receiving information
 * @snd_seq: sending sequence number
+4 −3
Original line number Diff line number Diff line
@@ -263,13 +263,14 @@ nl802154_prepare_wpan_dev_dump(struct sk_buff *skb,

	if (!cb->args[0]) {
		err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl802154_fam.hdrsize,
				  nl802154_fam.attrbuf, nl802154_fam.maxattr,
				  genl_family_attrbuf(&nl802154_fam),
				  nl802154_fam.maxattr,
				  nl802154_policy);
		if (err)
			goto out_unlock;

		*wpan_dev = __cfg802154_wpan_dev_from_attrs(sock_net(skb->sk),
							    nl802154_fam.attrbuf);
							    genl_family_attrbuf(&nl802154_fam));
		if (IS_ERR(*wpan_dev)) {
			err = PTR_ERR(*wpan_dev);
			goto out_unlock;
@@ -575,7 +576,7 @@ static int nl802154_dump_wpan_phy_parse(struct sk_buff *skb,
					struct netlink_callback *cb,
					struct nl802154_dump_wpan_phy_state *state)
{
	struct nlattr **tb = nl802154_fam.attrbuf;
	struct nlattr **tb = genl_family_attrbuf(&nl802154_fam);
	int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl802154_fam.hdrsize,
			      tb, nl802154_fam.maxattr, nl802154_policy);

+19 −0
Original line number Diff line number Diff line
@@ -1096,6 +1096,25 @@ static int __init genl_init(void)

subsys_initcall(genl_init);

/**
 * genl_family_attrbuf - return family's attrbuf
 * @family: the family
 *
 * Return the family's attrbuf, while validating that it's
 * actually valid to access it.
 *
 * You cannot use this function with a family that has parallel_ops
 * and you can only use it within (pre/post) doit/dumpit callbacks.
 */
struct nlattr **genl_family_attrbuf(struct genl_family *family)
{
	if (!WARN_ON(family->parallel_ops))
		lockdep_assert_held(&genl_mutex);

	return family->attrbuf;
}
EXPORT_SYMBOL(genl_family_attrbuf);

static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
			 gfp_t flags)
{
+4 −5
Original line number Diff line number Diff line
@@ -120,21 +120,20 @@ static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,

static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
{
	struct nlattr **attrbuf = genl_family_attrbuf(&nfc_genl_family);
	struct nfc_dev *dev;
	int rc;
	u32 idx;

	rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
			 nfc_genl_family.attrbuf,
			 nfc_genl_family.maxattr,
			 nfc_genl_policy);
			 attrbuf, nfc_genl_family.maxattr, nfc_genl_policy);
	if (rc < 0)
		return ERR_PTR(rc);

	if (!nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX])
	if (!attrbuf[NFC_ATTR_DEVICE_INDEX])
		return ERR_PTR(-EINVAL);

	idx = nla_get_u32(nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX]);
	idx = nla_get_u32(attrbuf[NFC_ATTR_DEVICE_INDEX]);

	dev = nfc_get_device(idx);
	if (!dev)
+1 −1
Original line number Diff line number Diff line
@@ -262,7 +262,7 @@ int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr)
{
	u32 maxattr = tipc_genl_family.maxattr;

	*attr = tipc_genl_family.attrbuf;
	*attr = genl_family_attrbuf(&tipc_genl_family);
	if (!*attr)
		return -EOPNOTSUPP;

Loading