Commit b5a1d1fe authored by Florian Westphal's avatar Florian Westphal Committed by Steffen Klassert
Browse files

xfrm: replay: remove last replay indirection



This replaces the overflow indirection with the new xfrm_replay_overflow
helper.  After this, the 'repl' pointer in xfrm_state is no longer
needed and can be removed as well.

xfrm_replay_overflow() is added in two incarnations, one is used
when the kernel is compiled with xfrm hardware offload support enabled,
the other when its disabled.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent adfc2fdb
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -221,9 +221,6 @@ struct xfrm_state {
	struct xfrm_replay_state preplay;
	struct xfrm_replay_state_esn *preplay_esn;

	/* The functions for replay detection. */
	const struct xfrm_replay *repl;

	/* replay detection mode */
	enum xfrm_replay_mode    repl_mode;
	/* internal flag that only holds state for delayed aevent at the
@@ -305,10 +302,6 @@ struct km_event {
	struct net *net;
};

struct xfrm_replay {
	int	(*overflow)(struct xfrm_state *x, struct sk_buff *skb);
};

struct xfrm_if_cb {
	struct xfrm_if	*(*decode_session)(struct sk_buff *skb,
					   unsigned short family);
@@ -1718,6 +1711,7 @@ static inline int xfrm_policy_id2dir(u32 index)
void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq);
int xfrm_replay_check(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
void xfrm_replay_notify(struct xfrm_state *x, int event);
int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb);
int xfrm_replay_recheck(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);

static inline int xfrm_aevent_is_on(struct net *net)
+1 −1
Original line number Diff line number Diff line
@@ -525,7 +525,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
			goto error;
		}

		err = x->repl->overflow(x, skb);
		err = xfrm_replay_overflow(x, skb);
		if (err) {
			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATESEQERROR);
			goto error;
+26 −25
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ void xfrm_replay_notify(struct xfrm_state *x, int event)
		x->xflags &= ~XFRM_TIME_DEFER;
}

static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
static int __xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
{
	int err = 0;
	struct net *net = xs_net(x);
@@ -617,7 +617,7 @@ static int xfrm_replay_overflow_offload(struct xfrm_state *x, struct sk_buff *sk
	__u32 oseq = x->replay.oseq;

	if (!xo)
		return xfrm_replay_overflow(x, skb);
		return __xfrm_replay_overflow(x, skb);

	if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
		if (!skb_is_gso(skb)) {
@@ -737,29 +737,33 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
	return err;
}

static const struct xfrm_replay xfrm_replay_legacy = {
	.overflow	= xfrm_replay_overflow_offload,
};

static const struct xfrm_replay xfrm_replay_bmp = {
	.overflow	= xfrm_replay_overflow_offload_bmp,
};
int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
{
	switch (x->repl_mode) {
	case XFRM_REPLAY_MODE_LEGACY:
		break;
	case XFRM_REPLAY_MODE_BMP:
		return xfrm_replay_overflow_offload_bmp(x, skb);
	case XFRM_REPLAY_MODE_ESN:
		return xfrm_replay_overflow_offload_esn(x, skb);
	}

static const struct xfrm_replay xfrm_replay_esn = {
	.overflow	= xfrm_replay_overflow_offload_esn,
};
	return xfrm_replay_overflow_offload(x, skb);
}
#else
static const struct xfrm_replay xfrm_replay_legacy = {
	.overflow	= xfrm_replay_overflow,
};

static const struct xfrm_replay xfrm_replay_bmp = {
	.overflow	= xfrm_replay_overflow_bmp,
};
int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
{
	switch (x->repl_mode) {
	case XFRM_REPLAY_MODE_LEGACY:
		break;
	case XFRM_REPLAY_MODE_BMP:
		return xfrm_replay_overflow_bmp(x, skb);
	case XFRM_REPLAY_MODE_ESN:
		return xfrm_replay_overflow_esn(x, skb);
	}

static const struct xfrm_replay xfrm_replay_esn = {
	.overflow	= xfrm_replay_overflow_esn,
};
	return __xfrm_replay_overflow(x, skb);
}
#endif

int xfrm_init_replay(struct xfrm_state *x)
@@ -774,14 +778,11 @@ int xfrm_init_replay(struct xfrm_state *x)
		if (x->props.flags & XFRM_STATE_ESN) {
			if (replay_esn->replay_window == 0)
				return -EINVAL;
			x->repl = &xfrm_replay_esn;
			x->repl_mode = XFRM_REPLAY_MODE_ESN;
		} else {
			x->repl = &xfrm_replay_bmp;
			x->repl_mode = XFRM_REPLAY_MODE_BMP;
		}
	} else {
		x->repl = &xfrm_replay_legacy;
		x->repl_mode = XFRM_REPLAY_MODE_LEGACY;
	}