aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-02-14 01:02:32 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-02-14 01:02:32 -0500
commitac98695d6c1508b724f246f38ce57fb4e3cec356 (patch)
tree189969a3689b9b83eaf39314a7942cc781ff836b /net/ipv6
parentd9bc125caf592b7d081021f32ce5b717efdf70c8 (diff)
parent93bbad8fe13a25dcf7f3bc628a71d1a7642ae61b (diff)
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Kconfig1
-rw-r--r--net/ipv6/inet6_hashtables.c2
-rw-r--r--net/ipv6/ip6_tunnel.c6
-rw-r--r--net/ipv6/sit.c30
-rw-r--r--net/ipv6/tunnel6.c43
-rw-r--r--net/ipv6/xfrm6_input.c3
-rw-r--r--net/ipv6/xfrm6_tunnel.c19
7 files changed, 80 insertions, 24 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index deb4101a2a81..79682efb14be 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -156,6 +156,7 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION
156config IPV6_SIT 156config IPV6_SIT
157 tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)" 157 tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)"
158 depends on IPV6 158 depends on IPV6
159 select INET_TUNNEL
159 default y 160 default y
160 ---help--- 161 ---help---
161 Tunneling means encapsulating data of one protocol type within 162 Tunneling means encapsulating data of one protocol type within
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 30b16da739c2..ae6b0e7eb488 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -172,7 +172,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
172 const struct in6_addr *saddr = &np->daddr; 172 const struct in6_addr *saddr = &np->daddr;
173 const int dif = sk->sk_bound_dev_if; 173 const int dif = sk->sk_bound_dev_if;
174 const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport); 174 const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
175 const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, 175 const unsigned int hash = inet6_ehashfn(daddr, lport, saddr,
176 inet->dport); 176 inet->dport);
177 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); 177 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
178 struct sock *sk2; 178 struct sock *sk2;
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/sit.c b/net/ipv6/sit.c
index 4d3cf301e1fc..862ed7c52c38 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -216,7 +216,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
216} 216}
217 217
218 218
219static void ipip6_err(struct sk_buff *skb, u32 info) 219static int ipip6_err(struct sk_buff *skb, u32 info)
220{ 220{
221#ifndef I_WISH_WORLD_WERE_PERFECT 221#ifndef I_WISH_WORLD_WERE_PERFECT
222 222
@@ -228,21 +228,22 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
228 int type = skb->h.icmph->type; 228 int type = skb->h.icmph->type;
229 int code = skb->h.icmph->code; 229 int code = skb->h.icmph->code;
230 struct ip_tunnel *t; 230 struct ip_tunnel *t;
231 int err;
231 232
232 switch (type) { 233 switch (type) {
233 default: 234 default:
234 case ICMP_PARAMETERPROB: 235 case ICMP_PARAMETERPROB:
235 return; 236 return 0;
236 237
237 case ICMP_DEST_UNREACH: 238 case ICMP_DEST_UNREACH:
238 switch (code) { 239 switch (code) {
239 case ICMP_SR_FAILED: 240 case ICMP_SR_FAILED:
240 case ICMP_PORT_UNREACH: 241 case ICMP_PORT_UNREACH:
241 /* Impossible event. */ 242 /* Impossible event. */
242 return; 243 return 0;
243 case ICMP_FRAG_NEEDED: 244 case ICMP_FRAG_NEEDED:
244 /* Soft state for pmtu is maintained by IP core. */ 245 /* Soft state for pmtu is maintained by IP core. */
245 return; 246 return 0;
246 default: 247 default:
247 /* All others are translated to HOST_UNREACH. 248 /* All others are translated to HOST_UNREACH.
248 rfc2003 contains "deep thoughts" about NET_UNREACH, 249 rfc2003 contains "deep thoughts" about NET_UNREACH,
@@ -253,14 +254,18 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
253 break; 254 break;
254 case ICMP_TIME_EXCEEDED: 255 case ICMP_TIME_EXCEEDED:
255 if (code != ICMP_EXC_TTL) 256 if (code != ICMP_EXC_TTL)
256 return; 257 return 0;
257 break; 258 break;
258 } 259 }
259 260
261 err = -ENOENT;
262
260 read_lock(&ipip6_lock); 263 read_lock(&ipip6_lock);
261 t = ipip6_tunnel_lookup(iph->daddr, iph->saddr); 264 t = ipip6_tunnel_lookup(iph->daddr, iph->saddr);
262 if (t == NULL || t->parms.iph.daddr == 0) 265 if (t == NULL || t->parms.iph.daddr == 0)
263 goto out; 266 goto out;
267
268 err = 0;
264 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) 269 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
265 goto out; 270 goto out;
266 271
@@ -271,7 +276,7 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
271 t->err_time = jiffies; 276 t->err_time = jiffies;
272out: 277out:
273 read_unlock(&ipip6_lock); 278 read_unlock(&ipip6_lock);
274 return; 279 return err;
275#else 280#else
276 struct iphdr *iph = (struct iphdr*)dp; 281 struct iphdr *iph = (struct iphdr*)dp;
277 int hlen = iph->ihl<<2; 282 int hlen = iph->ihl<<2;
@@ -332,7 +337,7 @@ out:
332 /* Prepare fake skb to feed it to icmpv6_send */ 337 /* Prepare fake skb to feed it to icmpv6_send */
333 skb2 = skb_clone(skb, GFP_ATOMIC); 338 skb2 = skb_clone(skb, GFP_ATOMIC);
334 if (skb2 == NULL) 339 if (skb2 == NULL)
335 return; 340 return 0;
336 dst_release(skb2->dst); 341 dst_release(skb2->dst);
337 skb2->dst = NULL; 342 skb2->dst = NULL;
338 skb_pull(skb2, skb->data - (u8*)iph6); 343 skb_pull(skb2, skb->data - (u8*)iph6);
@@ -355,7 +360,7 @@ out:
355 } 360 }
356 } 361 }
357 kfree_skb(skb2); 362 kfree_skb(skb2);
358 return; 363 return 0;
359#endif 364#endif
360} 365}
361 366
@@ -791,9 +796,10 @@ static int __init ipip6_fb_tunnel_init(struct net_device *dev)
791 return 0; 796 return 0;
792} 797}
793 798
794static struct net_protocol sit_protocol = { 799static struct xfrm_tunnel sit_handler = {
795 .handler = ipip6_rcv, 800 .handler = ipip6_rcv,
796 .err_handler = ipip6_err, 801 .err_handler = ipip6_err,
802 .priority = 1,
797}; 803};
798 804
799static void __exit sit_destroy_tunnels(void) 805static void __exit sit_destroy_tunnels(void)
@@ -812,7 +818,7 @@ static void __exit sit_destroy_tunnels(void)
812 818
813static void __exit sit_cleanup(void) 819static void __exit sit_cleanup(void)
814{ 820{
815 inet_del_protocol(&sit_protocol, IPPROTO_IPV6); 821 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
816 822
817 rtnl_lock(); 823 rtnl_lock();
818 sit_destroy_tunnels(); 824 sit_destroy_tunnels();
@@ -826,7 +832,7 @@ static int __init sit_init(void)
826 832
827 printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); 833 printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n");
828 834
829 if (inet_add_protocol(&sit_protocol, IPPROTO_IPV6) < 0) { 835 if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) {
830 printk(KERN_INFO "sit init: Can't add protocol\n"); 836 printk(KERN_INFO "sit init: Can't add protocol\n");
831 return -EAGAIN; 837 return -EAGAIN;
832 } 838 }
@@ -848,7 +854,7 @@ static int __init sit_init(void)
848 err2: 854 err2:
849 free_netdev(ipip6_fb_tunnel_dev); 855 free_netdev(ipip6_fb_tunnel_dev);
850 err1: 856 err1:
851 inet_del_protocol(&sit_protocol, IPPROTO_IPV6); 857 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
852 goto out; 858 goto out;
853} 859}
854 860
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