Commit 1d00a4eb authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller
Browse files

[NETLINK]: Remove error pointer from netlink message handler



The error pointer argument in netlink message handlers is used
to signal the special case where processing has to be interrupted
because a dump was started but no error happened. Instead it is
simpler and more clear to return -EINTR and have netlink_run_queue()
deal with getting the queue right.

nfnetlink passed on this error pointer to its subsystem handlers
but only uses it to signal the start of a netlink dump. Therefore
it can be removed there as well.

This patch also cleans up the error handling in the affected
message handlers to be consistent since it had to be touched anyway.

Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 45e7ae7f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ struct nfgenmsg {
struct nfnl_callback
{
	int (*call)(struct sock *nl, struct sk_buff *skb, 
		struct nlmsghdr *nlh, struct nfattr *cda[], int *errp);
		struct nlmsghdr *nlh, struct nfattr *cda[]);
	u_int16_t attr_count;	/* number of nfattr's */
};

+1 −1
Original line number Diff line number Diff line
@@ -214,7 +214,7 @@ struct nl_info {

extern void		netlink_run_queue(struct sock *sk, unsigned int *qlen,
					  int (*cb)(struct sk_buff *,
						    struct nlmsghdr *, int *));
						    struct nlmsghdr *));
extern void		netlink_queue_skip(struct nlmsghdr *nlh,
					   struct sk_buff *skb);
extern int		nlmsg_notify(struct sock *sk, struct sk_buff *skb,
+15 −31
Original line number Diff line number Diff line
@@ -852,8 +852,7 @@ static int rtattr_max;

/* Process one rtnetlink message. */

static __inline__ int
rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
	rtnl_doit_func doit;
	int sz_idx, kind;
@@ -863,10 +862,8 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
	int err;

	type = nlh->nlmsg_type;

	/* Unknown message: reply with EINVAL */
	if (type > RTM_MAX)
		goto err_inval;
		return -EINVAL;

	type -= RTM_BASE;

@@ -875,40 +872,33 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
		return 0;

	family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family;
	if (family >= NPROTO) {
		*errp = -EAFNOSUPPORT;
		return -1;
	}
	if (family >= NPROTO)
		return -EAFNOSUPPORT;

	sz_idx = type>>2;
	kind = type&3;

	if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) {
		*errp = -EPERM;
		return -1;
	}
	if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN))
		return -EPERM;

	if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
		rtnl_dumpit_func dumpit;

		dumpit = rtnl_get_dumpit(family, type);
		if (dumpit == NULL)
			goto err_inval;

		if ((*errp = netlink_dump_start(rtnl, skb, nlh,
						dumpit, NULL)) != 0) {
			return -1;
		}
			return -EINVAL;

		netlink_queue_skip(nlh, skb);
		return -1;
		err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
		if (err == 0)
			err = -EINTR;
		return err;
	}

	memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));

	min_len = rtm_min[sz_idx];
	if (nlh->nlmsg_len < min_len)
		goto err_inval;
		return -EINVAL;

	if (nlh->nlmsg_len > min_len) {
		int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
@@ -918,7 +908,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
			unsigned flavor = attr->rta_type;
			if (flavor) {
				if (flavor > rta_max[sz_idx])
					goto err_inval;
					return -EINVAL;
				rta_buf[flavor-1] = attr;
			}
			attr = RTA_NEXT(attr, attrlen);
@@ -927,15 +917,9 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)

	doit = rtnl_get_doit(family, type);
	if (doit == NULL)
		goto err_inval;
	err = doit(skb, nlh, (void *)&rta_buf[0]);

	*errp = err;
	return err;
		return -EINVAL;

err_inval:
	*errp = -EINVAL;
	return -1;
	return doit(skb, nlh, (void *)&rta_buf[0]);
}

static void rtnetlink_rcv(struct sock *sk, int len)
+17 −29
Original line number Diff line number Diff line
@@ -661,7 +661,7 @@ static const size_t cta_min[CTA_MAX] = {

static int
ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
			struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
			struct nlmsghdr *nlh, struct nfattr *cda[])
{
	struct nf_conntrack_tuple_hash *h;
	struct nf_conntrack_tuple tuple;
@@ -709,7 +709,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,

static int
ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
			struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
			struct nlmsghdr *nlh, struct nfattr *cda[])
{
	struct nf_conntrack_tuple_hash *h;
	struct nf_conntrack_tuple tuple;
@@ -720,22 +720,15 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
	int err = 0;

	if (nlh->nlmsg_flags & NLM_F_DUMP) {
		u32 rlen;

#ifndef CONFIG_NF_CT_ACCT
		if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO)
			return -ENOTSUPP;
#endif
		if ((*errp = netlink_dump_start(ctnl, skb, nlh,
						ctnetlink_dump_table,
						ctnetlink_done)) != 0)
			return -EINVAL;

		rlen = NLMSG_ALIGN(nlh->nlmsg_len);
		if (rlen > skb->len)
			rlen = skb->len;
		skb_pull(skb, rlen);
		return 0;
		err = netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table,
					 ctnetlink_done);
		if (err == 0)
			err = -EINTR;
		return err;
	}

	if (nfattr_bad_size(cda, CTA_MAX, cta_min))
@@ -1009,7 +1002,7 @@ err:

static int
ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
			struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
			struct nlmsghdr *nlh, struct nfattr *cda[])
{
	struct nf_conntrack_tuple otuple, rtuple;
	struct nf_conntrack_tuple_hash *h = NULL;
@@ -1260,7 +1253,7 @@ static const size_t cta_min_exp[CTA_EXPECT_MAX] = {

static int
ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
		     struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
		     struct nlmsghdr *nlh, struct nfattr *cda[])
{
	struct nf_conntrack_tuple tuple;
	struct nf_conntrack_expect *exp;
@@ -1273,17 +1266,12 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
		return -EINVAL;

	if (nlh->nlmsg_flags & NLM_F_DUMP) {
		u32 rlen;

		if ((*errp = netlink_dump_start(ctnl, skb, nlh,
		err = netlink_dump_start(ctnl, skb, nlh,
					 ctnetlink_exp_dump_table,
						ctnetlink_done)) != 0)
			return -EINVAL;
		rlen = NLMSG_ALIGN(nlh->nlmsg_len);
		if (rlen > skb->len)
			rlen = skb->len;
		skb_pull(skb, rlen);
		return 0;
					 ctnetlink_done);
		if (err == 0)
			err = -EINTR;
		return err;
	}

	if (cda[CTA_EXPECT_MASTER-1])
@@ -1330,7 +1318,7 @@ out:

static int
ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
		     struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
		     struct nlmsghdr *nlh, struct nfattr *cda[])
{
	struct nf_conntrack_expect *exp, *tmp;
	struct nf_conntrack_tuple tuple;
@@ -1464,7 +1452,7 @@ out:

static int
ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
		     struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
		     struct nlmsghdr *nlh, struct nfattr *cda[])
{
	struct nf_conntrack_tuple tuple;
	struct nf_conntrack_expect *exp;
+8 −18
Original line number Diff line number Diff line
@@ -195,17 +195,14 @@ int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags)
EXPORT_SYMBOL_GPL(nfnetlink_unicast);

/* Process one complete nfnetlink message. */
static int nfnetlink_rcv_msg(struct sk_buff *skb,
				    struct nlmsghdr *nlh, int *errp)
static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
	struct nfnl_callback *nc;
	struct nfnetlink_subsystem *ss;
	int type, err = 0;
	int type, err;

	if (security_netlink_recv(skb, CAP_NET_ADMIN)) {
		*errp = -EPERM;
		return -1;
	}
	if (security_netlink_recv(skb, CAP_NET_ADMIN))
		return -EPERM;

	/* Only requests are handled by kernel now. */
	if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
@@ -227,12 +224,12 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb,
		ss = nfnetlink_get_subsys(type);
		if (!ss)
#endif
			goto err_inval;
			return -EINVAL;
	}

	nc = nfnetlink_find_client(type, ss);
	if (!nc)
		goto err_inval;
		return -EINVAL;

	{
		u_int16_t attr_count =
@@ -243,16 +240,9 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb,

		err = nfnetlink_check_attributes(ss, nlh, cda);
		if (err < 0)
			goto err_inval;

		err = nc->call(nfnl, skb, nlh, cda, errp);
		*errp = err;
			return err;
		return nc->call(nfnl, skb, nlh, cda);
	}

err_inval:
	*errp = -EINVAL;
	return -1;
}

static void nfnetlink_rcv(struct sock *sk, int len)
Loading