diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/addrconf.c | 4 | ||||
| -rw-r--r-- | net/ipv6/icmp.c | 13 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 2 | ||||
| -rw-r--r-- | net/ipv6/mcast.c | 10 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 34 | 
5 files changed, 47 insertions, 16 deletions
| diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8ea1e36bf8eb..0c5042e7380d 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -1909,11 +1909,11 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | |||
| 1909 | ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags); | 1909 | ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags); | 
| 1910 | 1910 | ||
| 1911 | if (!IS_ERR(ifp)) { | 1911 | if (!IS_ERR(ifp)) { | 
| 1912 | spin_lock(&ifp->lock); | 1912 | spin_lock_bh(&ifp->lock); | 
| 1913 | ifp->valid_lft = valid_lft; | 1913 | ifp->valid_lft = valid_lft; | 
| 1914 | ifp->prefered_lft = prefered_lft; | 1914 | ifp->prefered_lft = prefered_lft; | 
| 1915 | ifp->tstamp = jiffies; | 1915 | ifp->tstamp = jiffies; | 
| 1916 | spin_unlock(&ifp->lock); | 1916 | spin_unlock_bh(&ifp->lock); | 
| 1917 | 1917 | ||
| 1918 | addrconf_dad_start(ifp, 0); | 1918 | addrconf_dad_start(ifp, 0); | 
| 1919 | in6_ifa_put(ifp); | 1919 | in6_ifa_put(ifp); | 
| diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 1044b6fce0d5..3d6e9a351150 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
| @@ -712,6 +712,11 @@ discard_it: | |||
| 712 | return 0; | 712 | return 0; | 
| 713 | } | 713 | } | 
| 714 | 714 | ||
| 715 | /* | ||
| 716 | * Special lock-class for __icmpv6_socket: | ||
| 717 | */ | ||
| 718 | static struct lock_class_key icmpv6_socket_sk_dst_lock_key; | ||
| 719 | |||
| 715 | int __init icmpv6_init(struct net_proto_family *ops) | 720 | int __init icmpv6_init(struct net_proto_family *ops) | 
| 716 | { | 721 | { | 
| 717 | struct sock *sk; | 722 | struct sock *sk; | 
| @@ -730,6 +735,14 @@ int __init icmpv6_init(struct net_proto_family *ops) | |||
| 730 | 735 | ||
| 731 | sk = per_cpu(__icmpv6_socket, i)->sk; | 736 | sk = per_cpu(__icmpv6_socket, i)->sk; | 
| 732 | sk->sk_allocation = GFP_ATOMIC; | 737 | sk->sk_allocation = GFP_ATOMIC; | 
| 738 | /* | ||
| 739 | * Split off their lock-class, because sk->sk_dst_lock | ||
| 740 | * gets used from softirqs, which is safe for | ||
| 741 | * __icmpv6_socket (because those never get directly used | ||
| 742 | * via userspace syscalls), but unsafe for normal sockets. | ||
| 743 | */ | ||
| 744 | lockdep_set_class(&sk->sk_dst_lock, | ||
| 745 | &icmpv6_socket_sk_dst_lock_key); | ||
| 733 | 746 | ||
| 734 | /* Enough space for 2 64K ICMP packets, including | 747 | /* Enough space for 2 64K ICMP packets, including | 
| 735 | * sk_buff struct overhead. | 748 | * sk_buff struct overhead. | 
| diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 69451af6abe7..4fb47a252913 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -1095,7 +1095,7 @@ alloc_new_skb: | |||
| 1095 | skb_prev->csum = csum_sub(skb_prev->csum, | 1095 | skb_prev->csum = csum_sub(skb_prev->csum, | 
| 1096 | skb->csum); | 1096 | skb->csum); | 
| 1097 | data += fraggap; | 1097 | data += fraggap; | 
| 1098 | skb_trim(skb_prev, maxfraglen); | 1098 | pskb_trim_unique(skb_prev, maxfraglen); | 
| 1099 | } | 1099 | } | 
| 1100 | copy = datalen - transhdrlen - fraggap; | 1100 | copy = datalen - transhdrlen - fraggap; | 
| 1101 | if (copy < 0) { | 1101 | if (copy < 0) { | 
| diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 9d697d4dcffc..639eb20c9f1f 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
| @@ -268,13 +268,14 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
| 268 | if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) { | 268 | if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) { | 
| 269 | struct inet6_dev *idev = in6_dev_get(dev); | 269 | struct inet6_dev *idev = in6_dev_get(dev); | 
| 270 | 270 | ||
| 271 | (void) ip6_mc_leave_src(sk, mc_lst, idev); | ||
| 271 | if (idev) { | 272 | if (idev) { | 
| 272 | (void) ip6_mc_leave_src(sk,mc_lst,idev); | ||
| 273 | __ipv6_dev_mc_dec(idev, &mc_lst->addr); | 273 | __ipv6_dev_mc_dec(idev, &mc_lst->addr); | 
| 274 | in6_dev_put(idev); | 274 | in6_dev_put(idev); | 
| 275 | } | 275 | } | 
| 276 | dev_put(dev); | 276 | dev_put(dev); | 
| 277 | } | 277 | } else | 
| 278 | (void) ip6_mc_leave_src(sk, mc_lst, NULL); | ||
| 278 | sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); | 279 | sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); | 
| 279 | return 0; | 280 | return 0; | 
| 280 | } | 281 | } | 
| @@ -334,13 +335,14 @@ void ipv6_sock_mc_close(struct sock *sk) | |||
| 334 | if (dev) { | 335 | if (dev) { | 
| 335 | struct inet6_dev *idev = in6_dev_get(dev); | 336 | struct inet6_dev *idev = in6_dev_get(dev); | 
| 336 | 337 | ||
| 338 | (void) ip6_mc_leave_src(sk, mc_lst, idev); | ||
| 337 | if (idev) { | 339 | if (idev) { | 
| 338 | (void) ip6_mc_leave_src(sk, mc_lst, idev); | ||
| 339 | __ipv6_dev_mc_dec(idev, &mc_lst->addr); | 340 | __ipv6_dev_mc_dec(idev, &mc_lst->addr); | 
| 340 | in6_dev_put(idev); | 341 | in6_dev_put(idev); | 
| 341 | } | 342 | } | 
| 342 | dev_put(dev); | 343 | dev_put(dev); | 
| 343 | } | 344 | } else | 
| 345 | (void) ip6_mc_leave_src(sk, mc_lst, NULL); | ||
| 344 | 346 | ||
| 345 | sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); | 347 | sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); | 
| 346 | 348 | ||
| diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index f26898b00347..c9d6b23cd3f7 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
| @@ -1398,23 +1398,39 @@ static int __init ip6_tables_init(void) | |||
| 1398 | { | 1398 | { | 
| 1399 | int ret; | 1399 | int ret; | 
| 1400 | 1400 | ||
| 1401 | xt_proto_init(AF_INET6); | 1401 | ret = xt_proto_init(AF_INET6); | 
| 1402 | if (ret < 0) | ||
| 1403 | goto err1; | ||
| 1402 | 1404 | ||
| 1403 | /* Noone else will be downing sem now, so we won't sleep */ | 1405 | /* Noone else will be downing sem now, so we won't sleep */ | 
| 1404 | xt_register_target(&ip6t_standard_target); | 1406 | ret = xt_register_target(&ip6t_standard_target); | 
| 1405 | xt_register_target(&ip6t_error_target); | 1407 | if (ret < 0) | 
| 1406 | xt_register_match(&icmp6_matchstruct); | 1408 | goto err2; | 
| 1409 | ret = xt_register_target(&ip6t_error_target); | ||
| 1410 | if (ret < 0) | ||
| 1411 | goto err3; | ||
| 1412 | ret = xt_register_match(&icmp6_matchstruct); | ||
| 1413 | if (ret < 0) | ||
| 1414 | goto err4; | ||
| 1407 | 1415 | ||
| 1408 | /* Register setsockopt */ | 1416 | /* Register setsockopt */ | 
| 1409 | ret = nf_register_sockopt(&ip6t_sockopts); | 1417 | ret = nf_register_sockopt(&ip6t_sockopts); | 
| 1410 | if (ret < 0) { | 1418 | if (ret < 0) | 
| 1411 | duprintf("Unable to register sockopts.\n"); | 1419 | goto err5; | 
| 1412 | xt_proto_fini(AF_INET6); | ||
| 1413 | return ret; | ||
| 1414 | } | ||
| 1415 | 1420 | ||
| 1416 | printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); | 1421 | printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); | 
| 1417 | return 0; | 1422 | return 0; | 
| 1423 | |||
| 1424 | err5: | ||
| 1425 | xt_unregister_match(&icmp6_matchstruct); | ||
| 1426 | err4: | ||
| 1427 | xt_unregister_target(&ip6t_error_target); | ||
| 1428 | err3: | ||
| 1429 | xt_unregister_target(&ip6t_standard_target); | ||
| 1430 | err2: | ||
| 1431 | xt_proto_fini(AF_INET6); | ||
| 1432 | err1: | ||
| 1433 | return ret; | ||
| 1418 | } | 1434 | } | 
| 1419 | 1435 | ||
| 1420 | static void __exit ip6_tables_fini(void) | 1436 | static void __exit ip6_tables_fini(void) | 
