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 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 2 |
6 files changed, 48 insertions, 17 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) |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index b843a650be71..802a1a6b1037 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -944,7 +944,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
944 | * comment in that function for the gory details. -acme | 944 | * comment in that function for the gory details. -acme |
945 | */ | 945 | */ |
946 | 946 | ||
947 | sk->sk_gso_type = SKB_GSO_TCPV6; | 947 | newsk->sk_gso_type = SKB_GSO_TCPV6; |
948 | __ip6_dst_store(newsk, dst, NULL); | 948 | __ip6_dst_store(newsk, dst, NULL); |
949 | 949 | ||
950 | newtcp6sk = (struct tcp6_sock *)newsk; | 950 | newtcp6sk = (struct tcp6_sock *)newsk; |