Commit c162eeaa21fde6c27112690f5bc0a461a9f1763e
Exists in
master
and in
7 other branches
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Showing 9 changed files Side-by-side Diff
include/linux/ipv6_route.h
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | fallback, no routers on link */ |
19 | 19 | #define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */ |
20 | 20 | #define RTF_PREFIX_RT 0x00080000 /* A prefix only route - RA */ |
21 | +#define RTF_ANYCAST 0x00100000 /* Anycast */ | |
21 | 22 | |
22 | 23 | #define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ |
23 | 24 | #define RTF_EXPIRES 0x00400000 |
include/net/if_inet6.h
net/8021q/vlan.c
... | ... | @@ -753,6 +753,8 @@ |
753 | 753 | break; |
754 | 754 | case GET_VLAN_REALDEV_NAME_CMD: |
755 | 755 | err = vlan_dev_get_realdev_name(args.device1, args.u.device2); |
756 | + if (err) | |
757 | + goto out; | |
756 | 758 | if (copy_to_user(arg, &args, |
757 | 759 | sizeof(struct vlan_ioctl_args))) { |
758 | 760 | err = -EFAULT; |
... | ... | @@ -761,6 +763,8 @@ |
761 | 763 | |
762 | 764 | case GET_VLAN_VID_CMD: |
763 | 765 | err = vlan_dev_get_vid(args.device1, &vid); |
766 | + if (err) | |
767 | + goto out; | |
764 | 768 | args.u.VID = vid; |
765 | 769 | if (copy_to_user(arg, &args, |
766 | 770 | sizeof(struct vlan_ioctl_args))) { |
... | ... | @@ -774,7 +778,7 @@ |
774 | 778 | __FUNCTION__, args.cmd); |
775 | 779 | return -EINVAL; |
776 | 780 | }; |
777 | - | |
781 | +out: | |
778 | 782 | return err; |
779 | 783 | } |
780 | 784 |
net/dccp/ipv4.c
... | ... | @@ -1251,7 +1251,7 @@ |
1251 | 1251 | struct dccp_sock *dp = dccp_sk(sk); |
1252 | 1252 | |
1253 | 1253 | /* |
1254 | - * DCCP doesn't use sk_qrite_queue, just sk_send_head | |
1254 | + * DCCP doesn't use sk_write_queue, just sk_send_head | |
1255 | 1255 | * for retransmissions |
1256 | 1256 | */ |
1257 | 1257 | if (sk->sk_send_head != NULL) { |
net/ipv6/addrconf.c
... | ... | @@ -137,6 +137,7 @@ |
137 | 137 | static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags); |
138 | 138 | static void addrconf_dad_timer(unsigned long data); |
139 | 139 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp); |
140 | +static void addrconf_dad_run(struct inet6_dev *idev); | |
140 | 141 | static void addrconf_rs_timer(unsigned long data); |
141 | 142 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); |
142 | 143 | static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); |
... | ... | @@ -388,6 +389,9 @@ |
388 | 389 | } |
389 | 390 | #endif |
390 | 391 | |
392 | + if (netif_carrier_ok(dev)) | |
393 | + ndev->if_flags |= IF_READY; | |
394 | + | |
391 | 395 | write_lock_bh(&addrconf_lock); |
392 | 396 | dev->ip6_ptr = ndev; |
393 | 397 | write_unlock_bh(&addrconf_lock); |
... | ... | @@ -415,6 +419,7 @@ |
415 | 419 | if ((idev = ipv6_add_dev(dev)) == NULL) |
416 | 420 | return NULL; |
417 | 421 | } |
422 | + | |
418 | 423 | if (dev->flags&IFF_UP) |
419 | 424 | ipv6_mc_up(idev); |
420 | 425 | return idev; |
... | ... | @@ -634,8 +639,7 @@ |
634 | 639 | } |
635 | 640 | #endif |
636 | 641 | |
637 | - for (ifap = &idev->addr_list; (ifa=*ifap) != NULL; | |
638 | - ifap = &ifa->if_next) { | |
642 | + for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;) { | |
639 | 643 | if (ifa == ifp) { |
640 | 644 | *ifap = ifa->if_next; |
641 | 645 | __in6_ifa_put(ifp); |
... | ... | @@ -643,6 +647,7 @@ |
643 | 647 | if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0) |
644 | 648 | break; |
645 | 649 | deleted = 1; |
650 | + continue; | |
646 | 651 | } else if (ifp->flags & IFA_F_PERMANENT) { |
647 | 652 | if (ipv6_prefix_equal(&ifa->addr, &ifp->addr, |
648 | 653 | ifp->prefix_len)) { |
... | ... | @@ -666,6 +671,7 @@ |
666 | 671 | } |
667 | 672 | } |
668 | 673 | } |
674 | + ifap = &ifa->if_next; | |
669 | 675 | } |
670 | 676 | write_unlock_bh(&idev->lock); |
671 | 677 | |
672 | 678 | |
... | ... | @@ -903,11 +909,18 @@ |
903 | 909 | |
904 | 910 | score.addr_type = __ipv6_addr_type(&ifa->addr); |
905 | 911 | |
906 | - /* Rule 0: Candidate Source Address (section 4) | |
912 | + /* Rule 0: | |
913 | + * - Tentative Address (RFC2462 section 5.4) | |
914 | + * - A tentative address is not considered | |
915 | + * "assigned to an interface" in the traditional | |
916 | + * sense. | |
917 | + * - Candidate Source Address (section 4) | |
907 | 918 | * - In any case, anycast addresses, multicast |
908 | 919 | * addresses, and the unspecified address MUST |
909 | 920 | * NOT be included in a candidate set. |
910 | 921 | */ |
922 | + if (ifa->flags & IFA_F_TENTATIVE) | |
923 | + continue; | |
911 | 924 | if (unlikely(score.addr_type == IPV6_ADDR_ANY || |
912 | 925 | score.addr_type & IPV6_ADDR_MULTICAST)) { |
913 | 926 | LIMIT_NETDEBUG(KERN_DEBUG |
914 | 927 | |
... | ... | @@ -1215,10 +1228,8 @@ |
1215 | 1228 | |
1216 | 1229 | /* Gets referenced address, destroys ifaddr */ |
1217 | 1230 | |
1218 | -void addrconf_dad_failure(struct inet6_ifaddr *ifp) | |
1231 | +void addrconf_dad_stop(struct inet6_ifaddr *ifp) | |
1219 | 1232 | { |
1220 | - if (net_ratelimit()) | |
1221 | - printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name); | |
1222 | 1233 | if (ifp->flags&IFA_F_PERMANENT) { |
1223 | 1234 | spin_lock_bh(&ifp->lock); |
1224 | 1235 | addrconf_del_timer(ifp); |
... | ... | @@ -1244,6 +1255,12 @@ |
1244 | 1255 | ipv6_del_addr(ifp); |
1245 | 1256 | } |
1246 | 1257 | |
1258 | +void addrconf_dad_failure(struct inet6_ifaddr *ifp) | |
1259 | +{ | |
1260 | + if (net_ratelimit()) | |
1261 | + printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name); | |
1262 | + addrconf_dad_stop(ifp); | |
1263 | +} | |
1247 | 1264 | |
1248 | 1265 | /* Join to solicited addr multicast group. */ |
1249 | 1266 | |
1250 | 1267 | |
... | ... | @@ -2133,9 +2150,42 @@ |
2133 | 2150 | { |
2134 | 2151 | struct net_device *dev = (struct net_device *) data; |
2135 | 2152 | struct inet6_dev *idev = __in6_dev_get(dev); |
2153 | + int run_pending = 0; | |
2136 | 2154 | |
2137 | 2155 | switch(event) { |
2138 | 2156 | case NETDEV_UP: |
2157 | + case NETDEV_CHANGE: | |
2158 | + if (event == NETDEV_UP) { | |
2159 | + if (!netif_carrier_ok(dev)) { | |
2160 | + /* device is not ready yet. */ | |
2161 | + printk(KERN_INFO | |
2162 | + "ADDRCONF(NETDEV_UP): %s: " | |
2163 | + "link is not ready\n", | |
2164 | + dev->name); | |
2165 | + break; | |
2166 | + } | |
2167 | + } else { | |
2168 | + if (!netif_carrier_ok(dev)) { | |
2169 | + /* device is still not ready. */ | |
2170 | + break; | |
2171 | + } | |
2172 | + | |
2173 | + if (idev) { | |
2174 | + if (idev->if_flags & IF_READY) { | |
2175 | + /* device is already configured. */ | |
2176 | + break; | |
2177 | + } | |
2178 | + idev->if_flags |= IF_READY; | |
2179 | + } | |
2180 | + | |
2181 | + printk(KERN_INFO | |
2182 | + "ADDRCONF(NETDEV_CHANGE): %s: " | |
2183 | + "link becomes ready\n", | |
2184 | + dev->name); | |
2185 | + | |
2186 | + run_pending = 1; | |
2187 | + } | |
2188 | + | |
2139 | 2189 | switch(dev->type) { |
2140 | 2190 | case ARPHRD_SIT: |
2141 | 2191 | addrconf_sit_config(dev); |
... | ... | @@ -2152,6 +2202,9 @@ |
2152 | 2202 | break; |
2153 | 2203 | }; |
2154 | 2204 | if (idev) { |
2205 | + if (run_pending) | |
2206 | + addrconf_dad_run(idev); | |
2207 | + | |
2155 | 2208 | /* If the MTU changed during the interface down, when the |
2156 | 2209 | interface up, the changed MTU must be reflected in the |
2157 | 2210 | idev as well as routers. |
... | ... | @@ -2186,8 +2239,7 @@ |
2186 | 2239 | */ |
2187 | 2240 | addrconf_ifdown(dev, event != NETDEV_DOWN); |
2188 | 2241 | break; |
2189 | - case NETDEV_CHANGE: | |
2190 | - break; | |
2242 | + | |
2191 | 2243 | case NETDEV_CHANGENAME: |
2192 | 2244 | #ifdef CONFIG_SYSCTL |
2193 | 2245 | if (idev) { |
... | ... | @@ -2268,7 +2320,7 @@ |
2268 | 2320 | |
2269 | 2321 | /* Step 3: clear flags for stateless addrconf */ |
2270 | 2322 | if (how != 1) |
2271 | - idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD); | |
2323 | + idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY); | |
2272 | 2324 | |
2273 | 2325 | /* Step 4: clear address list */ |
2274 | 2326 | #ifdef CONFIG_IPV6_PRIVACY |
2275 | 2327 | |
... | ... | @@ -2377,11 +2429,20 @@ |
2377 | 2429 | /* |
2378 | 2430 | * Duplicate Address Detection |
2379 | 2431 | */ |
2432 | +static void addrconf_dad_kick(struct inet6_ifaddr *ifp) | |
2433 | +{ | |
2434 | + unsigned long rand_num; | |
2435 | + struct inet6_dev *idev = ifp->idev; | |
2436 | + | |
2437 | + rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); | |
2438 | + ifp->probes = idev->cnf.dad_transmits; | |
2439 | + addrconf_mod_timer(ifp, AC_DAD, rand_num); | |
2440 | +} | |
2441 | + | |
2380 | 2442 | static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) |
2381 | 2443 | { |
2382 | 2444 | struct inet6_dev *idev = ifp->idev; |
2383 | 2445 | struct net_device *dev = idev->dev; |
2384 | - unsigned long rand_num; | |
2385 | 2446 | |
2386 | 2447 | addrconf_join_solict(dev, &ifp->addr); |
2387 | 2448 | |
... | ... | @@ -2390,7 +2451,6 @@ |
2390 | 2451 | flags); |
2391 | 2452 | |
2392 | 2453 | net_srandom(ifp->addr.s6_addr32[3]); |
2393 | - rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); | |
2394 | 2454 | |
2395 | 2455 | read_lock_bh(&idev->lock); |
2396 | 2456 | if (ifp->dead) |
... | ... | @@ -2407,8 +2467,17 @@ |
2407 | 2467 | return; |
2408 | 2468 | } |
2409 | 2469 | |
2410 | - ifp->probes = idev->cnf.dad_transmits; | |
2411 | - addrconf_mod_timer(ifp, AC_DAD, rand_num); | |
2470 | + if (idev->if_flags & IF_READY) | |
2471 | + addrconf_dad_kick(ifp); | |
2472 | + else { | |
2473 | + /* | |
2474 | + * If the defice is not ready: | |
2475 | + * - keep it tentative if it is a permanent address. | |
2476 | + * - otherwise, kill it. | |
2477 | + */ | |
2478 | + in6_ifa_hold(ifp); | |
2479 | + addrconf_dad_stop(ifp); | |
2480 | + } | |
2412 | 2481 | |
2413 | 2482 | spin_unlock_bh(&ifp->lock); |
2414 | 2483 | out: |
... | ... | @@ -2490,6 +2559,22 @@ |
2490 | 2559 | addrconf_mod_timer(ifp, AC_RS, ifp->idev->cnf.rtr_solicit_interval); |
2491 | 2560 | spin_unlock_bh(&ifp->lock); |
2492 | 2561 | } |
2562 | +} | |
2563 | + | |
2564 | +static void addrconf_dad_run(struct inet6_dev *idev) { | |
2565 | + struct inet6_ifaddr *ifp; | |
2566 | + | |
2567 | + read_lock_bh(&idev->lock); | |
2568 | + for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) { | |
2569 | + spin_lock_bh(&ifp->lock); | |
2570 | + if (!(ifp->flags & IFA_F_TENTATIVE)) { | |
2571 | + spin_unlock_bh(&ifp->lock); | |
2572 | + continue; | |
2573 | + } | |
2574 | + spin_unlock_bh(&ifp->lock); | |
2575 | + addrconf_dad_kick(ifp); | |
2576 | + } | |
2577 | + read_unlock_bh(&idev->lock); | |
2493 | 2578 | } |
2494 | 2579 | |
2495 | 2580 | #ifdef CONFIG_PROC_FS |
net/ipv6/icmp.c
... | ... | @@ -328,8 +328,10 @@ |
328 | 328 | iif = skb->dev->ifindex; |
329 | 329 | |
330 | 330 | /* |
331 | - * Must not send if we know that source is Anycast also. | |
332 | - * for now we don't know that. | |
331 | + * Must not send error if the source does not uniquely | |
332 | + * identify a single node (RFC2463 Section 2.4). | |
333 | + * We check unspecified / multicast addresses here, | |
334 | + * and anycast addresses will be checked later. | |
333 | 335 | */ |
334 | 336 | if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { |
335 | 337 | LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n"); |
... | ... | @@ -373,6 +375,16 @@ |
373 | 375 | err = ip6_dst_lookup(sk, &dst, &fl); |
374 | 376 | if (err) |
375 | 377 | goto out; |
378 | + | |
379 | + /* | |
380 | + * We won't send icmp if the destination is known | |
381 | + * anycast. | |
382 | + */ | |
383 | + if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) { | |
384 | + LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: acast source\n"); | |
385 | + goto out_dst_release; | |
386 | + } | |
387 | + | |
376 | 388 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
377 | 389 | goto out; |
378 | 390 |
net/ipv6/route.c
... | ... | @@ -413,11 +413,14 @@ |
413 | 413 | rt = ip6_rt_copy(ort); |
414 | 414 | |
415 | 415 | if (rt) { |
416 | - ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); | |
417 | - | |
418 | - if (!(rt->rt6i_flags&RTF_GATEWAY)) | |
416 | + if (!(rt->rt6i_flags&RTF_GATEWAY)) { | |
417 | + if (rt->rt6i_dst.plen != 128 && | |
418 | + ipv6_addr_equal(&rt->rt6i_dst.addr, daddr)) | |
419 | + rt->rt6i_flags |= RTF_ANYCAST; | |
419 | 420 | ipv6_addr_copy(&rt->rt6i_gateway, daddr); |
421 | + } | |
420 | 422 | |
423 | + ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); | |
421 | 424 | rt->rt6i_dst.plen = 128; |
422 | 425 | rt->rt6i_flags |= RTF_CACHE; |
423 | 426 | rt->u.dst.flags |= DST_HOST; |
... | ... | @@ -1413,7 +1416,9 @@ |
1413 | 1416 | rt->u.dst.obsolete = -1; |
1414 | 1417 | |
1415 | 1418 | rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; |
1416 | - if (!anycast) | |
1419 | + if (anycast) | |
1420 | + rt->rt6i_flags |= RTF_ANYCAST; | |
1421 | + else | |
1417 | 1422 | rt->rt6i_flags |= RTF_LOCAL; |
1418 | 1423 | rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); |
1419 | 1424 | if (rt->rt6i_nexthop == NULL) { |
net/netrom/nr_in.c
... | ... | @@ -99,7 +99,7 @@ |
99 | 99 | break; |
100 | 100 | |
101 | 101 | case NR_RESET: |
102 | - if (sysctl_netrom_reset_circuit); | |
102 | + if (sysctl_netrom_reset_circuit) | |
103 | 103 | nr_disconnect(sk, ECONNRESET); |
104 | 104 | break; |
105 | 105 | |
... | ... | @@ -130,7 +130,7 @@ |
130 | 130 | break; |
131 | 131 | |
132 | 132 | case NR_RESET: |
133 | - if (sysctl_netrom_reset_circuit); | |
133 | + if (sysctl_netrom_reset_circuit) | |
134 | 134 | nr_disconnect(sk, ECONNRESET); |
135 | 135 | break; |
136 | 136 | |
... | ... | @@ -265,7 +265,7 @@ |
265 | 265 | break; |
266 | 266 | |
267 | 267 | case NR_RESET: |
268 | - if (sysctl_netrom_reset_circuit); | |
268 | + if (sysctl_netrom_reset_circuit) | |
269 | 269 | nr_disconnect(sk, ECONNRESET); |
270 | 270 | break; |
271 | 271 |
net/xfrm/xfrm_policy.c
... | ... | @@ -346,6 +346,7 @@ |
346 | 346 | struct xfrm_policy *pol, **p; |
347 | 347 | struct xfrm_policy *delpol = NULL; |
348 | 348 | struct xfrm_policy **newpos = NULL; |
349 | + struct dst_entry *gc_list; | |
349 | 350 | |
350 | 351 | write_lock_bh(&xfrm_policy_lock); |
351 | 352 | for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { |
352 | 353 | |
353 | 354 | |
... | ... | @@ -381,9 +382,36 @@ |
381 | 382 | xfrm_pol_hold(policy); |
382 | 383 | write_unlock_bh(&xfrm_policy_lock); |
383 | 384 | |
384 | - if (delpol) { | |
385 | + if (delpol) | |
385 | 386 | xfrm_policy_kill(delpol); |
387 | + | |
388 | + read_lock_bh(&xfrm_policy_lock); | |
389 | + gc_list = NULL; | |
390 | + for (policy = policy->next; policy; policy = policy->next) { | |
391 | + struct dst_entry *dst; | |
392 | + | |
393 | + write_lock(&policy->lock); | |
394 | + dst = policy->bundles; | |
395 | + if (dst) { | |
396 | + struct dst_entry *tail = dst; | |
397 | + while (tail->next) | |
398 | + tail = tail->next; | |
399 | + tail->next = gc_list; | |
400 | + gc_list = dst; | |
401 | + | |
402 | + policy->bundles = NULL; | |
403 | + } | |
404 | + write_unlock(&policy->lock); | |
386 | 405 | } |
406 | + read_unlock_bh(&xfrm_policy_lock); | |
407 | + | |
408 | + while (gc_list) { | |
409 | + struct dst_entry *dst = gc_list; | |
410 | + | |
411 | + gc_list = dst->next; | |
412 | + dst_free(dst); | |
413 | + } | |
414 | + | |
387 | 415 | return 0; |
388 | 416 | } |
389 | 417 | EXPORT_SYMBOL(xfrm_policy_insert); |