aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_tunnel.c19
-rw-r--r--net/ipv6/route.c15
-rw-r--r--net/ipv6/udp.c7
3 files changed, 29 insertions, 12 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 84d7ebdb9d21..b9f40290d12a 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -542,6 +542,7 @@ ip6ip6_rcv(struct sk_buff *skb)
542 skb->dev = t->dev; 542 skb->dev = t->dev;
543 dst_release(skb->dst); 543 dst_release(skb->dst);
544 skb->dst = NULL; 544 skb->dst = NULL;
545 nf_reset(skb);
545 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) 546 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
546 ipv6_copy_dscp(ipv6h, skb->nh.ipv6h); 547 ipv6_copy_dscp(ipv6h, skb->nh.ipv6h);
547 ip6ip6_ecn_decapsulate(ipv6h, skb); 548 ip6ip6_ecn_decapsulate(ipv6h, skb);
@@ -1149,6 +1150,20 @@ fail:
1149 return err; 1150 return err;
1150} 1151}
1151 1152
1153static void __exit ip6ip6_destroy_tunnels(void)
1154{
1155 int h;
1156 struct ip6_tnl *t;
1157
1158 for (h = 0; h < HASH_SIZE; h++) {
1159 while ((t = tnls_r_l[h]) != NULL)
1160 unregister_netdevice(t->dev);
1161 }
1162
1163 t = tnls_wc[0];
1164 unregister_netdevice(t->dev);
1165}
1166
1152/** 1167/**
1153 * ip6_tunnel_cleanup - free resources and unregister protocol 1168 * ip6_tunnel_cleanup - free resources and unregister protocol
1154 **/ 1169 **/
@@ -1158,7 +1173,9 @@ static void __exit ip6_tunnel_cleanup(void)
1158 if (xfrm6_tunnel_deregister(&ip6ip6_handler)) 1173 if (xfrm6_tunnel_deregister(&ip6ip6_handler))
1159 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); 1174 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
1160 1175
1161 unregister_netdev(ip6ip6_fb_tnl_dev); 1176 rtnl_lock();
1177 ip6ip6_destroy_tunnels();
1178 rtnl_unlock();
1162} 1179}
1163 1180
1164module_init(ip6_tunnel_init); 1181module_init(ip6_tunnel_init);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c953466b7afd..b39ae99122d5 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -330,6 +330,8 @@ static int inline rt6_check_neigh(struct rt6_info *rt)
330 read_lock_bh(&neigh->lock); 330 read_lock_bh(&neigh->lock);
331 if (neigh->nud_state & NUD_VALID) 331 if (neigh->nud_state & NUD_VALID)
332 m = 2; 332 m = 2;
333 else if (!(neigh->nud_state & NUD_FAILED))
334 m = 1;
333 read_unlock_bh(&neigh->lock); 335 read_unlock_bh(&neigh->lock);
334 } 336 }
335 return m; 337 return m;
@@ -347,9 +349,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
347 m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; 349 m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;
348#endif 350#endif
349 n = rt6_check_neigh(rt); 351 n = rt6_check_neigh(rt);
350 if (n > 1) 352 if (!n && (strict & RT6_LOOKUP_F_REACHABLE))
351 m |= 16;
352 else if (!n && strict & RT6_LOOKUP_F_REACHABLE)
353 return -1; 353 return -1;
354 return m; 354 return m;
355} 355}
@@ -380,10 +380,11 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif,
380 continue; 380 continue;
381 381
382 if (m > mpri) { 382 if (m > mpri) {
383 rt6_probe(match); 383 if (strict & RT6_LOOKUP_F_REACHABLE)
384 rt6_probe(match);
384 match = rt; 385 match = rt;
385 mpri = m; 386 mpri = m;
386 } else { 387 } else if (strict & RT6_LOOKUP_F_REACHABLE) {
387 rt6_probe(rt); 388 rt6_probe(rt);
388 } 389 }
389 } 390 }
@@ -636,7 +637,7 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
636 int strict = 0; 637 int strict = 0;
637 int attempts = 3; 638 int attempts = 3;
638 int err; 639 int err;
639 int reachable = RT6_LOOKUP_F_REACHABLE; 640 int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
640 641
641 strict |= flags & RT6_LOOKUP_F_IFACE; 642 strict |= flags & RT6_LOOKUP_F_IFACE;
642 643
@@ -733,7 +734,7 @@ static struct rt6_info *ip6_pol_route_output(struct fib6_table *table,
733 int strict = 0; 734 int strict = 0;
734 int attempts = 3; 735 int attempts = 3;
735 int err; 736 int err;
736 int reachable = RT6_LOOKUP_F_REACHABLE; 737 int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
737 738
738 strict |= flags & RT6_LOOKUP_F_IFACE; 739 strict |= flags & RT6_LOOKUP_F_IFACE;
739 740
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e0c3934a7e4b..c83f23e51c46 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -242,14 +242,13 @@ static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
242{ 242{
243 struct ipv6_pinfo *np; 243 struct ipv6_pinfo *np;
244 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; 244 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
245 struct net_device *dev = skb->dev;
246 struct in6_addr *saddr = &hdr->saddr; 245 struct in6_addr *saddr = &hdr->saddr;
247 struct in6_addr *daddr = &hdr->daddr; 246 struct in6_addr *daddr = &hdr->daddr;
248 struct udphdr *uh = (struct udphdr*)(skb->data+offset); 247 struct udphdr *uh = (struct udphdr*)(skb->data+offset);
249 struct sock *sk; 248 struct sock *sk;
250 int err; 249 int err;
251 250
252 sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex); 251 sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, inet6_iif(skb));
253 252
254 if (sk == NULL) 253 if (sk == NULL)
255 return; 254 return;
@@ -348,7 +347,7 @@ static void udpv6_mcast_deliver(struct udphdr *uh,
348 347
349 read_lock(&udp_hash_lock); 348 read_lock(&udp_hash_lock);
350 sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); 349 sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
351 dif = skb->dev->ifindex; 350 dif = inet6_iif(skb);
352 sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); 351 sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
353 if (!sk) { 352 if (!sk) {
354 kfree_skb(skb); 353 kfree_skb(skb);
@@ -429,7 +428,7 @@ static int udpv6_rcv(struct sk_buff **pskb)
429 * check socket cache ... must talk to Alan about his plans 428 * check socket cache ... must talk to Alan about his plans
430 * for sock caches... i'll skip this for now. 429 * for sock caches... i'll skip this for now.
431 */ 430 */
432 sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex); 431 sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, inet6_iif(skb));
433 432
434 if (sk == NULL) { 433 if (sk == NULL) {
435 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 434 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))