* [PATCH ipsec-next v2 0/6] xfrm: remove xfrm replay indirections
@ 2020-06-24 8:07 Florian Westphal
2020-06-24 8:07 ` [PATCH ipsec-next v2 1/6] xfrm: replay: avoid xfrm replay notify indirection Florian Westphal
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Florian Westphal @ 2020-06-24 8:07 UTC (permalink / raw)
To: steffen.klassert; +Cc: netdev
v2: fix unitialized variable buf reported by kbuild robot.
The xfrm replay logic is implemented via indirect calls.
xfrm_state struct holds a pointer to a
'struct xfrm_replay', which is one of several replay protection
backends.
XFRM then invokes the backend via state->repl->callback().
Due to retpoline all indirect calls have become a lot more
expensive. Fortunately, there are no 'replay modules', all are available
for direct calls.
This series removes the 'struct xfrm_replay' and adds replay
functions that can be called instead of the redirection.
Example:
- err = x->repl->overflow(x, skb);
+ err = xfrm_replay_overflow(x, skb);
Instead of a pointer to a struct with function pointers, xfrm_state
now holds an enum that tells the replay core what kind of replay
test is to be done.
Florian Westphal (6):
xfrm: replay: avoid xfrm replay notify indirection
xfrm: replay: get rid of duplicated notification code
xfrm: replay: remove advance indirection
xfrm: replay: remove recheck indirection
xfrm: replay: avoid replay indirection
xfrm: replay: remove last replay indirection
include/net/xfrm.h | 29 ++++----
net/xfrm/xfrm_input.c | 6 +-
net/xfrm/xfrm_output.c | 2 +-
net/xfrm/xfrm_replay.c | 189 +++++++++++++++++++++++++++----------------------
net/xfrm/xfrm_state.c | 2 +-
5 files changed, 125 insertions(+), 103 deletions(-)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH ipsec-next v2 1/6] xfrm: replay: avoid xfrm replay notify indirection
2020-06-24 8:07 [PATCH ipsec-next v2 0/6] xfrm: remove xfrm replay indirections Florian Westphal
@ 2020-06-24 8:07 ` Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 2/6] xfrm: replay: get rid of duplicated notification code Florian Westphal
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2020-06-24 8:07 UTC (permalink / raw)
To: steffen.klassert; +Cc: netdev, Florian Westphal
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: Florian Westphal <fw@strlen.de>
---
include/net/xfrm.h | 11 ++++++++++-
net/xfrm/xfrm_replay.c | 45 ++++++++++++++++++++++++++----------------
net/xfrm/xfrm_state.c | 2 +-
3 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index e20b2b27ec48..ed105257c5a8 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -144,6 +144,12 @@ enum {
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. */
struct xfrm_state {
possible_net_t xs_net;
@@ -216,6 +222,8 @@ struct xfrm_state {
/* 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
* moment
*/
@@ -303,7 +311,6 @@ struct xfrm_replay {
int (*recheck)(struct xfrm_state *x,
struct sk_buff *skb,
__be32 net_seq);
- void (*notify)(struct xfrm_state *x, int event);
int (*overflow)(struct xfrm_state *x, struct sk_buff *skb);
};
@@ -1712,6 +1719,8 @@ static inline int xfrm_policy_id2dir(u32 index)
}
#ifdef CONFIG_XFRM
+void xfrm_replay_notify(struct xfrm_state *x, int event);
+
static inline int xfrm_aevent_is_on(struct net *net)
{
struct sock *nlsk;
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 98943f8d01aa..e42a7afb8ee5 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -34,8 +34,11 @@ u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq)
return seq_hi;
}
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;
/* we send notify messages in case
@@ -48,6 +51,17 @@ static void xfrm_replay_notify(struct xfrm_state *x, int event)
* 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) {
case XFRM_REPLAY_UPDATE:
if (!x->replay_maxdiff ||
@@ -97,7 +111,7 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
return err;
}
if (xfrm_aevent_is_on(net))
- x->repl->notify(x, XFRM_REPLAY_UPDATE);
+ xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
return err;
@@ -156,7 +170,7 @@ static void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
}
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)
@@ -176,7 +190,7 @@ static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb)
return err;
}
if (xfrm_aevent_is_on(net))
- x->repl->notify(x, XFRM_REPLAY_UPDATE);
+ xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
return err;
@@ -271,7 +285,7 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq)
replay_esn->bmp[nr] |= (1U << bitnr);
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)
@@ -414,7 +428,7 @@ static int xfrm_replay_overflow_esn(struct xfrm_state *x, struct sk_buff *skb)
}
}
if (xfrm_aevent_is_on(net))
- x->repl->notify(x, XFRM_REPLAY_UPDATE);
+ xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
return err;
@@ -546,7 +560,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
replay_esn->bmp[nr] |= (1U << bitnr);
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
@@ -582,7 +596,7 @@ static int xfrm_replay_overflow_offload(struct xfrm_state *x, struct sk_buff *sk
x->replay.oseq = oseq;
if (xfrm_aevent_is_on(net))
- x->repl->notify(x, XFRM_REPLAY_UPDATE);
+ xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
return err;
@@ -621,7 +635,7 @@ static int xfrm_replay_overflow_offload_bmp(struct xfrm_state *x, struct sk_buff
}
if (xfrm_aevent_is_on(net))
- x->repl->notify(x, XFRM_REPLAY_UPDATE);
+ xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
return err;
@@ -670,7 +684,7 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
replay_esn->oseq = oseq;
if (xfrm_aevent_is_on(net))
- x->repl->notify(x, XFRM_REPLAY_UPDATE);
+ xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
return err;
@@ -680,7 +694,6 @@ static const struct xfrm_replay xfrm_replay_legacy = {
.advance = xfrm_replay_advance,
.check = xfrm_replay_check,
.recheck = xfrm_replay_check,
- .notify = xfrm_replay_notify,
.overflow = xfrm_replay_overflow_offload,
};
@@ -688,7 +701,6 @@ static const struct xfrm_replay xfrm_replay_bmp = {
.advance = xfrm_replay_advance_bmp,
.check = xfrm_replay_check_bmp,
.recheck = xfrm_replay_check_bmp,
- .notify = xfrm_replay_notify_bmp,
.overflow = xfrm_replay_overflow_offload_bmp,
};
@@ -696,7 +708,6 @@ static const struct xfrm_replay xfrm_replay_esn = {
.advance = xfrm_replay_advance_esn,
.check = xfrm_replay_check_esn,
.recheck = xfrm_replay_recheck_esn,
- .notify = xfrm_replay_notify_esn,
.overflow = xfrm_replay_overflow_offload_esn,
};
#else
@@ -704,7 +715,6 @@ static const struct xfrm_replay xfrm_replay_legacy = {
.advance = xfrm_replay_advance,
.check = xfrm_replay_check,
.recheck = xfrm_replay_check,
- .notify = xfrm_replay_notify,
.overflow = xfrm_replay_overflow,
};
@@ -712,7 +722,6 @@ static const struct xfrm_replay xfrm_replay_bmp = {
.advance = xfrm_replay_advance_bmp,
.check = xfrm_replay_check_bmp,
.recheck = xfrm_replay_check_bmp,
- .notify = xfrm_replay_notify_bmp,
.overflow = xfrm_replay_overflow_bmp,
};
@@ -720,7 +729,6 @@ static const struct xfrm_replay xfrm_replay_esn = {
.advance = xfrm_replay_advance_esn,
.check = xfrm_replay_check_esn,
.recheck = xfrm_replay_recheck_esn,
- .notify = xfrm_replay_notify_esn,
.overflow = xfrm_replay_overflow_esn,
};
#endif
@@ -738,11 +746,14 @@ int xfrm_init_replay(struct xfrm_state *x)
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;
}
return 0;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 8be2d926acc2..c51bbcc263c7 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2110,7 +2110,7 @@ static void xfrm_replay_timer_handler(struct timer_list *t)
if (x->km.state == XFRM_STATE_VALID) {
if (xfrm_aevent_is_on(xs_net(x)))
- x->repl->notify(x, XFRM_REPLAY_TIMEOUT);
+ xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT);
else
x->xflags |= XFRM_TIME_DEFER;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH ipsec-next v2 2/6] xfrm: replay: get rid of duplicated notification code
2020-06-24 8:07 [PATCH ipsec-next v2 0/6] xfrm: remove xfrm replay indirections Florian Westphal
2020-06-24 8:07 ` [PATCH ipsec-next v2 1/6] xfrm: replay: avoid xfrm replay notify indirection Florian Westphal
@ 2020-06-24 8:08 ` Florian Westphal
2020-06-25 7:07 ` Sabrina Dubroca
2020-06-24 8:08 ` [PATCH ipsec-next v2 3/6] xfrm: replay: remove advance indirection Florian Westphal
` (3 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Florian Westphal @ 2020-06-24 8:08 UTC (permalink / raw)
To: steffen.klassert; +Cc: netdev, Florian Westphal
After previous patch, we can consolidate some code:
xfrm_replay_notify, xfrm_replay_notify_bmp and _esn all contain the
same code at the end.
Remove it from xfrm_replay_notify_bmp/esn and reuse the one
in xfrm_replay_notify.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/xfrm/xfrm_replay.c | 22 ++++------------------
1 file changed, 4 insertions(+), 18 deletions(-)
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index e42a7afb8ee5..fac2f3af4c1a 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -56,10 +56,10 @@ void xfrm_replay_notify(struct xfrm_state *x, int event)
break;
case XFRM_REPLAY_MODE_BMP:
xfrm_replay_notify_bmp(x, event);
- return;
+ goto notify;
case XFRM_REPLAY_MODE_ESN:
xfrm_replay_notify_esn(x, event);
- return;
+ goto notify;
}
switch (event) {
@@ -86,6 +86,8 @@ void xfrm_replay_notify(struct xfrm_state *x, int event)
}
memcpy(&x->preplay, &x->replay, sizeof(struct xfrm_replay_state));
+
+notify:
c.event = XFRM_MSG_NEWAE;
c.data.aevent = event;
km_state_notify(x, &c);
@@ -290,7 +292,6 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq)
static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event)
{
- struct km_event c;
struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn;
@@ -330,19 +331,11 @@ static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event)
memcpy(x->preplay_esn, x->replay_esn,
xfrm_replay_state_esn_len(replay_esn));
- c.event = XFRM_MSG_NEWAE;
- c.data.aevent = event;
- km_state_notify(x, &c);
-
- if (x->replay_maxage &&
- !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
- x->xflags &= ~XFRM_TIME_DEFER;
}
static void xfrm_replay_notify_esn(struct xfrm_state *x, int event)
{
u32 seq_diff, oseq_diff;
- struct km_event c;
struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn;
@@ -396,13 +389,6 @@ static void xfrm_replay_notify_esn(struct xfrm_state *x, int event)
memcpy(x->preplay_esn, x->replay_esn,
xfrm_replay_state_esn_len(replay_esn));
- c.event = XFRM_MSG_NEWAE;
- c.data.aevent = event;
- km_state_notify(x, &c);
-
- if (x->replay_maxage &&
- !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
- x->xflags &= ~XFRM_TIME_DEFER;
}
static int xfrm_replay_overflow_esn(struct xfrm_state *x, struct sk_buff *skb)
--
2.26.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH ipsec-next v2 3/6] xfrm: replay: remove advance indirection
2020-06-24 8:07 [PATCH ipsec-next v2 0/6] xfrm: remove xfrm replay indirections Florian Westphal
2020-06-24 8:07 ` [PATCH ipsec-next v2 1/6] xfrm: replay: avoid xfrm replay notify indirection Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 2/6] xfrm: replay: get rid of duplicated notification code Florian Westphal
@ 2020-06-24 8:08 ` Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 4/6] xfrm: replay: remove recheck indirection Florian Westphal
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2020-06-24 8:08 UTC (permalink / raw)
To: steffen.klassert; +Cc: netdev, Florian Westphal
Similar to other patches: add a new helper to avoid
an indirection.
v2: fix 'net/xfrm/xfrm_replay.c:519:13: warning: 'seq' may be used
uninitialized in this function' warning.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/net/xfrm.h | 2 +-
net/xfrm/xfrm_input.c | 2 +-
net/xfrm/xfrm_replay.c | 24 +++++++++++++++---------
3 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index ed105257c5a8..78bbfd370e34 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -304,7 +304,6 @@ struct km_event {
};
struct xfrm_replay {
- void (*advance)(struct xfrm_state *x, __be32 net_seq);
int (*check)(struct xfrm_state *x,
struct sk_buff *skb,
__be32 net_seq);
@@ -1719,6 +1718,7 @@ static inline int xfrm_policy_id2dir(u32 index)
}
#ifdef CONFIG_XFRM
+void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq);
void xfrm_replay_notify(struct xfrm_state *x, int event);
static inline int xfrm_aevent_is_on(struct net *net)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index bd984ff17c2d..b4b559b35cf1 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -663,7 +663,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop_unlock;
}
- x->repl->advance(x, seq);
+ xfrm_replay_advance(x, seq);
x->curlft.bytes += skb->len;
x->curlft.packets++;
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index fac2f3af4c1a..460f438bd138 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -151,14 +151,26 @@ static int xfrm_replay_check(struct xfrm_state *x,
return -EINVAL;
}
-static void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
+static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq);
+static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq);
+
+void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
{
- u32 diff;
- u32 seq = ntohl(net_seq);
+ u32 diff, seq;
+
+ switch (x->repl_mode) {
+ case XFRM_REPLAY_MODE_LEGACY:
+ break;
+ case XFRM_REPLAY_MODE_BMP:
+ return xfrm_replay_advance_bmp(x, net_seq);
+ case XFRM_REPLAY_MODE_ESN:
+ return xfrm_replay_advance_esn(x, net_seq);
+ }
if (!x->props.replay_window)
return;
+ seq = ntohl(net_seq);
if (seq > x->replay.seq) {
diff = seq - x->replay.seq;
if (diff < x->props.replay_window)
@@ -677,42 +689,36 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
}
static const struct xfrm_replay xfrm_replay_legacy = {
- .advance = xfrm_replay_advance,
.check = xfrm_replay_check,
.recheck = xfrm_replay_check,
.overflow = xfrm_replay_overflow_offload,
};
static const struct xfrm_replay xfrm_replay_bmp = {
- .advance = xfrm_replay_advance_bmp,
.check = xfrm_replay_check_bmp,
.recheck = xfrm_replay_check_bmp,
.overflow = xfrm_replay_overflow_offload_bmp,
};
static const struct xfrm_replay xfrm_replay_esn = {
- .advance = xfrm_replay_advance_esn,
.check = xfrm_replay_check_esn,
.recheck = xfrm_replay_recheck_esn,
.overflow = xfrm_replay_overflow_offload_esn,
};
#else
static const struct xfrm_replay xfrm_replay_legacy = {
- .advance = xfrm_replay_advance,
.check = xfrm_replay_check,
.recheck = xfrm_replay_check,
.overflow = xfrm_replay_overflow,
};
static const struct xfrm_replay xfrm_replay_bmp = {
- .advance = xfrm_replay_advance_bmp,
.check = xfrm_replay_check_bmp,
.recheck = xfrm_replay_check_bmp,
.overflow = xfrm_replay_overflow_bmp,
};
static const struct xfrm_replay xfrm_replay_esn = {
- .advance = xfrm_replay_advance_esn,
.check = xfrm_replay_check_esn,
.recheck = xfrm_replay_recheck_esn,
.overflow = xfrm_replay_overflow_esn,
--
2.26.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH ipsec-next v2 4/6] xfrm: replay: remove recheck indirection
2020-06-24 8:07 [PATCH ipsec-next v2 0/6] xfrm: remove xfrm replay indirections Florian Westphal
` (2 preceding siblings ...)
2020-06-24 8:08 ` [PATCH ipsec-next v2 3/6] xfrm: replay: remove advance indirection Florian Westphal
@ 2020-06-24 8:08 ` Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 5/6] xfrm: replay: avoid replay indirection Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 6/6] xfrm: replay: remove last " Florian Westphal
5 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2020-06-24 8:08 UTC (permalink / raw)
To: steffen.klassert; +Cc: netdev, Florian Westphal
Adds new xfrm_replay_recheck() helper and calls it from
xfrm input path instead of the indirection.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/net/xfrm.h | 4 +---
net/xfrm/xfrm_input.c | 2 +-
net/xfrm/xfrm_replay.c | 22 ++++++++++++++++------
3 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 78bbfd370e34..7c0b69e00128 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -307,9 +307,6 @@ struct xfrm_replay {
int (*check)(struct xfrm_state *x,
struct sk_buff *skb,
__be32 net_seq);
- int (*recheck)(struct xfrm_state *x,
- struct sk_buff *skb,
- __be32 net_seq);
int (*overflow)(struct xfrm_state *x, struct sk_buff *skb);
};
@@ -1720,6 +1717,7 @@ static inline int xfrm_policy_id2dir(u32 index)
#ifdef CONFIG_XFRM
void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq);
void xfrm_replay_notify(struct xfrm_state *x, int event);
+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_input.c b/net/xfrm/xfrm_input.c
index b4b559b35cf1..005d8e9c5df4 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -658,7 +658,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
/* only the first xfrm gets the encap type */
encap_type = 0;
- if (async && x->repl->recheck(x, skb, seq)) {
+ if (async && xfrm_replay_recheck(x, skb, seq)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
goto drop_unlock;
}
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 460f438bd138..60608b51b2d9 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -503,6 +503,22 @@ static int xfrm_replay_recheck_esn(struct xfrm_state *x,
return xfrm_replay_check_esn(x, skb, net_seq);
}
+int xfrm_replay_recheck(struct xfrm_state *x,
+ struct sk_buff *skb, __be32 net_seq)
+{
+ switch (x->repl_mode) {
+ case XFRM_REPLAY_MODE_LEGACY:
+ break;
+ case XFRM_REPLAY_MODE_BMP:
+ /* no special recheck treatment */
+ return xfrm_replay_check_bmp(x, skb, net_seq);
+ case XFRM_REPLAY_MODE_ESN:
+ return xfrm_replay_recheck_esn(x, skb, net_seq);
+ }
+
+ return xfrm_replay_check(x, skb, net_seq);
+}
+
static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
{
unsigned int bitnr, nr, i;
@@ -690,37 +706,31 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
static const struct xfrm_replay xfrm_replay_legacy = {
.check = xfrm_replay_check,
- .recheck = xfrm_replay_check,
.overflow = xfrm_replay_overflow_offload,
};
static const struct xfrm_replay xfrm_replay_bmp = {
.check = xfrm_replay_check_bmp,
- .recheck = xfrm_replay_check_bmp,
.overflow = xfrm_replay_overflow_offload_bmp,
};
static const struct xfrm_replay xfrm_replay_esn = {
.check = xfrm_replay_check_esn,
- .recheck = xfrm_replay_recheck_esn,
.overflow = xfrm_replay_overflow_offload_esn,
};
#else
static const struct xfrm_replay xfrm_replay_legacy = {
.check = xfrm_replay_check,
- .recheck = xfrm_replay_check,
.overflow = xfrm_replay_overflow,
};
static const struct xfrm_replay xfrm_replay_bmp = {
.check = xfrm_replay_check_bmp,
- .recheck = xfrm_replay_check_bmp,
.overflow = xfrm_replay_overflow_bmp,
};
static const struct xfrm_replay xfrm_replay_esn = {
.check = xfrm_replay_check_esn,
- .recheck = xfrm_replay_recheck_esn,
.overflow = xfrm_replay_overflow_esn,
};
#endif
--
2.26.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH ipsec-next v2 5/6] xfrm: replay: avoid replay indirection
2020-06-24 8:07 [PATCH ipsec-next v2 0/6] xfrm: remove xfrm replay indirections Florian Westphal
` (3 preceding siblings ...)
2020-06-24 8:08 ` [PATCH ipsec-next v2 4/6] xfrm: replay: remove recheck indirection Florian Westphal
@ 2020-06-24 8:08 ` Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 6/6] xfrm: replay: remove last " Florian Westphal
5 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2020-06-24 8:08 UTC (permalink / raw)
To: steffen.klassert; +Cc: netdev, Florian Westphal
Add and use xfrm_replay_check helper instead of indirection.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/net/xfrm.h | 4 +---
net/xfrm/xfrm_input.c | 2 +-
net/xfrm/xfrm_replay.c | 27 ++++++++++++++++++---------
3 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 7c0b69e00128..008b564cb126 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -304,9 +304,6 @@ struct km_event {
};
struct xfrm_replay {
- int (*check)(struct xfrm_state *x,
- struct sk_buff *skb,
- __be32 net_seq);
int (*overflow)(struct xfrm_state *x, struct sk_buff *skb);
};
@@ -1716,6 +1713,7 @@ static inline int xfrm_policy_id2dir(u32 index)
#ifdef CONFIG_XFRM
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_recheck(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 005d8e9c5df4..694adc6e9286 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -610,7 +610,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop_unlock;
}
- if (x->repl->check(x, skb, seq)) {
+ if (xfrm_replay_check(x, skb, seq)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
goto drop_unlock;
}
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 60608b51b2d9..8c97fcaf17cf 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -119,8 +119,8 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
return err;
}
-static int xfrm_replay_check(struct xfrm_state *x,
- struct sk_buff *skb, __be32 net_seq)
+static int xfrm_replay_check_legacy(struct xfrm_state *x,
+ struct sk_buff *skb, __be32 net_seq)
{
u32 diff;
u32 seq = ntohl(net_seq);
@@ -491,6 +491,21 @@ static int xfrm_replay_check_esn(struct xfrm_state *x,
return -EINVAL;
}
+int xfrm_replay_check(struct xfrm_state *x,
+ struct sk_buff *skb, __be32 net_seq)
+{
+ switch (x->repl_mode) {
+ case XFRM_REPLAY_MODE_LEGACY:
+ break;
+ case XFRM_REPLAY_MODE_BMP:
+ return xfrm_replay_check_bmp(x, skb, net_seq);
+ case XFRM_REPLAY_MODE_ESN:
+ return xfrm_replay_check_esn(x, skb, net_seq);
+ }
+
+ return xfrm_replay_check_legacy(x, skb, net_seq);
+}
+
static int xfrm_replay_recheck_esn(struct xfrm_state *x,
struct sk_buff *skb, __be32 net_seq)
{
@@ -516,7 +531,7 @@ int xfrm_replay_recheck(struct xfrm_state *x,
return xfrm_replay_recheck_esn(x, skb, net_seq);
}
- return xfrm_replay_check(x, skb, net_seq);
+ return xfrm_replay_check_legacy(x, skb, net_seq);
}
static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
@@ -705,32 +720,26 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
}
static const struct xfrm_replay xfrm_replay_legacy = {
- .check = xfrm_replay_check,
.overflow = xfrm_replay_overflow_offload,
};
static const struct xfrm_replay xfrm_replay_bmp = {
- .check = xfrm_replay_check_bmp,
.overflow = xfrm_replay_overflow_offload_bmp,
};
static const struct xfrm_replay xfrm_replay_esn = {
- .check = xfrm_replay_check_esn,
.overflow = xfrm_replay_overflow_offload_esn,
};
#else
static const struct xfrm_replay xfrm_replay_legacy = {
- .check = xfrm_replay_check,
.overflow = xfrm_replay_overflow,
};
static const struct xfrm_replay xfrm_replay_bmp = {
- .check = xfrm_replay_check_bmp,
.overflow = xfrm_replay_overflow_bmp,
};
static const struct xfrm_replay xfrm_replay_esn = {
- .check = xfrm_replay_check_esn,
.overflow = xfrm_replay_overflow_esn,
};
#endif
--
2.26.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH ipsec-next v2 6/6] xfrm: replay: remove last replay indirection
2020-06-24 8:07 [PATCH ipsec-next v2 0/6] xfrm: remove xfrm replay indirections Florian Westphal
` (4 preceding siblings ...)
2020-06-24 8:08 ` [PATCH ipsec-next v2 5/6] xfrm: replay: avoid replay indirection Florian Westphal
@ 2020-06-24 8:08 ` Florian Westphal
5 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2020-06-24 8:08 UTC (permalink / raw)
To: steffen.klassert; +Cc: netdev, Florian Westphal
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 <fw@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
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH ipsec-next v2 2/6] xfrm: replay: get rid of duplicated notification code
2020-06-24 8:08 ` [PATCH ipsec-next v2 2/6] xfrm: replay: get rid of duplicated notification code Florian Westphal
@ 2020-06-25 7:07 ` Sabrina Dubroca
2020-06-25 10:09 ` Florian Westphal
0 siblings, 1 reply; 9+ messages in thread
From: Sabrina Dubroca @ 2020-06-25 7:07 UTC (permalink / raw)
To: Florian Westphal; +Cc: steffen.klassert, netdev
Hi Florian,
2020-06-24, 10:08:00 +0200, Florian Westphal wrote:
> After previous patch, we can consolidate some code:
>
> xfrm_replay_notify, xfrm_replay_notify_bmp and _esn all contain the
> same code at the end.
>
> Remove it from xfrm_replay_notify_bmp/esn and reuse the one
> in xfrm_replay_notify.
>
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> net/xfrm/xfrm_replay.c | 22 ++++------------------
> 1 file changed, 4 insertions(+), 18 deletions(-)
>
> diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
> index e42a7afb8ee5..fac2f3af4c1a 100644
> --- a/net/xfrm/xfrm_replay.c
> +++ b/net/xfrm/xfrm_replay.c
> @@ -56,10 +56,10 @@ void xfrm_replay_notify(struct xfrm_state *x, int event)
> break;
> case XFRM_REPLAY_MODE_BMP:
> xfrm_replay_notify_bmp(x, event);
> - return;
> + goto notify;
> case XFRM_REPLAY_MODE_ESN:
> xfrm_replay_notify_esn(x, event);
> - return;
> + goto notify;
These two functions have some early returns that skip the
notification, but now the notification will be sent in all cases:
static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event)
{
<snip>
switch (event) {
case XFRM_REPLAY_UPDATE:
if (...) {
if (x->xflags & XFRM_TIME_DEFER)
event = XFRM_REPLAY_TIMEOUT;
else
return;
}
break;
And this also changes the value that ends up in c.data.aevent. That
change will be lost after this patch.
> }
>
> switch (event) {
> @@ -86,6 +86,8 @@ void xfrm_replay_notify(struct xfrm_state *x, int event)
> }
>
> memcpy(&x->preplay, &x->replay, sizeof(struct xfrm_replay_state));
> +
> +notify:
> c.event = XFRM_MSG_NEWAE;
> c.data.aevent = event;
> km_state_notify(x, &c);
--
Sabrina
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH ipsec-next v2 2/6] xfrm: replay: get rid of duplicated notification code
2020-06-25 7:07 ` Sabrina Dubroca
@ 2020-06-25 10:09 ` Florian Westphal
0 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2020-06-25 10:09 UTC (permalink / raw)
To: Sabrina Dubroca; +Cc: Florian Westphal, steffen.klassert, netdev
Sabrina Dubroca <sd@queasysnail.net> wrote:
> > case XFRM_REPLAY_MODE_BMP:
> > xfrm_replay_notify_bmp(x, event);
> > - return;
> > + goto notify;
> > case XFRM_REPLAY_MODE_ESN:
> > xfrm_replay_notify_esn(x, event);
> > - return;
> > + goto notify;
>
> These two functions have some early returns that skip the
> notification, but now the notification will be sent in all cases:
Right, I will rework this series.
Thanks for pointing this out.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2020-06-25 10:09 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-24 8:07 [PATCH ipsec-next v2 0/6] xfrm: remove xfrm replay indirections Florian Westphal
2020-06-24 8:07 ` [PATCH ipsec-next v2 1/6] xfrm: replay: avoid xfrm replay notify indirection Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 2/6] xfrm: replay: get rid of duplicated notification code Florian Westphal
2020-06-25 7:07 ` Sabrina Dubroca
2020-06-25 10:09 ` Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 3/6] xfrm: replay: remove advance indirection Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 4/6] xfrm: replay: remove recheck indirection Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 5/6] xfrm: replay: avoid replay indirection Florian Westphal
2020-06-24 8:08 ` [PATCH ipsec-next v2 6/6] xfrm: replay: remove last " Florian Westphal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).