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

Commit 78f10c55 authored by Steffen Klassert's avatar Steffen Klassert Committed by Benedict Wong
Browse files

BACKPORT: xfrm: Extend the output_mark to support input direction and masking.



We already support setting an output mark at the xfrm_state,
unfortunately this does not support the input direction and
masking the marks that will be applied to the skb. This change
adds support applying a masked value in both directions.

The existing XFRMA_OUTPUT_MARK number is reused for this purpose
and as it is now bi-directional, it is renamed to XFRMA_SET_MARK.

An additional XFRMA_SET_MARK_MASK attribute is added for setting the
mask. If the attribute mask not provided, it is set to 0xffffffff,
keeping the XFRMA_OUTPUT_MARK existing 'full mask' semantics.

Co-developed-by: default avatarTobias Brunner <tobias@strongswan.org>
Co-developed-by: default avatarEyal Birger <eyal.birger@gmail.com>
Co-developed-by: default avatarLorenzo Colitti <lorenzo@google.com>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: default avatarTobias Brunner <tobias@strongswan.org>
Signed-off-by: default avatarEyal Birger <eyal.birger@gmail.com>
Signed-off-by: default avatarLorenzo Colitti <lorenzo@google.com>

Conflicts: XFRM OFFLOAD not previously backported; removed incompatible
device offload copying in xfrm_user.c, xfrm_device.c

(cherry picked from commit 9b42c1f179a614e11893ae4619f0304a38f481ae)
Signed-off-by: default avatarBenedict Wong <benedictwong@google.com>
Bug: 115914689
Change-Id: I9f554d1697a72ef5668e5251d560cc1ba4d0ab07
parent 0e51f102
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -155,7 +155,7 @@ struct xfrm_state {
		int		header_len;
		int		trailer_len;
		u32		extra_flags;
		u32		output_mark;
		struct xfrm_mark	smark;
	} props;

	struct xfrm_lifetime_cfg lft;
@@ -1788,6 +1788,13 @@ static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
	return ret;
}

static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
{
	struct xfrm_mark *m = &x->props.smark;

	return (m->v & m->m) | (mark & ~m->m);
}

static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
				    unsigned int family)
{
+3 −1
Original line number Diff line number Diff line
@@ -304,9 +304,11 @@ enum xfrm_attr_type_t {
	XFRMA_ADDRESS_FILTER,	/* struct xfrm_address_filter */
	XFRMA_PAD,
	XFRMA_OFFLOAD_DEV,	/* struct xfrm_state_offload */
	XFRMA_OUTPUT_MARK,	/* __u32 */
	XFRMA_SET_MARK,		/* __u32 */
	XFRMA_SET_MARK_MASK,	/* __u32 */
	__XFRMA_MAX

#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK	/* Compatibility */
#define XFRMA_MAX (__XFRMA_MAX - 1)
};

+2 −0
Original line number Diff line number Diff line
@@ -251,6 +251,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
			goto drop;
		}

		skb->mark = xfrm_smark_get(skb->mark, x);

		skb->sp->xvec[skb->sp->len++] = x;

		spin_lock(&x->lock);
+1 −2
Original line number Diff line number Diff line
@@ -66,8 +66,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
			goto error_nolock;
		}

		if (x->props.output_mark)
			skb->mark = x->props.output_mark;
		skb->mark = xfrm_smark_get(skb->mark, x);

		err = x->outer_mode->output(x, skb);
		if (err) {
+3 −2
Original line number Diff line number Diff line
@@ -1750,10 +1750,11 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
		dst_copy_metrics(dst1, dst);

		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
			__u32 mark = xfrm_smark_get(fl->flowi_mark, xfrm[i]);

			family = xfrm[i]->props.family;
			dst = xfrm_dst_lookup(xfrm[i], tos, fl->flowi_oif,
					      &saddr, &daddr, family,
					      xfrm[i]->props.output_mark);
					      &saddr, &daddr, family, mark);
			err = PTR_ERR(dst);
			if (IS_ERR(dst))
				goto put_states;
Loading