lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Fri, 9 Feb 2007 16:12:35 +0900
From:	Kazunori MIYAZAWA <kazunori@...azawa.org>
To:	Herbert Xu <herbert@...dor.apana.org.au>,
	David Miller <davem@...emloft.net>
Cc:	Miika Komu <miika@....fi>, Diego Beltrami <Diego.Beltrami@...t.fi>,
	netdev@...r.kernel.org, usagi-core@...ux-ipv6.org
Subject: [PATCH][IPSEC][3/4] changing API of xfrm6_tunnel_register

This patch changes xfrm6_tunnel register and deregister
interface to prepare for solving the conflict of device
tunnels with inter address family IPsec tunnel.
There is no device which conflicts with IPv4 over IPv6
IPsec tunnel.

signed-off-by Kazunori MIYAZAWA <miyazawa@...ux-ipv6.org>

---
 include/net/xfrm.h      |    4 ++--
 net/ipv6/ip6_tunnel.c   |    6 +++---
 net/ipv6/tunnel6.c      |   43 +++++++++++++++++++++++++++++++++++++++----
 net/ipv6/xfrm6_input.c  |    3 ++-
 net/ipv6/xfrm6_tunnel.c |   19 ++++++++++++++++---
 5 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 3ee0995..0ecc6a7 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -938,8 +938,8 @@ extern int xfrm6_rcv_spi(struct sk_buff 
 extern int xfrm6_rcv(struct sk_buff **pskb);
 extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 			    xfrm_address_t *saddr, u8 proto);
-extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler);
-extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);
+extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
+extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
 extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
 extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
 extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 8d91834..850b72b 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1127,7 +1127,7 @@ static int __init ip6_tunnel_init(void)
 {
 	int  err;
 
-	if (xfrm6_tunnel_register(&ip6ip6_handler)) {
+	if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) {
 		printk(KERN_ERR "ip6ip6 init: can't register tunnel\n");
 		return -EAGAIN;
 	}
@@ -1146,7 +1146,7 @@ static int __init ip6_tunnel_init(void)
 	}
 	return 0;
 fail:
-	xfrm6_tunnel_deregister(&ip6ip6_handler);
+	xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
 	return err;
 }
 
@@ -1170,7 +1170,7 @@ static void __exit ip6ip6_destroy_tunnel
 
 static void __exit ip6_tunnel_cleanup(void)
 {
-	if (xfrm6_tunnel_deregister(&ip6ip6_handler))
+	if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6))
 		printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
 
 	rtnl_lock();
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 918d07d..23e2809 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -30,9 +30,10 @@ #include <net/protocol.h>
 #include <net/xfrm.h>
 
 static struct xfrm6_tunnel *tunnel6_handlers;
+static struct xfrm6_tunnel *tunnel46_handlers;
 static DEFINE_MUTEX(tunnel6_mutex);
 
-int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
+int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family)
 {
 	struct xfrm6_tunnel **pprev;
 	int ret = -EEXIST;
@@ -40,7 +41,8 @@ int xfrm6_tunnel_register(struct xfrm6_t
 
 	mutex_lock(&tunnel6_mutex);
 
-	for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) {
+	for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
+	     *pprev; pprev = &(*pprev)->next) {
 		if ((*pprev)->priority > priority)
 			break;
 		if ((*pprev)->priority == priority)
@@ -60,14 +62,15 @@ err:
 
 EXPORT_SYMBOL(xfrm6_tunnel_register);
 
-int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler)
+int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
 {
 	struct xfrm6_tunnel **pprev;
 	int ret = -ENOENT;
 
 	mutex_lock(&tunnel6_mutex);
 
-	for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) {
+	for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
+	     *pprev; pprev = &(*pprev)->next) {
 		if (*pprev == handler) {
 			*pprev = handler->next;
 			ret = 0;
@@ -103,6 +106,25 @@ drop:
 	return 0;
 }
 
+static int tunnel46_rcv(struct sk_buff **pskb)
+{
+	struct sk_buff *skb = *pskb;
+	struct xfrm6_tunnel *handler;
+
+	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+		goto drop;
+
+	for (handler = tunnel46_handlers; handler; handler = handler->next)
+		if (!handler->handler(skb))
+			return 0;
+
+	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev);
+
+drop:
+	kfree_skb(skb);
+	return 0;
+}
+
 static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 			int type, int code, int offset, __be32 info)
 {
@@ -119,17 +141,30 @@ static struct inet6_protocol tunnel6_pro
 	.flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
 
+static struct inet6_protocol tunnel46_protocol = {
+	.handler	= tunnel46_rcv,
+	.err_handler	= tunnel6_err,
+	.flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
+};
+
 static int __init tunnel6_init(void)
 {
 	if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) {
 		printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
 		return -EAGAIN;
 	}
+	if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) {
+		printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
+		inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6);
+		return -EAGAIN;
+	}
 	return 0;
 }
 
 static void __exit tunnel6_fini(void)
 {
+	if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP))
+		printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
 	if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6))
 		printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
 }
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 5c8b7a5..b7e90e3 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -40,7 +40,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, _
 		if (xfrm_nr == XFRM_MAX_DEPTH)
 			goto drop;
 
-		x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, nexthdr, AF_INET6);
+		x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
+				nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6);
 		if (x == NULL)
 			goto drop;
 		spin_lock(&x->lock);
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 12e426b..df1a402 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -339,17 +339,29 @@ static struct xfrm6_tunnel xfrm6_tunnel_
 	.priority	= 2,
 };
 
+static struct xfrm6_tunnel xfrm46_tunnel_handler = {
+	.handler	= xfrm6_tunnel_rcv,
+	.err_handler	= xfrm6_tunnel_err,
+	.priority	= 2,
+};
+
 static int __init xfrm6_tunnel_init(void)
 {
 	if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
 		return -EAGAIN;
 
-	if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) {
+	if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) {
+		xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
+		return -EAGAIN;
+	}
+	if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) {
+		xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
 		xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
 		return -EAGAIN;
 	}
 	if (xfrm6_tunnel_spi_init() < 0) {
-		xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
+		xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
+		xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
 		xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
 		return -EAGAIN;
 	}
@@ -359,7 +371,8 @@ static int __init xfrm6_tunnel_init(void
 static void __exit xfrm6_tunnel_fini(void)
 {
 	xfrm6_tunnel_spi_fini();
-	xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
+	xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
+	xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
 	xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
 }
 
-- 
1.4.1

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