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 configured with xfrm offload enabled, the other
when its disabled.

Signed-off-by: Florian Westphal <f...@strlen.de>
---
 include/net/xfrm.h     |  8 +------
 net/xfrm/xfrm_output.c |  2 +-
 net/xfrm/xfrm_replay.c | 51 +++++++++++++++++++++---------------------
 3 files changed, 28 insertions(+), 33 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 008b564cb126..c0f3e8a3fdd0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -219,9 +219,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
@@ -303,10 +300,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);
@@ -1715,6 +1708,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)
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index e4c23f69f69f..8893a37690ad 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -448,7 +448,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;
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 8c97fcaf17cf..7630d002107b 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -97,7 +97,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);
@@ -601,7 +601,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)) {
@@ -719,29 +719,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)
@@ -756,14 +760,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;
        }
 
-- 
2.26.2

Reply via email to