aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazunori MIYAZAWA <miyazawa@linux-ipv6.org>2007-02-13 15:55:55 -0500
committerDavid S. Miller <davem@davemloft.net>2007-02-13 15:55:55 -0500
commit73d605d1abbd70ef67b7660cf2ff177259960756 (patch)
tree3b183bc597044785eef7cc8efefb41fbac097bf5
parentc73cb5a2d607b5b95a06a54d8291ddb659b348b6 (diff)
[IPSEC]: 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@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/xfrm.h4
-rw-r--r--net/ipv6/ip6_tunnel.c6
-rw-r--r--net/ipv6/tunnel6.c43
-rw-r--r--net/ipv6/xfrm6_input.c3
-rw-r--r--net/ipv6/xfrm6_tunnel.c19
5 files changed, 62 insertions, 13 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 20be8beb9a11..92a1fc46ea59 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -952,8 +952,8 @@ extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
952extern int xfrm6_rcv(struct sk_buff **pskb); 952extern int xfrm6_rcv(struct sk_buff **pskb);
953extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, 953extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
954 xfrm_address_t *saddr, u8 proto); 954 xfrm_address_t *saddr, u8 proto);
955extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); 955extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
956extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); 956extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
957extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); 957extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
958extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); 958extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
959extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); 959extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 367b74832986..662edb826899 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1128,7 +1128,7 @@ static int __init ip6_tunnel_init(void)
1128{ 1128{
1129 int err; 1129 int err;
1130 1130
1131 if (xfrm6_tunnel_register(&ip6ip6_handler)) { 1131 if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) {
1132 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n"); 1132 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n");
1133 return -EAGAIN; 1133 return -EAGAIN;
1134 } 1134 }
@@ -1147,7 +1147,7 @@ static int __init ip6_tunnel_init(void)
1147 } 1147 }
1148 return 0; 1148 return 0;
1149fail: 1149fail:
1150 xfrm6_tunnel_deregister(&ip6ip6_handler); 1150 xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
1151 return err; 1151 return err;
1152} 1152}
1153 1153
@@ -1171,7 +1171,7 @@ static void __exit ip6ip6_destroy_tunnels(void)
1171 1171
1172static void __exit ip6_tunnel_cleanup(void) 1172static void __exit ip6_tunnel_cleanup(void)
1173{ 1173{
1174 if (xfrm6_tunnel_deregister(&ip6ip6_handler)) 1174 if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6))
1175 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); 1175 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
1176 1176
1177 rtnl_lock(); 1177 rtnl_lock();
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 918d07dd1219..23e2809878ae 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -30,9 +30,10 @@
30#include <net/xfrm.h> 30#include <net/xfrm.h>
31 31
32static struct xfrm6_tunnel *tunnel6_handlers; 32static struct xfrm6_tunnel *tunnel6_handlers;
33static struct xfrm6_tunnel *tunnel46_handlers;
33static DEFINE_MUTEX(tunnel6_mutex); 34static DEFINE_MUTEX(tunnel6_mutex);
34 35
35int xfrm6_tunnel_register(struct xfrm6_tunnel *handler) 36int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family)
36{ 37{
37 struct xfrm6_tunnel **pprev; 38 struct xfrm6_tunnel **pprev;
38 int ret = -EEXIST; 39 int ret = -EEXIST;
@@ -40,7 +41,8 @@ int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
40 41
41 mutex_lock(&tunnel6_mutex); 42 mutex_lock(&tunnel6_mutex);
42 43
43 for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) { 44 for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
45 *pprev; pprev = &(*pprev)->next) {
44 if ((*pprev)->priority > priority) 46 if ((*pprev)->priority > priority)
45 break; 47 break;
46 if ((*pprev)->priority == priority) 48 if ((*pprev)->priority == priority)
@@ -60,14 +62,15 @@ err:
60 62
61EXPORT_SYMBOL(xfrm6_tunnel_register); 63EXPORT_SYMBOL(xfrm6_tunnel_register);
62 64
63int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler) 65int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
64{ 66{
65 struct xfrm6_tunnel **pprev; 67 struct xfrm6_tunnel **pprev;
66 int ret = -ENOENT; 68 int ret = -ENOENT;
67 69
68 mutex_lock(&tunnel6_mutex); 70 mutex_lock(&tunnel6_mutex);
69 71
70 for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) { 72 for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
73 *pprev; pprev = &(*pprev)->next) {
71 if (*pprev == handler) { 74 if (*pprev == handler) {
72 *pprev = handler->next; 75 *pprev = handler->next;
73 ret = 0; 76 ret = 0;
@@ -103,6 +106,25 @@ drop:
103 return 0; 106 return 0;
104} 107}
105 108
109static int tunnel46_rcv(struct sk_buff **pskb)
110{
111 struct sk_buff *skb = *pskb;
112 struct xfrm6_tunnel *handler;
113
114 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
115 goto drop;
116
117 for (handler = tunnel46_handlers; handler; handler = handler->next)
118 if (!handler->handler(skb))
119 return 0;
120
121 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev);
122
123drop:
124 kfree_skb(skb);
125 return 0;
126}
127
106static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 128static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
107 int type, int code, int offset, __be32 info) 129 int type, int code, int offset, __be32 info)
108{ 130{
@@ -119,17 +141,30 @@ static struct inet6_protocol tunnel6_protocol = {
119 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 141 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
120}; 142};
121 143
144static struct inet6_protocol tunnel46_protocol = {
145 .handler = tunnel46_rcv,
146 .err_handler = tunnel6_err,
147 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
148};
149
122static int __init tunnel6_init(void) 150static int __init tunnel6_init(void)
123{ 151{
124 if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) { 152 if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) {
125 printk(KERN_ERR "tunnel6 init(): can't add protocol\n"); 153 printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
126 return -EAGAIN; 154 return -EAGAIN;
127 } 155 }
156 if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) {
157 printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
158 inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6);
159 return -EAGAIN;
160 }
128 return 0; 161 return 0;
129} 162}
130 163
131static void __exit tunnel6_fini(void) 164static void __exit tunnel6_fini(void)
132{ 165{
166 if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP))
167 printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
133 if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6)) 168 if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6))
134 printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); 169 printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
135} 170}
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 25250147bdc3..31f651f95096 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, __be32 spi)
40 if (xfrm_nr == XFRM_MAX_DEPTH) 40 if (xfrm_nr == XFRM_MAX_DEPTH)
41 goto drop; 41 goto drop;
42 42
43 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, nexthdr, AF_INET6); 43 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
44 nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6);
44 if (x == NULL) 45 if (x == NULL)
45 goto drop; 46 goto drop;
46 spin_lock(&x->lock); 47 spin_lock(&x->lock);
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index fb0228772f01..ee4b84a33ff4 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -339,17 +339,29 @@ static struct xfrm6_tunnel xfrm6_tunnel_handler = {
339 .priority = 2, 339 .priority = 2,
340}; 340};
341 341
342static struct xfrm6_tunnel xfrm46_tunnel_handler = {
343 .handler = xfrm6_tunnel_rcv,
344 .err_handler = xfrm6_tunnel_err,
345 .priority = 2,
346};
347
342static int __init xfrm6_tunnel_init(void) 348static int __init xfrm6_tunnel_init(void)
343{ 349{
344 if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) 350 if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
345 return -EAGAIN; 351 return -EAGAIN;
346 352
347 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) { 353 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) {
354 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
355 return -EAGAIN;
356 }
357 if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) {
358 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
348 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 359 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
349 return -EAGAIN; 360 return -EAGAIN;
350 } 361 }
351 if (xfrm6_tunnel_spi_init() < 0) { 362 if (xfrm6_tunnel_spi_init() < 0) {
352 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); 363 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
364 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
353 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 365 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
354 return -EAGAIN; 366 return -EAGAIN;
355 } 367 }
@@ -359,7 +371,8 @@ static int __init xfrm6_tunnel_init(void)
359static void __exit xfrm6_tunnel_fini(void) 371static void __exit xfrm6_tunnel_fini(void)
360{ 372{
361 xfrm6_tunnel_spi_fini(); 373 xfrm6_tunnel_spi_fini();
362 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); 374 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
375 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
363 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 376 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
364} 377}
365 378