From: Steffen Klassert <steffen.klassert@secunet•com>
To: netdev@vger•kernel.org
Subject: [PATCH RFC 1/2] ipv6: Add a receive path hook for vti6 in xfrm6_mode_tunnel.
Date: Mon, 19 Aug 2013 08:26:56 +0200 [thread overview]
Message-ID: <20130819062656.GO26773@secunet.com> (raw)
In-Reply-To: <20130819062623.GN26773@secunet.com>
Add a receive path hook for the IPsec vritual tunnel interface.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
include/net/xfrm.h | 2 ++
net/ipv6/xfrm6_mode_tunnel.c | 69 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 94ce082..1e7700f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1497,6 +1497,8 @@ extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short fam
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
extern int xfrm4_mode_tunnel_input_register(struct xfrm_tunnel *handler);
extern int xfrm4_mode_tunnel_input_deregister(struct xfrm_tunnel *handler);
+extern int xfrm6_mode_tunnel_input_register(struct xfrm6_tunnel *handler);
+extern int xfrm6_mode_tunnel_input_deregister(struct xfrm6_tunnel *handler);
extern int xfrm6_extract_header(struct sk_buff *skb);
extern int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 4770d51..77e2f23 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -18,6 +18,65 @@
#include <net/ipv6.h>
#include <net/xfrm.h>
+/* Informational hook. The decap is still done here. */
+static struct xfrm6_tunnel __rcu *rcv_notify_handlers __read_mostly;
+static DEFINE_MUTEX(xfrm6_mode_tunnel_input_mutex);
+
+int xfrm6_mode_tunnel_input_register(struct xfrm6_tunnel *handler)
+{
+ struct xfrm6_tunnel __rcu **pprev;
+ struct xfrm6_tunnel *t;
+ int ret = -EEXIST;
+ int priority = handler->priority;
+
+ mutex_lock(&xfrm6_mode_tunnel_input_mutex);
+
+ for (pprev = &rcv_notify_handlers;
+ (t = rcu_dereference_protected(*pprev,
+ lockdep_is_held(&xfrm6_mode_tunnel_input_mutex))) != NULL;
+ pprev = &t->next) {
+ if (t->priority > priority)
+ break;
+ if (t->priority == priority)
+ goto err;
+
+ }
+
+ handler->next = *pprev;
+ rcu_assign_pointer(*pprev, handler);
+
+ ret = 0;
+
+err:
+ mutex_unlock(&xfrm6_mode_tunnel_input_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(xfrm6_mode_tunnel_input_register);
+
+int xfrm6_mode_tunnel_input_deregister(struct xfrm6_tunnel *handler)
+{
+ struct xfrm6_tunnel __rcu **pprev;
+ struct xfrm6_tunnel *t;
+ int ret = -ENOENT;
+
+ mutex_lock(&xfrm6_mode_tunnel_input_mutex);
+ for (pprev = &rcv_notify_handlers;
+ (t = rcu_dereference_protected(*pprev,
+ lockdep_is_held(&xfrm6_mode_tunnel_input_mutex))) != NULL;
+ pprev = &t->next) {
+ if (t == handler) {
+ *pprev = handler->next;
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&xfrm6_mode_tunnel_input_mutex);
+ synchronize_net();
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(xfrm6_mode_tunnel_input_deregister);
+
static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
{
const struct ipv6hdr *outer_iph = ipv6_hdr(skb);
@@ -63,8 +122,15 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
return 0;
}
+#define for_each_input_rcu(head, handler) \
+ for (handler = rcu_dereference(head); \
+ handler != NULL; \
+ handler = rcu_dereference(handler->next))
+
+
static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
{
+ struct xfrm6_tunnel *handler;
int err = -EINVAL;
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
@@ -72,6 +138,9 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
goto out;
+ for_each_input_rcu(rcv_notify_handlers, handler)
+ handler->handler(skb);
+
err = skb_unclone(skb, GFP_ATOMIC);
if (err)
goto out;
--
1.7.9.5
next prev parent reply other threads:[~2013-08-19 6:26 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-19 6:26 [PATCH RFC 0/2] Add IPsec virtual tunnel interfaces to IPv6 Steffen Klassert
2013-08-19 6:26 ` Steffen Klassert [this message]
2013-08-19 6:27 ` [PATCH RFC 2/2] ipv6: Add support for IPsec virtual tunnel interfaces Steffen Klassert
2013-08-22 7:47 ` Fan Du
2013-08-23 6:12 ` Steffen Klassert
2013-08-23 6:17 ` Fan Du
2013-08-26 16:37 ` Dan Williams
2013-08-26 16:51 ` Eric Dumazet
2013-08-27 11:08 ` Steffen Klassert
2013-08-21 0:28 ` [PATCH RFC 0/2] Add IPsec virtual tunnel interfaces to IPv6 David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130819062656.GO26773@secunet.com \
--to=steffen.klassert@secunet$(echo .)com \
--cc=netdev@vger$(echo .)kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox