Commit cfc61c59 authored by Florian Westphal's avatar Florian Westphal Committed by Steffen Klassert

xfrm: replay: avoid xfrm replay notify indirection

replay protection is implemented using a callback structure and then
called via

   x->repl->notify(), x->repl->recheck(), and so on.

all the differect functions are always built-in, so this could be direct
calls instead.

This first patch prepares for removal of the x->repl structure.
Add an enum with the three available replay modes to the xfrm_state
structure and then replace all x->repl->notify() calls by the new
xfrm_replay_notify() helper.

The helper checks the enum internally to adapt behaviour as needed.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 30ad6a84
...@@ -145,6 +145,12 @@ enum { ...@@ -145,6 +145,12 @@ enum {
XFRM_MODE_FLAG_TUNNEL = 1, XFRM_MODE_FLAG_TUNNEL = 1,
}; };
enum xfrm_replay_mode {
XFRM_REPLAY_MODE_LEGACY,
XFRM_REPLAY_MODE_BMP,
XFRM_REPLAY_MODE_ESN,
};
/* Full description of state of transformer. */ /* Full description of state of transformer. */
struct xfrm_state { struct xfrm_state {
possible_net_t xs_net; possible_net_t xs_net;
...@@ -218,6 +224,8 @@ struct xfrm_state { ...@@ -218,6 +224,8 @@ struct xfrm_state {
/* The functions for replay detection. */ /* The functions for replay detection. */
const struct xfrm_replay *repl; 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 /* internal flag that only holds state for delayed aevent at the
* moment * moment
*/ */
...@@ -305,7 +313,6 @@ struct xfrm_replay { ...@@ -305,7 +313,6 @@ struct xfrm_replay {
int (*recheck)(struct xfrm_state *x, int (*recheck)(struct xfrm_state *x,
struct sk_buff *skb, struct sk_buff *skb,
__be32 net_seq); __be32 net_seq);
void (*notify)(struct xfrm_state *x, int event);
int (*overflow)(struct xfrm_state *x, struct sk_buff *skb); int (*overflow)(struct xfrm_state *x, struct sk_buff *skb);
}; };
...@@ -1715,6 +1722,8 @@ static inline int xfrm_policy_id2dir(u32 index) ...@@ -1715,6 +1722,8 @@ static inline int xfrm_policy_id2dir(u32 index)
} }
#ifdef CONFIG_XFRM #ifdef CONFIG_XFRM
void xfrm_replay_notify(struct xfrm_state *x, int event);
static inline int xfrm_aevent_is_on(struct net *net) static inline int xfrm_aevent_is_on(struct net *net)
{ {
struct sock *nlsk; struct sock *nlsk;
......
...@@ -34,8 +34,11 @@ u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq) ...@@ -34,8 +34,11 @@ u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq)
return seq_hi; return seq_hi;
} }
EXPORT_SYMBOL(xfrm_replay_seqhi); EXPORT_SYMBOL(xfrm_replay_seqhi);
;
static void xfrm_replay_notify(struct xfrm_state *x, int event) static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event);
static void xfrm_replay_notify_esn(struct xfrm_state *x, int event);
void xfrm_replay_notify(struct xfrm_state *x, int event)
{ {
struct km_event c; struct km_event c;
/* we send notify messages in case /* we send notify messages in case
...@@ -48,6 +51,17 @@ static void xfrm_replay_notify(struct xfrm_state *x, int event) ...@@ -48,6 +51,17 @@ static void xfrm_replay_notify(struct xfrm_state *x, int event)
* The state structure must be locked! * The state structure must be locked!
*/ */
switch (x->repl_mode) {
case XFRM_REPLAY_MODE_LEGACY:
break;
case XFRM_REPLAY_MODE_BMP:
xfrm_replay_notify_bmp(x, event);
return;
case XFRM_REPLAY_MODE_ESN:
xfrm_replay_notify_esn(x, event);
return;
}
switch (event) { switch (event) {
case XFRM_REPLAY_UPDATE: case XFRM_REPLAY_UPDATE:
if (!x->replay_maxdiff || if (!x->replay_maxdiff ||
...@@ -98,7 +112,7 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb) ...@@ -98,7 +112,7 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
return err; return err;
} }
if (xfrm_aevent_is_on(net)) if (xfrm_aevent_is_on(net))
x->repl->notify(x, XFRM_REPLAY_UPDATE); xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
} }
return err; return err;
...@@ -157,7 +171,7 @@ static void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq) ...@@ -157,7 +171,7 @@ static void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
} }
if (xfrm_aevent_is_on(xs_net(x))) if (xfrm_aevent_is_on(xs_net(x)))
x->repl->notify(x, XFRM_REPLAY_UPDATE); xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
} }
static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb) static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb)
...@@ -178,7 +192,7 @@ static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb) ...@@ -178,7 +192,7 @@ static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb)
return err; return err;
} }
if (xfrm_aevent_is_on(net)) if (xfrm_aevent_is_on(net))
x->repl->notify(x, XFRM_REPLAY_UPDATE); xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
} }
return err; return err;
...@@ -273,7 +287,7 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq) ...@@ -273,7 +287,7 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq)
replay_esn->bmp[nr] |= (1U << bitnr); replay_esn->bmp[nr] |= (1U << bitnr);
if (xfrm_aevent_is_on(xs_net(x))) if (xfrm_aevent_is_on(xs_net(x)))
x->repl->notify(x, XFRM_REPLAY_UPDATE); xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
} }
static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event) static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event)
...@@ -416,7 +430,7 @@ static int xfrm_replay_overflow_esn(struct xfrm_state *x, struct sk_buff *skb) ...@@ -416,7 +430,7 @@ static int xfrm_replay_overflow_esn(struct xfrm_state *x, struct sk_buff *skb)
} }
} }
if (xfrm_aevent_is_on(net)) if (xfrm_aevent_is_on(net))
x->repl->notify(x, XFRM_REPLAY_UPDATE); xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
} }
return err; return err;
...@@ -548,7 +562,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq) ...@@ -548,7 +562,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
replay_esn->bmp[nr] |= (1U << bitnr); replay_esn->bmp[nr] |= (1U << bitnr);
if (xfrm_aevent_is_on(xs_net(x))) if (xfrm_aevent_is_on(xs_net(x)))
x->repl->notify(x, XFRM_REPLAY_UPDATE); xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
} }
#ifdef CONFIG_XFRM_OFFLOAD #ifdef CONFIG_XFRM_OFFLOAD
...@@ -585,7 +599,7 @@ static int xfrm_replay_overflow_offload(struct xfrm_state *x, struct sk_buff *sk ...@@ -585,7 +599,7 @@ static int xfrm_replay_overflow_offload(struct xfrm_state *x, struct sk_buff *sk
x->replay.oseq = oseq; x->replay.oseq = oseq;
if (xfrm_aevent_is_on(net)) if (xfrm_aevent_is_on(net))
x->repl->notify(x, XFRM_REPLAY_UPDATE); xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
} }
return err; return err;
...@@ -625,7 +639,7 @@ static int xfrm_replay_overflow_offload_bmp(struct xfrm_state *x, struct sk_buff ...@@ -625,7 +639,7 @@ static int xfrm_replay_overflow_offload_bmp(struct xfrm_state *x, struct sk_buff
} }
if (xfrm_aevent_is_on(net)) if (xfrm_aevent_is_on(net))
x->repl->notify(x, XFRM_REPLAY_UPDATE); xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
} }
return err; return err;
...@@ -674,7 +688,7 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff ...@@ -674,7 +688,7 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
replay_esn->oseq = oseq; replay_esn->oseq = oseq;
if (xfrm_aevent_is_on(net)) if (xfrm_aevent_is_on(net))
x->repl->notify(x, XFRM_REPLAY_UPDATE); xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
} }
return err; return err;
...@@ -684,7 +698,6 @@ static const struct xfrm_replay xfrm_replay_legacy = { ...@@ -684,7 +698,6 @@ static const struct xfrm_replay xfrm_replay_legacy = {
.advance = xfrm_replay_advance, .advance = xfrm_replay_advance,
.check = xfrm_replay_check, .check = xfrm_replay_check,
.recheck = xfrm_replay_check, .recheck = xfrm_replay_check,
.notify = xfrm_replay_notify,
.overflow = xfrm_replay_overflow_offload, .overflow = xfrm_replay_overflow_offload,
}; };
...@@ -692,7 +705,6 @@ static const struct xfrm_replay xfrm_replay_bmp = { ...@@ -692,7 +705,6 @@ static const struct xfrm_replay xfrm_replay_bmp = {
.advance = xfrm_replay_advance_bmp, .advance = xfrm_replay_advance_bmp,
.check = xfrm_replay_check_bmp, .check = xfrm_replay_check_bmp,
.recheck = xfrm_replay_check_bmp, .recheck = xfrm_replay_check_bmp,
.notify = xfrm_replay_notify_bmp,
.overflow = xfrm_replay_overflow_offload_bmp, .overflow = xfrm_replay_overflow_offload_bmp,
}; };
...@@ -700,7 +712,6 @@ static const struct xfrm_replay xfrm_replay_esn = { ...@@ -700,7 +712,6 @@ static const struct xfrm_replay xfrm_replay_esn = {
.advance = xfrm_replay_advance_esn, .advance = xfrm_replay_advance_esn,
.check = xfrm_replay_check_esn, .check = xfrm_replay_check_esn,
.recheck = xfrm_replay_recheck_esn, .recheck = xfrm_replay_recheck_esn,
.notify = xfrm_replay_notify_esn,
.overflow = xfrm_replay_overflow_offload_esn, .overflow = xfrm_replay_overflow_offload_esn,
}; };
#else #else
...@@ -708,7 +719,6 @@ static const struct xfrm_replay xfrm_replay_legacy = { ...@@ -708,7 +719,6 @@ static const struct xfrm_replay xfrm_replay_legacy = {
.advance = xfrm_replay_advance, .advance = xfrm_replay_advance,
.check = xfrm_replay_check, .check = xfrm_replay_check,
.recheck = xfrm_replay_check, .recheck = xfrm_replay_check,
.notify = xfrm_replay_notify,
.overflow = xfrm_replay_overflow, .overflow = xfrm_replay_overflow,
}; };
...@@ -716,7 +726,6 @@ static const struct xfrm_replay xfrm_replay_bmp = { ...@@ -716,7 +726,6 @@ static const struct xfrm_replay xfrm_replay_bmp = {
.advance = xfrm_replay_advance_bmp, .advance = xfrm_replay_advance_bmp,
.check = xfrm_replay_check_bmp, .check = xfrm_replay_check_bmp,
.recheck = xfrm_replay_check_bmp, .recheck = xfrm_replay_check_bmp,
.notify = xfrm_replay_notify_bmp,
.overflow = xfrm_replay_overflow_bmp, .overflow = xfrm_replay_overflow_bmp,
}; };
...@@ -724,7 +733,6 @@ static const struct xfrm_replay xfrm_replay_esn = { ...@@ -724,7 +733,6 @@ static const struct xfrm_replay xfrm_replay_esn = {
.advance = xfrm_replay_advance_esn, .advance = xfrm_replay_advance_esn,
.check = xfrm_replay_check_esn, .check = xfrm_replay_check_esn,
.recheck = xfrm_replay_recheck_esn, .recheck = xfrm_replay_recheck_esn,
.notify = xfrm_replay_notify_esn,
.overflow = xfrm_replay_overflow_esn, .overflow = xfrm_replay_overflow_esn,
}; };
#endif #endif
...@@ -742,11 +750,14 @@ int xfrm_init_replay(struct xfrm_state *x) ...@@ -742,11 +750,14 @@ int xfrm_init_replay(struct xfrm_state *x)
if (replay_esn->replay_window == 0) if (replay_esn->replay_window == 0)
return -EINVAL; return -EINVAL;
x->repl = &xfrm_replay_esn; x->repl = &xfrm_replay_esn;
x->repl_mode = XFRM_REPLAY_MODE_ESN;
} else { } else {
x->repl = &xfrm_replay_bmp; x->repl = &xfrm_replay_bmp;
x->repl_mode = XFRM_REPLAY_MODE_BMP;
} }
} else { } else {
x->repl = &xfrm_replay_legacy; x->repl = &xfrm_replay_legacy;
x->repl_mode = XFRM_REPLAY_MODE_LEGACY;
} }
return 0; return 0;
......
...@@ -2177,7 +2177,7 @@ static void xfrm_replay_timer_handler(struct timer_list *t) ...@@ -2177,7 +2177,7 @@ static void xfrm_replay_timer_handler(struct timer_list *t)
if (x->km.state == XFRM_STATE_VALID) { if (x->km.state == XFRM_STATE_VALID) {
if (xfrm_aevent_is_on(xs_net(x))) if (xfrm_aevent_is_on(xs_net(x)))
x->repl->notify(x, XFRM_REPLAY_TIMEOUT); xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT);
else else
x->xflags |= XFRM_TIME_DEFER; x->xflags |= XFRM_TIME_DEFER;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment