diff options
| author | 2018-08-28 09:58:03 -0700 | |
|---|---|---|
| committer | 2018-08-28 09:58:03 -0700 | |
| commit | ea4d65f14f6aaa53e379b93c5544245ef081b3e7 (patch) | |
| tree | a15485f4f1cf547a52b31fa8e16e14b9579b7200 /net/xfrm/xfrm_user.c | |
| parent | arm: dts: am4372: setup rtc as system-power-controller (diff) | |
| parent | ARM: dts: Fix file permission for am335x-osd3358-sm-red.dts (diff) | |
| download | wireguard-linux-ea4d65f14f6aaa53e379b93c5544245ef081b3e7.tar.xz wireguard-linux-ea4d65f14f6aaa53e379b93c5544245ef081b3e7.zip  | |
Merge branch 'perm-fix' into omap-for-v4.19/fixes-v2
Diffstat (limited to 'net/xfrm/xfrm_user.c')
| -rw-r--r-- | net/xfrm/xfrm_user.c | 95 | 
1 files changed, 82 insertions, 13 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 33878e6e0d0a..4791aa8b8185 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -527,6 +527,19 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs,  		x->replay_maxdiff = nla_get_u32(rt);  } +static void xfrm_smark_init(struct nlattr **attrs, struct xfrm_mark *m) +{ +	if (attrs[XFRMA_SET_MARK]) { +		m->v = nla_get_u32(attrs[XFRMA_SET_MARK]); +		if (attrs[XFRMA_SET_MARK_MASK]) +			m->m = nla_get_u32(attrs[XFRMA_SET_MARK_MASK]); +		else +			m->m = 0xffffffff; +	} else { +		m->v = m->m = 0; +	} +} +  static struct xfrm_state *xfrm_state_construct(struct net *net,  					       struct xfrm_usersa_info *p,  					       struct nlattr **attrs, @@ -579,8 +592,10 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,  	xfrm_mark_get(attrs, &x->mark); -	if (attrs[XFRMA_OUTPUT_MARK]) -		x->props.output_mark = nla_get_u32(attrs[XFRMA_OUTPUT_MARK]); +	xfrm_smark_init(attrs, &x->props.smark); + +	if (attrs[XFRMA_IF_ID]) +		x->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);  	err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]);  	if (err) @@ -824,6 +839,18 @@ static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb)  	return 0;  } +static int xfrm_smark_put(struct sk_buff *skb, struct xfrm_mark *m) +{ +	int ret = 0; + +	if (m->v | m->m) { +		ret = nla_put_u32(skb, XFRMA_SET_MARK, m->v); +		if (!ret) +			ret = nla_put_u32(skb, XFRMA_SET_MARK_MASK, m->m); +	} +	return ret; +} +  /* Don't change this without updating xfrm_sa_len! */  static int copy_to_user_state_extra(struct xfrm_state *x,  				    struct xfrm_usersa_info *p, @@ -887,6 +914,11 @@ static int copy_to_user_state_extra(struct xfrm_state *x,  	ret = xfrm_mark_put(skb, &x->mark);  	if (ret)  		goto out; + +	ret = xfrm_smark_put(skb, &x->props.smark); +	if (ret) +		goto out; +  	if (x->replay_esn)  		ret = nla_put(skb, XFRMA_REPLAY_ESN_VAL,  			      xfrm_replay_state_esn_len(x->replay_esn), @@ -900,8 +932,8 @@ static int copy_to_user_state_extra(struct xfrm_state *x,  		ret = copy_user_offload(&x->xso, skb);  	if (ret)  		goto out; -	if (x->props.output_mark) { -		ret = nla_put_u32(skb, XFRMA_OUTPUT_MARK, x->props.output_mark); +	if (x->if_id) { +		ret = nla_put_u32(skb, XFRMA_IF_ID, x->if_id);  		if (ret)  			goto out;  	} @@ -1255,6 +1287,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,  	int err;  	u32 mark;  	struct xfrm_mark m; +	u32 if_id = 0;  	p = nlmsg_data(nlh);  	err = verify_spi_info(p->info.id.proto, p->min, p->max); @@ -1267,6 +1300,10 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,  	x = NULL;  	mark = xfrm_mark_get(attrs, &m); + +	if (attrs[XFRMA_IF_ID]) +		if_id = nla_get_u32(attrs[XFRMA_IF_ID]); +  	if (p->info.seq) {  		x = xfrm_find_acq_byseq(net, mark, p->info.seq);  		if (x && !xfrm_addr_equal(&x->id.daddr, daddr, family)) { @@ -1277,7 +1314,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,  	if (!x)  		x = xfrm_find_acq(net, &m, p->info.mode, p->info.reqid, -				  p->info.id.proto, daddr, +				  if_id, p->info.id.proto, daddr,  				  &p->info.saddr, 1,  				  family);  	err = -ENOENT; @@ -1565,6 +1602,9 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us  	xfrm_mark_get(attrs, &xp->mark); +	if (attrs[XFRMA_IF_ID]) +		xp->if_id = nla_get_u32(attrs[XFRMA_IF_ID]); +  	return xp;   error:  	*errp = err; @@ -1712,6 +1752,8 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr  		err = copy_to_user_policy_type(xp->type, skb);  	if (!err)  		err = xfrm_mark_put(skb, &xp->mark); +	if (!err) +		err = xfrm_if_id_put(skb, xp->if_id);  	if (err) {  		nlmsg_cancel(skb, nlh);  		return err; @@ -1793,6 +1835,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,  	int delete;  	struct xfrm_mark m;  	u32 mark = xfrm_mark_get(attrs, &m); +	u32 if_id = 0;  	p = nlmsg_data(nlh);  	delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; @@ -1805,8 +1848,11 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,  	if (err)  		return err; +	if (attrs[XFRMA_IF_ID]) +		if_id = nla_get_u32(attrs[XFRMA_IF_ID]); +  	if (p->index) -		xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, delete, &err); +		xp = xfrm_policy_byid(net, mark, if_id, type, p->dir, p->index, delete, &err);  	else {  		struct nlattr *rt = attrs[XFRMA_SEC_CTX];  		struct xfrm_sec_ctx *ctx; @@ -1823,7 +1869,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,  			if (err)  				return err;  		} -		xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir, &p->sel, +		xp = xfrm_policy_bysel_ctx(net, mark, if_id, type, p->dir, &p->sel,  					   ctx, delete, &err);  		security_xfrm_policy_free(ctx);  	} @@ -1946,6 +1992,10 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct  	if (err)  		goto out_cancel; +	err = xfrm_if_id_put(skb, x->if_id); +	if (err) +		goto out_cancel; +  	nlmsg_end(skb, nlh);  	return 0; @@ -2088,6 +2138,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,  	int err = -ENOENT;  	struct xfrm_mark m;  	u32 mark = xfrm_mark_get(attrs, &m); +	u32 if_id = 0;  	err = copy_from_user_policy_type(&type, attrs);  	if (err) @@ -2097,8 +2148,11 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,  	if (err)  		return err; +	if (attrs[XFRMA_IF_ID]) +		if_id = nla_get_u32(attrs[XFRMA_IF_ID]); +  	if (p->index) -		xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, 0, &err); +		xp = xfrm_policy_byid(net, mark, if_id, type, p->dir, p->index, 0, &err);  	else {  		struct nlattr *rt = attrs[XFRMA_SEC_CTX];  		struct xfrm_sec_ctx *ctx; @@ -2115,7 +2169,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,  			if (err)  				return err;  		} -		xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir, +		xp = xfrm_policy_bysel_ctx(net, mark, if_id, type, p->dir,  					   &p->sel, ctx, 0, &err);  		security_xfrm_policy_free(ctx);  	} @@ -2497,7 +2551,9 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {  	[XFRMA_PROTO]		= { .type = NLA_U8 },  	[XFRMA_ADDRESS_FILTER]	= { .len = sizeof(struct xfrm_address_filter) },  	[XFRMA_OFFLOAD_DEV]	= { .len = sizeof(struct xfrm_user_offload) }, -	[XFRMA_OUTPUT_MARK]	= { .type = NLA_U32 }, +	[XFRMA_SET_MARK]	= { .type = NLA_U32 }, +	[XFRMA_SET_MARK_MASK]	= { .type = NLA_U32 }, +	[XFRMA_IF_ID]		= { .type = NLA_U32 },  };  static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { @@ -2629,6 +2685,10 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, const struct  	if (err)  		return err; +	err = xfrm_if_id_put(skb, x->if_id); +	if (err) +		return err; +  	nlmsg_end(skb, nlh);  	return 0;  } @@ -2723,8 +2783,12 @@ static inline unsigned int xfrm_sa_len(struct xfrm_state *x)  		l += nla_total_size(sizeof(x->props.extra_flags));  	if (x->xso.dev)  		 l += nla_total_size(sizeof(x->xso)); -	if (x->props.output_mark) -		l += nla_total_size(sizeof(x->props.output_mark)); +	if (x->props.smark.v | x->props.smark.m) { +		l += nla_total_size(sizeof(x->props.smark.v)); +		l += nla_total_size(sizeof(x->props.smark.m)); +	} +	if (x->if_id) +		l += nla_total_size(sizeof(x->if_id));  	/* Must count x->lastused as it may become non-zero behind our back. */  	l += nla_total_size_64bit(sizeof(u64)); @@ -2854,6 +2918,8 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,  		err = copy_to_user_policy_type(xp->type, skb);  	if (!err)  		err = xfrm_mark_put(skb, &xp->mark); +	if (!err) +		err = xfrm_if_id_put(skb, xp->if_id);  	if (err) {  		nlmsg_cancel(skb, nlh);  		return err; @@ -2970,6 +3036,8 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,  		err = copy_to_user_policy_type(xp->type, skb);  	if (!err)  		err = xfrm_mark_put(skb, &xp->mark); +	if (!err) +		err = xfrm_if_id_put(skb, xp->if_id);  	if (err) {  		nlmsg_cancel(skb, nlh);  		return err; @@ -3051,6 +3119,8 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, const struct km_e  		err = copy_to_user_policy_type(xp->type, skb);  	if (!err)  		err = xfrm_mark_put(skb, &xp->mark); +	if (!err) +		err = xfrm_if_id_put(skb, xp->if_id);  	if (err)  		goto out_free_skb; @@ -3284,4 +3354,3 @@ module_init(xfrm_user_init);  module_exit(xfrm_user_exit);  MODULE_LICENSE("GPL");  MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_XFRM); -  | 
