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

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

[XFRM] netlink: Use nla_put()/NLA_PUT() variantes



Also makes use of copy_sec_ctx() in another place and removes
duplicated code.

Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 082a1ad5
Loading
Loading
Loading
Loading
+67 −89
Original line number Original line Diff line number Diff line
@@ -576,6 +576,27 @@ struct xfrm_dump_info {
	int this_idx;
	int this_idx;
};
};


static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
{
	int ctx_size = sizeof(struct xfrm_sec_ctx) + s->ctx_len;
	struct xfrm_user_sec_ctx *uctx;
	struct nlattr *attr;

	attr = nla_reserve(skb, XFRMA_SEC_CTX, ctx_size);
	if (attr == NULL)
		return -EMSGSIZE;

	uctx = nla_data(attr);
	uctx->exttype = XFRMA_SEC_CTX;
	uctx->len = ctx_size;
	uctx->ctx_doi = s->ctx_doi;
	uctx->ctx_alg = s->ctx_alg;
	uctx->ctx_len = s->ctx_len;
	memcpy(uctx + 1, s->ctx_str, s->ctx_len);

	return 0;
}

static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
{
{
	struct xfrm_dump_info *sp = ptr;
	struct xfrm_dump_info *sp = ptr;
@@ -596,43 +617,32 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
	copy_to_user_state(x, p);
	copy_to_user_state(x, p);


	if (x->aalg)
	if (x->aalg)
		RTA_PUT(skb, XFRMA_ALG_AUTH,
		NLA_PUT(skb, XFRMA_ALG_AUTH,
			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
	if (x->ealg)
	if (x->ealg)
		RTA_PUT(skb, XFRMA_ALG_CRYPT,
		NLA_PUT(skb, XFRMA_ALG_CRYPT,
			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
	if (x->calg)
	if (x->calg)
		RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
		NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);


	if (x->encap)
	if (x->encap)
		RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
		NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);


	if (x->security) {
	if (x->security && copy_sec_ctx(x->security, skb) < 0)
		int ctx_size = sizeof(struct xfrm_sec_ctx) +
		goto nla_put_failure;
				x->security->ctx_len;
		struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
		struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);

		uctx->exttype = XFRMA_SEC_CTX;
		uctx->len = ctx_size;
		uctx->ctx_doi = x->security->ctx_doi;
		uctx->ctx_alg = x->security->ctx_alg;
		uctx->ctx_len = x->security->ctx_len;
		memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
	}


	if (x->coaddr)
	if (x->coaddr)
		RTA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);
		NLA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);


	if (x->lastused)
	if (x->lastused)
		RTA_PUT(skb, XFRMA_LASTUSED, sizeof(x->lastused), &x->lastused);
		NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused);


	nlmsg_end(skb, nlh);
	nlmsg_end(skb, nlh);
out:
out:
	sp->this_idx++;
	sp->this_idx++;
	return 0;
	return 0;


rtattr_failure:
nla_put_failure:
	nlmsg_cancel(skb, nlh);
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
	return -EMSGSIZE;
}
}
@@ -1193,32 +1203,9 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb)
		up->ealgos = kp->ealgos;
		up->ealgos = kp->ealgos;
		up->calgos = kp->calgos;
		up->calgos = kp->calgos;
	}
	}
	RTA_PUT(skb, XFRMA_TMPL,
		(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr),
		vec);

	return 0;

rtattr_failure:
	return -1;
}

static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
{
	int ctx_size = sizeof(struct xfrm_sec_ctx) + s->ctx_len;
	struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
	struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);

	uctx->exttype = XFRMA_SEC_CTX;
	uctx->len = ctx_size;
	uctx->ctx_doi = s->ctx_doi;
	uctx->ctx_alg = s->ctx_alg;
	uctx->ctx_len = s->ctx_len;
	memcpy(uctx + 1, s->ctx_str, s->ctx_len);
	return 0;


 rtattr_failure:
	return nla_put(skb, XFRMA_TMPL,
	return -1;
		       sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr, vec);
}
}


static inline int copy_to_user_state_sec_ctx(struct xfrm_state *x, struct sk_buff *skb)
static inline int copy_to_user_state_sec_ctx(struct xfrm_state *x, struct sk_buff *skb)
@@ -1240,17 +1227,11 @@ static inline int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *s
#ifdef CONFIG_XFRM_SUB_POLICY
#ifdef CONFIG_XFRM_SUB_POLICY
static int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
static int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
{
{
	struct xfrm_userpolicy_type upt;
	struct xfrm_userpolicy_type upt = {

		.type = type,
	memset(&upt, 0, sizeof(upt));
	};
	upt.type = type;

	RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);

	return 0;


rtattr_failure:
	return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
	return -1;
}
}


#else
#else
@@ -1440,7 +1421,6 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve
{
{
	struct xfrm_aevent_id *id;
	struct xfrm_aevent_id *id;
	struct nlmsghdr *nlh;
	struct nlmsghdr *nlh;
	struct xfrm_lifetime_cur ltime;


	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0);
	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0);
	if (nlh == NULL)
	if (nlh == NULL)
