From db19dee0bf0ce644c74afaac87edd8dc9b204ea8 Mon Sep 17 00:00:00 2001 From: Bart Trojanowski Date: Wed, 16 Aug 2006 22:46:58 -0400 Subject: [PATCH] Added XFRM_ALTERNATE_STACK config option. When enabled a second IPsec stack can be registered with the XFRM code. When the SPI of a packet is not found in the XFRM database, the second stack's registered receive function is called. --- include/net/xfrm.h | 9 +++++++++ net/ipv4/xfrm4_input.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- net/xfrm/Kconfig | 9 +++++++++ 3 files changed, 62 insertions(+), 1 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index afa508d..c1115a5 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1017,5 +1017,14 @@ static inline void xfrm_aevent_doreplay( xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); } +#ifdef CONFIG_XFRM_ALTERNATE_STACK +/* + * The alternate IPsec stack will only be called for packets that do not match + * an existing SPI in the XFRM SADB. + */ +typedef int (*xfrm_alternate_rcv_fn)(struct sk_buff *skb); +extern int xfrm_register_alternate_rcv(xfrm_alternate_rcv_fn fn); +extern void xfrm_deregister_alternate_rcv(xfrm_alternate_rcv_fn fn); +#endif #endif /* _NET_XFRM_H */ diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index 3e174c8..b4d7963 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c @@ -17,6 +17,11 @@ #include #include #include +#ifdef CONFIG_XFRM_ALTERNATE_STACK +static xfrm_alternate_rcv_fn alternate_rcv_fn = NULL; +static DEFINE_RWLOCK(xfrm_alternate_rcv_lock); +#endif + int xfrm4_rcv(struct sk_buff *skb) { return xfrm4_rcv_encap(skb, 0); @@ -187,6 +192,44 @@ drop: while (--xfrm_nr >= 0) xfrm_state_put(xfrm_vec[xfrm_nr]); - kfree_skb(skb); +#ifdef CONFIG_XFRM_ALTERNATE_STACK + read_lock_bh (&xfrm_alternate_rcv_lock); + if (alternate_rcv_fn) { + if (0 == alternate_rcv_fn (skb)) + skb = NULL; + } + read_unlock_bh (&xfrm_alternate_rcv_lock); +#endif + + if (skb) + kfree_skb(skb); + return 0; } + +#ifdef CONFIG_XFRM_ALTERNATE_STACK +int +xfrm_register_alternate_rcv(xfrm_alternate_rcv_fn fn) +{ + int rc; + + rc = -EBUSY; + write_lock_bh (&xfrm_alternate_rcv_lock); + if (!alternate_rcv_fn) { + alternate_rcv_fn = fn; + rc = 0; + } + write_unlock_bh (&xfrm_alternate_rcv_lock); + + return rc; +} +void +xfrm_deregister_alternate_rcv(xfrm_alternate_rcv_fn fn) +{ + write_lock_bh (&xfrm_alternate_rcv_lock); + if (alternate_rcv_fn == fn) { + alternate_rcv_fn = NULL; + } + write_unlock_bh (&xfrm_alternate_rcv_lock); +} +#endif diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig index 0c1c043..189a9c5 100644 --- a/net/xfrm/Kconfig +++ b/net/xfrm/Kconfig @@ -24,4 +24,13 @@ config NET_KEY Say Y unless you know what you are doing. +config XFRM_ALTERNATE_STACK + bool 'Alternate IPsec stack support' + default y + depends on INET && XFRM + ---help--- + Support a second IPSec stack (like KLIPS from Openswan.org) to + interoperate with the XFRM SADB. + + Say Y if you intend to use KLIPS. -- 1.4.2.rc2.g432f-dirty