]> err.no Git - linux-2.6/blobdiff - net/ipv6/addrconf.c
[ICMP]: Store sock rather than socket for ICMP flow control.
[linux-2.6] / net / ipv6 / addrconf.c
index 803caf1a38909656a17098cace2c35a8108e1720..18e3a9825d8124347d26957e100e5d527a13075e 100644 (file)
@@ -1125,6 +1125,11 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
                        if (hiscore.rule < 7)
                                hiscore.rule++;
 #endif
+
+                       /* Skip rule 8 for orchid -> non-orchid address pairs. */
+                       if (ipv6_addr_orchid(&ifa->addr) && !ipv6_addr_orchid(daddr))
+                               continue;
+
                        /* Rule 8: Use longest matching prefix */
                        if (hiscore.rule < 8) {
                                hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
@@ -1557,6 +1562,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
                .fc_expires = expires,
                .fc_dst_len = plen,
                .fc_flags = RTF_UP | flags,
+               .fc_nlinfo.nl_net = &init_net,
        };
 
        ipv6_addr_copy(&cfg.fc_dst, pfx);
@@ -1583,6 +1589,7 @@ static void addrconf_add_mroute(struct net_device *dev)
                .fc_ifindex = dev->ifindex,
                .fc_dst_len = 8,
                .fc_flags = RTF_UP,
+               .fc_nlinfo.nl_net = &init_net,
        };
 
        ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
@@ -1599,6 +1606,7 @@ static void sit_route_add(struct net_device *dev)
                .fc_ifindex = dev->ifindex,
                .fc_dst_len = 96,
                .fc_flags = RTF_UP | RTF_NONEXTHOP,
+               .fc_nlinfo.nl_net = &init_net,
        };
 
        /* prefix length - 96 bits "::d.d.d.d" */
@@ -1900,7 +1908,7 @@ int addrconf_set_dstaddr(void __user *arg)
                p.iph.ihl = 5;
                p.iph.protocol = IPPROTO_IPV6;
                p.iph.ttl = 64;
-               ifr.ifr_ifru.ifru_data = (void __user *)&p;
+               ifr.ifr_ifru.ifru_data = (__force void __user *)&p;
 
                oldfs = get_fs(); set_fs(KERNEL_DS);
                err = dev->do_ioctl(dev, &ifr, SIOCADDTUNNEL);
@@ -2799,6 +2807,7 @@ static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(addrconf_hash_lock)
 {
        read_lock_bh(&addrconf_hash_lock);
        return if6_get_idx(seq, *pos);
@@ -2814,6 +2823,7 @@ static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void if6_seq_stop(struct seq_file *seq, void *v)
+       __releases(addrconf_hash_lock)
 {
        read_unlock_bh(&addrconf_hash_lock);
 }
@@ -3333,11 +3343,11 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                             ifa = ifa->if_next, ip_idx++) {
                                if (ip_idx < s_ip_idx)
                                        continue;
-                               if ((err = inet6_fill_ifaddr(skb, ifa,
-                                   NETLINK_CB(cb->skb).pid,
-                                   cb->nlh->nlmsg_seq, RTM_NEWADDR,
-                                   NLM_F_MULTI)) <= 0)
-                                       goto done;
+                               err = inet6_fill_ifaddr(skb, ifa,
+                                                       NETLINK_CB(cb->skb).pid,
+                                                       cb->nlh->nlmsg_seq,
+                                                       RTM_NEWADDR,
+                                                       NLM_F_MULTI);
                        }
                        break;
                case MULTICAST_ADDR:
@@ -3346,11 +3356,11 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                             ifmca = ifmca->next, ip_idx++) {
                                if (ip_idx < s_ip_idx)
                                        continue;
-                               if ((err = inet6_fill_ifmcaddr(skb, ifmca,
-                                   NETLINK_CB(cb->skb).pid,
-                                   cb->nlh->nlmsg_seq, RTM_GETMULTICAST,
-                                   NLM_F_MULTI)) <= 0)
-                                       goto done;
+                               err = inet6_fill_ifmcaddr(skb, ifmca,
+                                                         NETLINK_CB(cb->skb).pid,
+                                                         cb->nlh->nlmsg_seq,
+                                                         RTM_GETMULTICAST,
+                                                         NLM_F_MULTI);
                        }
                        break;
                case ANYCAST_ADDR:
@@ -3359,11 +3369,11 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                             ifaca = ifaca->aca_next, ip_idx++) {
                                if (ip_idx < s_ip_idx)
                                        continue;
-                               if ((err = inet6_fill_ifacaddr(skb, ifaca,
-                                   NETLINK_CB(cb->skb).pid,
-                                   cb->nlh->nlmsg_seq, RTM_GETANYCAST,
-                                   NLM_F_MULTI)) <= 0)
-                                       goto done;
+                               err = inet6_fill_ifacaddr(skb, ifaca,
+                                                         NETLINK_CB(cb->skb).pid,
+                                                         cb->nlh->nlmsg_seq,
+                                                         RTM_GETANYCAST,
+                                                         NLM_F_MULTI);
                        }
                        break;
                default:
@@ -3371,14 +3381,12 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                }
                read_unlock_bh(&idev->lock);
                in6_dev_put(idev);
+
+               if (err <= 0)
+                       break;
 cont:
                idx++;
        }
-done:
-       if (err <= 0) {
-               read_unlock_bh(&idev->lock);
-               in6_dev_put(idev);
-       }
        cb->args[0] = idx;
        cb->args[1] = ip_idx;
        return skb->len;