@@ -1455,27 +1435,19 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve
	id->reqid = x->props.reqid;
	id->reqid = x->props.reqid;
	id->flags = c->data.aevent;
	id->flags = c->data.aevent;


	RTA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay);
	NLA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay);
	NLA_PUT(skb, XFRMA_LTIME_VAL, sizeof(x->curlft), &x->curlft);


	ltime.bytes = x->curlft.bytes;
	if (id->flags & XFRM_AE_RTHR)
	ltime.packets = x->curlft.packets;
		NLA_PUT_U32(skb, XFRMA_REPLAY_THRESH, x->replay_maxdiff);
	ltime.add_time = x->curlft.add_time;
	ltime.use_time = x->curlft.use_time;


	RTA_PUT(skb, XFRMA_LTIME_VAL, sizeof(struct xfrm_lifetime_cur), &ltime);
	if (id->flags & XFRM_AE_ETHR)

		NLA_PUT_U32(skb, XFRMA_ETIMER_THRESH,
	if (id->flags&XFRM_AE_RTHR) {
			    x->replay_maxage * 10 / HZ);
		RTA_PUT(skb,XFRMA_REPLAY_THRESH,sizeof(u32),&x->replay_maxdiff);
	}

	if (id->flags&XFRM_AE_ETHR) {
		u32 etimer = x->replay_maxage*10/HZ;
		RTA_PUT(skb,XFRMA_ETIMER_THRESH,sizeof(u32),&etimer);
	}


	return nlmsg_end(skb, nlh);
	return nlmsg_end(skb, nlh);


rtattr_failure:
nla_put_failure:
	nlmsg_cancel(skb, nlh);
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
	return -EMSGSIZE;
}
}
@@ -1840,11 +1812,7 @@ static int copy_to_user_migrate(struct xfrm_migrate *m, struct sk_buff *skb)
	memcpy(&um.new_daddr, &m->new_daddr, sizeof(um.new_daddr));
	memcpy(&um.new_daddr, &m->new_daddr, sizeof(um.new_daddr));
	memcpy(&um.new_saddr, &m->new_saddr, sizeof(um.new_saddr));
	memcpy(&um.new_saddr, &m->new_saddr, sizeof(um.new_saddr));


	RTA_PUT(skb, XFRMA_MIGRATE, sizeof(um), &um);
	return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um);
	return 0;

rtattr_failure:
	return -1;
}
}


static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
@@ -2137,39 +2105,44 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c)


	nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
	nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
	if (nlh == NULL)
	if (nlh == NULL)
		goto nlmsg_failure;
		goto nla_put_failure;


	p = nlmsg_data(nlh);
	p = nlmsg_data(nlh);
	if (c->event == XFRM_MSG_DELSA) {
	if (c->event == XFRM_MSG_DELSA) {
		struct nlattr *attr;

		id = nlmsg_data(nlh);
		id = nlmsg_data(nlh);
		memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr));
		memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr));
		id->spi = x->id.spi;
		id->spi = x->id.spi;
		id->family = x->props.family;
		id->family = x->props.family;
		id->proto = x->id.proto;
		id->proto = x->id.proto;


		p = RTA_DATA(__RTA_PUT(skb, XFRMA_SA, sizeof(*p)));
		attr = nla_reserve(skb, XFRMA_SA, sizeof(*p));
		if (attr == NULL)
			goto nla_put_failure;

		p = nla_data(attr);
	}
	}


	copy_to_user_state(x, p);
	copy_to_user_state(x, p);


	if (x->aalg)
	if (x->aalg)
		RTA_PUT(skb, XFRMA_ALG_AUTH,
		NLA_PUT(skb, XFRMA_ALG_AUTH,
			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
	if (x->ealg)
	if (x->ealg)
		RTA_PUT(skb, XFRMA_ALG_CRYPT,
		NLA_PUT(skb, XFRMA_ALG_CRYPT,
			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
	if (x->calg)
	if (x->calg)
		RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
		NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);


	if (x->encap)
	if (x->encap)
		RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
		NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);


	nlmsg_end(skb, nlh);
	nlmsg_end(skb, nlh);


	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);


nlmsg_failure:
nla_put_failure:
rtattr_failure:
	kfree_skb(skb);
	kfree_skb(skb);
	return -1;
	return -1;
}
}
@@ -2392,6 +2365,8 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *


	p = nlmsg_data(nlh);
	p = nlmsg_data(nlh);
	if (c->event == XFRM_MSG_DELPOLICY) {
	if (c->event == XFRM_MSG_DELPOLICY) {
		struct nlattr *attr;

		id = nlmsg_data(nlh);
		id = nlmsg_data(nlh);
		memset(id, 0, sizeof(*id));
		memset(id, 0, sizeof(*id));
		id->dir = dir;
		id->dir = dir;
@@ -2400,7 +2375,11 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
		else
		else
			memcpy(&id->sel, &xp->selector, sizeof(id->sel));
			memcpy(&id->sel, &xp->selector, sizeof(id->sel));


		p = RTA_DATA(__RTA_PUT(skb, XFRMA_POLICY, sizeof(*p)));
		attr = nla_reserve(skb, XFRMA_POLICY, sizeof(*p));
		if (attr == NULL)
			goto nlmsg_failure;

		p = nla_data(attr);
	}
	}


	copy_to_user_policy(xp, p, dir);
	copy_to_user_policy(xp, p, dir);
@@ -2414,7 +2393,6 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);


nlmsg_failure:
nlmsg_failure:
rtattr_failure:
	kfree_skb(skb);
	kfree_skb(skb);
	return -1;
	return -1;
}
}
@@ -2483,11 +2461,11 @@ static int build_report(struct sk_buff *skb, u8 proto,
	memcpy(&ur->sel, sel, sizeof(ur->sel));
	memcpy(&ur->sel, sel, sizeof(ur->sel));


	if (addr)
	if (addr)
		RTA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr);
		NLA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr);


	return nlmsg_end(skb, nlh);
	return nlmsg_end(skb, nlh);


rtattr_failure:
nla_put_failure:
	nlmsg_cancel(skb, nlh);
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
	return -EMSGSIZE;
}
}