aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Kconfig23
-rw-r--r--net/ipv6/addrconf.c22
-rw-r--r--net/ipv6/af_inet6.c4
-rw-r--r--net/ipv6/ip6_flowlabel.c1
-rw-r--r--net/ipv6/ip6_input.c9
-rw-r--r--net/ipv6/ip6_output.c8
-rw-r--r--net/ipv6/ip6_tunnel.c38
-rw-r--r--net/ipv6/ipcomp6.c2
-rw-r--r--net/ipv6/ipv6_sockglue.c3
-rw-r--r--net/ipv6/mcast.c29
-rw-r--r--net/ipv6/netfilter/ip6_queue.c9
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c11
-rw-r--r--net/ipv6/raw.c2
-rw-r--r--net/ipv6/sit.c21
-rw-r--r--net/ipv6/tcp_ipv6.c13
15 files changed, 141 insertions, 54 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index e66ca9381c..ab7a9124f9 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -1,6 +1,26 @@
1# 1#
2# IPv6 configuration 2# IPv6 configuration
3# 3#
4
5# IPv6 as module will cause a CRASH if you try to unload it
6config IPV6
7 tristate "The IPv6 protocol"
8 default m
9 select CRYPTO if IPV6_PRIVACY
10 select CRYPTO_MD5 if IPV6_PRIVACY
11 ---help---
12 This is complemental support for the IP version 6.
13 You will still be able to do traditional IPv4 networking as well.
14
15 For general information about IPv6, see
16 <http://playground.sun.com/pub/ipng/html/ipng-main.html>.
17 For Linux IPv6 development information, see <http://www.linux-ipv6.org>.
18 For specific information about IPv6 under Linux, read the HOWTO at
19 <http://www.bieringer.de/linux/IPv6/>.
20
21 To compile this protocol support as a module, choose M here: the
22 module will be called ipv6.
23
4config IPV6_PRIVACY 24config IPV6_PRIVACY
5 bool "IPv6: Privacy Extensions (RFC 3041) support" 25 bool "IPv6: Privacy Extensions (RFC 3041) support"
6 depends on IPV6 26 depends on IPV6
@@ -71,7 +91,6 @@ config INET6_TUNNEL
71config IPV6_TUNNEL 91config IPV6_TUNNEL
72 tristate "IPv6: IPv6-in-IPv6 tunnel" 92 tristate "IPv6: IPv6-in-IPv6 tunnel"
73 depends on IPV6 93 depends on IPV6
74 select INET6_TUNNEL
75 ---help--- 94 ---help---
76 Support for IPv6-in-IPv6 tunnels described in RFC 2473. 95 Support for IPv6-in-IPv6 tunnels described in RFC 2473.
77 96
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 14f5c53235..77004b9456 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -57,6 +57,7 @@
57#endif 57#endif
58#include <linux/delay.h> 58#include <linux/delay.h>
59#include <linux/notifier.h> 59#include <linux/notifier.h>
60#include <linux/string.h>
60 61
61#include <net/sock.h> 62#include <net/sock.h>
62#include <net/snmp.h> 63#include <net/snmp.h>
@@ -2776,7 +2777,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
2776 read_lock_bh(&idev->lock); 2777 read_lock_bh(&idev->lock);
2777 switch (type) { 2778 switch (type) {
2778 case UNICAST_ADDR: 2779 case UNICAST_ADDR:
2779 /* unicast address */ 2780 /* unicast address incl. temp addr */
2780 for (ifa = idev->addr_list; ifa; 2781 for (ifa = idev->addr_list; ifa;
2781 ifa = ifa->if_next, ip_idx++) { 2782 ifa = ifa->if_next, ip_idx++) {
2782 if (ip_idx < s_ip_idx) 2783 if (ip_idx < s_ip_idx)
@@ -2787,19 +2788,6 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
2787 NLM_F_MULTI)) <= 0) 2788 NLM_F_MULTI)) <= 0)
2788 goto done; 2789 goto done;
2789 } 2790 }
2790 /* temp addr */
2791#ifdef CONFIG_IPV6_PRIVACY
2792 for (ifa = idev->tempaddr_list; ifa;
2793 ifa = ifa->tmp_next, ip_idx++) {
2794 if (ip_idx < s_ip_idx)
2795 continue;
2796 if ((err = inet6_fill_ifaddr(skb, ifa,
2797 NETLINK_CB(cb->skb).pid,
2798 cb->nlh->nlmsg_seq, RTM_NEWADDR,
2799 NLM_F_MULTI)) <= 0)
2800 goto done;
2801 }
2802#endif
2803 break; 2791 break;
2804 case MULTICAST_ADDR: 2792 case MULTICAST_ADDR:
2805 /* multicast address */ 2793 /* multicast address */
@@ -2922,6 +2910,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
2922 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); 2910 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
2923 r = NLMSG_DATA(nlh); 2911 r = NLMSG_DATA(nlh);
2924 r->ifi_family = AF_INET6; 2912 r->ifi_family = AF_INET6;
2913 r->__ifi_pad = 0;
2925 r->ifi_type = dev->type; 2914 r->ifi_type = dev->type;
2926 r->ifi_index = dev->ifindex; 2915 r->ifi_index = dev->ifindex;
2927 r->ifi_flags = dev_get_flags(dev); 2916 r->ifi_flags = dev_get_flags(dev);
@@ -3029,9 +3018,12 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3029 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags); 3018 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags);
3030 pmsg = NLMSG_DATA(nlh); 3019 pmsg = NLMSG_DATA(nlh);
3031 pmsg->prefix_family = AF_INET6; 3020 pmsg->prefix_family = AF_INET6;
3021 pmsg->prefix_pad1 = 0;
3022 pmsg->prefix_pad2 = 0;
3032 pmsg->prefix_ifindex = idev->dev->ifindex; 3023 pmsg->prefix_ifindex = idev->dev->ifindex;
3033 pmsg->prefix_len = pinfo->prefix_len; 3024 pmsg->prefix_len = pinfo->prefix_len;
3034 pmsg->prefix_type = pinfo->type; 3025 pmsg->prefix_type = pinfo->type;
3026 pmsg->prefix_pad3 = 0;
3035 3027
3036 pmsg->prefix_flags = 0; 3028 pmsg->prefix_flags = 0;
3037 if (pinfo->onlink) 3029 if (pinfo->onlink)
@@ -3437,7 +3429,7 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
3437 * by sysctl and we wouldn't want anyone to change it under our feet 3429 * by sysctl and we wouldn't want anyone to change it under our feet
3438 * (see SIOCSIFNAME). 3430 * (see SIOCSIFNAME).
3439 */ 3431 */
3440 dev_name = net_sysctl_strdup(dev_name); 3432 dev_name = kstrdup(dev_name, GFP_KERNEL);
3441 if (!dev_name) 3433 if (!dev_name)
3442 goto free; 3434 goto free;
3443 3435
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 2b193e3df4..28d9bcab09 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -774,7 +774,6 @@ static int __init inet6_init(void)
774 if (if6_proc_init()) 774 if (if6_proc_init())
775 goto proc_if6_fail; 775 goto proc_if6_fail;
776#endif 776#endif
777 ipv6_packet_init();
778 ip6_route_init(); 777 ip6_route_init();
779 ip6_flowlabel_init(); 778 ip6_flowlabel_init();
780 err = addrconf_init(); 779 err = addrconf_init();
@@ -791,6 +790,8 @@ static int __init inet6_init(void)
791 /* Init v6 transport protocols. */ 790 /* Init v6 transport protocols. */
792 udpv6_init(); 791 udpv6_init();
793 tcpv6_init(); 792 tcpv6_init();
793
794 ipv6_packet_init();
794 err = 0; 795 err = 0;
795out: 796out:
796 return err; 797 return err;
@@ -798,7 +799,6 @@ out:
798addrconf_fail: 799addrconf_fail:
799 ip6_flowlabel_cleanup(); 800 ip6_flowlabel_cleanup();
800 ip6_route_cleanup(); 801 ip6_route_cleanup();
801 ipv6_packet_cleanup();
802#ifdef CONFIG_PROC_FS 802#ifdef CONFIG_PROC_FS
803 if6_proc_exit(); 803 if6_proc_exit();
804proc_if6_fail: 804proc_if6_fail:
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 0e5f7499de..b6c73da5ff 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -244,7 +244,6 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
244 opt_space->opt_nflen = 0; 244 opt_space->opt_nflen = 0;
245 } 245 }
246 opt_space->dst1opt = fopt->dst1opt; 246 opt_space->dst1opt = fopt->dst1opt;
247 opt_space->auth = fopt->auth;
248 opt_space->opt_flen = fopt->opt_flen; 247 opt_space->opt_flen = fopt->opt_flen;
249 return opt_space; 248 return opt_space;
250} 249}
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 866f10726c..10fbb50dae 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -198,12 +198,13 @@ resubmit:
198 if (!raw_sk) { 198 if (!raw_sk) {
199 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 199 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
200 IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); 200 IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS);
201 icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff); 201 icmpv6_send(skb, ICMPV6_PARAMPROB,
202 ICMPV6_UNK_NEXTHDR, nhoff,
203 skb->dev);
202 } 204 }
203 } else { 205 } else
204 IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); 206 IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS);
205 kfree_skb(skb); 207 kfree_skb(skb);
206 }
207 } 208 }
208 rcu_read_unlock(); 209 rcu_read_unlock();
209 return 0; 210 return 0;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 06e7cdaeed..ae652ca14b 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -465,7 +465,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
465 to->pkt_type = from->pkt_type; 465 to->pkt_type = from->pkt_type;
466 to->priority = from->priority; 466 to->priority = from->priority;
467 to->protocol = from->protocol; 467 to->protocol = from->protocol;
468 to->security = from->security;
469 dst_release(to->dst); 468 dst_release(to->dst);
470 to->dst = dst_clone(from->dst); 469 to->dst = dst_clone(from->dst);
471 to->dev = from->dev; 470 to->dev = from->dev;
@@ -793,13 +792,8 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
793 if (ipv6_addr_any(&fl->fl6_src)) { 792 if (ipv6_addr_any(&fl->fl6_src)) {
794 err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); 793 err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
795 794
796 if (err) { 795 if (err)
797#if IP6_DEBUG >= 2
798 printk(KERN_DEBUG "ip6_dst_lookup: "
799 "no available source address\n");
800#endif
801 goto out_err_release; 796 goto out_err_release;
802 }
803 } 797 }
804 798
805 return 0; 799 return 0;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index ba3b0c267f..0961372940 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1110,11 +1110,39 @@ ip6ip6_fb_tnl_dev_init(struct net_device *dev)
1110 return 0; 1110 return 0;
1111} 1111}
1112 1112
1113#ifdef CONFIG_INET6_TUNNEL
1113static struct xfrm6_tunnel ip6ip6_handler = { 1114static struct xfrm6_tunnel ip6ip6_handler = {
1114 .handler = ip6ip6_rcv, 1115 .handler = ip6ip6_rcv,
1115 .err_handler = ip6ip6_err, 1116 .err_handler = ip6ip6_err,
1116}; 1117};
1117 1118
1119static inline int ip6ip6_register(void)
1120{
1121 return xfrm6_tunnel_register(&ip6ip6_handler);
1122}
1123
1124static inline int ip6ip6_unregister(void)
1125{
1126 return xfrm6_tunnel_deregister(&ip6ip6_handler);
1127}
1128#else
1129static struct inet6_protocol xfrm6_tunnel_protocol = {
1130 .handler = ip6ip6_rcv,
1131 .err_handler = ip6ip6_err,
1132 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1133};
1134
1135static inline int ip6ip6_register(void)
1136{
1137 return inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6);
1138}
1139
1140static inline int ip6ip6_unregister(void)
1141{
1142 return inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6);
1143}
1144#endif
1145
1118/** 1146/**
1119 * ip6_tunnel_init - register protocol and reserve needed resources 1147 * ip6_tunnel_init - register protocol and reserve needed resources
1120 * 1148 *
@@ -1125,7 +1153,7 @@ static int __init ip6_tunnel_init(void)
1125{ 1153{
1126 int err; 1154 int err;
1127 1155
1128 if (xfrm6_tunnel_register(&ip6ip6_handler) < 0) { 1156 if (ip6ip6_register() < 0) {
1129 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n"); 1157 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n");
1130 return -EAGAIN; 1158 return -EAGAIN;
1131 } 1159 }
@@ -1144,7 +1172,7 @@ static int __init ip6_tunnel_init(void)
1144 } 1172 }
1145 return 0; 1173 return 0;
1146fail: 1174fail:
1147 xfrm6_tunnel_deregister(&ip6ip6_handler); 1175 ip6ip6_unregister();
1148 return err; 1176 return err;
1149} 1177}
1150 1178
@@ -1154,7 +1182,7 @@ fail:
1154 1182
1155static void __exit ip6_tunnel_cleanup(void) 1183static void __exit ip6_tunnel_cleanup(void)
1156{ 1184{
1157 if (xfrm6_tunnel_deregister(&ip6ip6_handler) < 0) 1185 if (ip6ip6_unregister() < 0)
1158 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); 1186 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
1159 1187
1160 unregister_netdev(ip6ip6_fb_tnl_dev); 1188 unregister_netdev(ip6ip6_fb_tnl_dev);
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 423feb46cc..135383ef53 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -354,7 +354,7 @@ static struct crypto_tfm **ipcomp6_alloc_tfms(const char *alg_name)
354 int cpu; 354 int cpu;
355 355
356 /* This can be any valid CPU ID so we don't need locking. */ 356 /* This can be any valid CPU ID so we don't need locking. */
357 cpu = smp_processor_id(); 357 cpu = raw_smp_processor_id();
358 358
359 list_for_each_entry(pos, &ipcomp6_tfms_list, list) { 359 list_for_each_entry(pos, &ipcomp6_tfms_list, list) {
360 struct crypto_tfm *tfm; 360 struct crypto_tfm *tfm;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index f3ef4c38d3..3bc144a79f 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -504,6 +504,9 @@ done:
504 break; 504 break;
505 case IPV6_IPSEC_POLICY: 505 case IPV6_IPSEC_POLICY:
506 case IPV6_XFRM_POLICY: 506 case IPV6_XFRM_POLICY:
507 retv = -EPERM;
508 if (!capable(CAP_NET_ADMIN))
509 break;
507 retv = xfrm_user_policy(sk, optname, optval, optlen); 510 retv = xfrm_user_policy(sk, optname, optval, optlen);
508 break; 511 break;
509 512
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 562fcd14fd..29fed6e58d 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -281,7 +281,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
281 } 281 }
282 write_unlock_bh(&ipv6_sk_mc_lock); 282 write_unlock_bh(&ipv6_sk_mc_lock);
283 283
284 return -ENOENT; 284 return -EADDRNOTAVAIL;
285} 285}
286 286
287static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex) 287static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex)
@@ -386,12 +386,16 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
386 if (ipv6_addr_equal(&pmc->addr, group)) 386 if (ipv6_addr_equal(&pmc->addr, group))
387 break; 387 break;
388 } 388 }
389 if (!pmc) /* must have a prior join */ 389 if (!pmc) { /* must have a prior join */
390 err = -EINVAL;
390 goto done; 391 goto done;
392 }
391 /* if a source filter was set, must be the same mode as before */ 393 /* if a source filter was set, must be the same mode as before */
392 if (pmc->sflist) { 394 if (pmc->sflist) {
393 if (pmc->sfmode != omode) 395 if (pmc->sfmode != omode) {
396 err = -EINVAL;
394 goto done; 397 goto done;
398 }
395 } else if (pmc->sfmode != omode) { 399 } else if (pmc->sfmode != omode) {
396 /* allow mode switches for empty-set filters */ 400 /* allow mode switches for empty-set filters */
397 ip6_mc_add_src(idev, group, omode, 0, NULL, 0); 401 ip6_mc_add_src(idev, group, omode, 0, NULL, 0);
@@ -402,7 +406,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
402 psl = pmc->sflist; 406 psl = pmc->sflist;
403 if (!add) { 407 if (!add) {
404 if (!psl) 408 if (!psl)
405 goto done; 409 goto done; /* err = -EADDRNOTAVAIL */
406 rv = !0; 410 rv = !0;
407 for (i=0; i<psl->sl_count; i++) { 411 for (i=0; i<psl->sl_count; i++) {
408 rv = memcmp(&psl->sl_addr[i], source, 412 rv = memcmp(&psl->sl_addr[i], source,
@@ -411,7 +415,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
411 break; 415 break;
412 } 416 }
413 if (rv) /* source not found */ 417 if (rv) /* source not found */
414 goto done; 418 goto done; /* err = -EADDRNOTAVAIL */
415 419
416 /* special case - (INCLUDE, empty) == LEAVE_GROUP */ 420 /* special case - (INCLUDE, empty) == LEAVE_GROUP */
417 if (psl->sl_count == 1 && omode == MCAST_INCLUDE) { 421 if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
@@ -488,6 +492,7 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
488 struct inet6_dev *idev; 492 struct inet6_dev *idev;
489 struct ipv6_pinfo *inet6 = inet6_sk(sk); 493 struct ipv6_pinfo *inet6 = inet6_sk(sk);
490 struct ip6_sf_socklist *newpsl, *psl; 494 struct ip6_sf_socklist *newpsl, *psl;
495 int leavegroup = 0;
491 int i, err; 496 int i, err;
492 497
493 group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr; 498 group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr;
@@ -503,7 +508,12 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
503 if (!idev) 508 if (!idev)
504 return -ENODEV; 509 return -ENODEV;
505 dev = idev->dev; 510 dev = idev->dev;
506 err = -EADDRNOTAVAIL; 511
512 err = 0;
513 if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) {
514 leavegroup = 1;
515 goto done;
516 }
507 517
508 for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { 518 for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
509 if (pmc->ifindex != gsf->gf_interface) 519 if (pmc->ifindex != gsf->gf_interface)
@@ -511,8 +521,10 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
511 if (ipv6_addr_equal(&pmc->addr, group)) 521 if (ipv6_addr_equal(&pmc->addr, group))
512 break; 522 break;
513 } 523 }
514 if (!pmc) /* must have a prior join */ 524 if (!pmc) { /* must have a prior join */
525 err = -EINVAL;
515 goto done; 526 goto done;
527 }
516 if (gsf->gf_numsrc) { 528 if (gsf->gf_numsrc) {
517 newpsl = (struct ip6_sf_socklist *)sock_kmalloc(sk, 529 newpsl = (struct ip6_sf_socklist *)sock_kmalloc(sk,
518 IP6_SFLSIZE(gsf->gf_numsrc), GFP_ATOMIC); 530 IP6_SFLSIZE(gsf->gf_numsrc), GFP_ATOMIC);
@@ -544,10 +556,13 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
544 (void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0); 556 (void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0);
545 pmc->sflist = newpsl; 557 pmc->sflist = newpsl;
546 pmc->sfmode = gsf->gf_fmode; 558 pmc->sfmode = gsf->gf_fmode;
559 err = 0;
547done: 560done:
548 read_unlock_bh(&idev->lock); 561 read_unlock_bh(&idev->lock);
549 in6_dev_put(idev); 562 in6_dev_put(idev);
550 dev_put(dev); 563 dev_put(dev);
564 if (leavegroup)
565 err = ipv6_sock_mc_drop(sk, gsf->gf_interface, group);
551 return err; 566 return err;
552} 567}
553 568
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 750943e2d3..a16df5b27c 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -76,7 +76,9 @@ static DECLARE_MUTEX(ipqnl_sem);
76static void 76static void
77ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) 77ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)
78{ 78{
79 local_bh_disable();
79 nf_reinject(entry->skb, entry->info, verdict); 80 nf_reinject(entry->skb, entry->info, verdict);
81 local_bh_enable();
80 kfree(entry); 82 kfree(entry);
81} 83}
82 84
@@ -209,6 +211,12 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
209 break; 211 break;
210 212
211 case IPQ_COPY_PACKET: 213 case IPQ_COPY_PACKET:
214 if (entry->skb->ip_summed == CHECKSUM_HW &&
215 (*errp = skb_checksum_help(entry->skb,
216 entry->info->outdev == NULL))) {
217 read_unlock_bh(&queue_lock);
218 return NULL;
219 }
212 if (copy_range == 0 || copy_range > entry->skb->len) 220 if (copy_range == 0 || copy_range > entry->skb->len)
213 data_len = entry->skb->len; 221 data_len = entry->skb->len;
214 else 222 else
@@ -379,6 +387,7 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
379 if (!skb_ip_make_writable(&e->skb, v->data_len)) 387 if (!skb_ip_make_writable(&e->skb, v->data_len))
380 return -ENOMEM; 388 return -ENOMEM;
381 memcpy(e->skb->data, v->payload, v->data_len); 389 memcpy(e->skb->data, v->payload, v->data_len);
390 e->skb->ip_summed = CHECKSUM_NONE;
382 e->skb->nfcache |= NFC_ALTERED; 391 e->skb->nfcache |= NFC_ALTERED;
383 392
384 /* 393 /*
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index c44685e391..a692e26a4f 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -373,9 +373,10 @@ ip6t_log_packet(unsigned int hooknum,
373 in ? in->name : "", 373 in ? in->name : "",
374 out ? out->name : ""); 374 out ? out->name : "");
375 if (in && !out) { 375 if (in && !out) {
376 unsigned int len;
376 /* MAC logging for input chain only. */ 377 /* MAC logging for input chain only. */
377 printk("MAC="); 378 printk("MAC=");
378 if (skb->dev && skb->dev->hard_header_len && 379 if (skb->dev && (len = skb->dev->hard_header_len) &&
379 skb->mac.raw != skb->nh.raw) { 380 skb->mac.raw != skb->nh.raw) {
380 unsigned char *p = skb->mac.raw; 381 unsigned char *p = skb->mac.raw;
381 int i; 382 int i;
@@ -384,9 +385,11 @@ ip6t_log_packet(unsigned int hooknum,
384 (p -= ETH_HLEN) < skb->head) 385 (p -= ETH_HLEN) < skb->head)
385 p = NULL; 386 p = NULL;
386 387
387 if (p != NULL) 388 if (p != NULL) {
388 for (i = 0; i < skb->dev->hard_header_len; i++) 389 for (i = 0; i < len; i++)
389 printk("%02x", p[i]); 390 printk("%02x%s", p[i],
391 i == len - 1 ? "" : ":");
392 }
390 printk(" "); 393 printk(" ");
391 394
392 if (skb->dev->type == ARPHRD_SIT) { 395 if (skb->dev->type == ARPHRD_SIT) {
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index e2b848ec98..1d4d75b34d 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -328,6 +328,8 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
328 328
329 if (skb->ip_summed != CHECKSUM_UNNECESSARY) { 329 if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
330 if (skb->ip_summed == CHECKSUM_HW) { 330 if (skb->ip_summed == CHECKSUM_HW) {
331 skb_postpull_rcsum(skb, skb->nh.raw,
332 skb->h.raw - skb->nh.raw);
331 skb->ip_summed = CHECKSUM_UNNECESSARY; 333 skb->ip_summed = CHECKSUM_UNNECESSARY;
332 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, 334 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
333 &skb->nh.ipv6h->daddr, 335 &skb->nh.ipv6h->daddr,
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b788f55e13..e553e5b80d 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -195,7 +195,6 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
195 dev_hold(dev); 195 dev_hold(dev);
196 196
197 ipip6_tunnel_link(nt); 197 ipip6_tunnel_link(nt);
198 /* Do not decrement MOD_USE_COUNT here. */
199 return nt; 198 return nt;
200 199
201failed: 200failed:
@@ -794,10 +793,28 @@ static struct net_protocol sit_protocol = {
794 .err_handler = ipip6_err, 793 .err_handler = ipip6_err,
795}; 794};
796 795
796static void __exit sit_destroy_tunnels(void)
797{
798 int prio;
799
800 for (prio = 1; prio < 4; prio++) {
801 int h;
802 for (h = 0; h < HASH_SIZE; h++) {
803 struct ip_tunnel *t;
804 while ((t = tunnels[prio][h]) != NULL)
805 unregister_netdevice(t->dev);
806 }
807 }
808}
809
797void __exit sit_cleanup(void) 810void __exit sit_cleanup(void)
798{ 811{
799 inet_del_protocol(&sit_protocol, IPPROTO_IPV6); 812 inet_del_protocol(&sit_protocol, IPPROTO_IPV6);
800 unregister_netdev(ipip6_fb_tunnel_dev); 813
814 rtnl_lock();
815 sit_destroy_tunnels();
816 unregister_netdevice(ipip6_fb_tunnel_dev);
817 rtnl_unlock();
801} 818}
802 819
803int __init sit_init(void) 820int __init sit_init(void)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 2414937f2a..ef29cfd936 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -158,9 +158,14 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
158 tcp_port_rover = rover; 158 tcp_port_rover = rover;
159 spin_unlock(&tcp_portalloc_lock); 159 spin_unlock(&tcp_portalloc_lock);
160 160
161 /* Exhausted local port range during search? */ 161 /* Exhausted local port range during search? It is not
162 * possible for us to be holding one of the bind hash
163 * locks if this test triggers, because if 'remaining'
164 * drops to zero, we broke out of the do/while loop at
165 * the top level, not from the 'break;' statement.
166 */
162 ret = 1; 167 ret = 1;
163 if (remaining <= 0) 168 if (unlikely(remaining <= 0))
164 goto fail; 169 goto fail;
165 170
166 /* OK, here is the one we will use. */ 171 /* OK, here is the one we will use. */
@@ -2018,14 +2023,14 @@ static int tcp_v6_init_sock(struct sock *sk)
2018 */ 2023 */
2019 tp->snd_ssthresh = 0x7fffffff; 2024 tp->snd_ssthresh = 0x7fffffff;
2020 tp->snd_cwnd_clamp = ~0; 2025 tp->snd_cwnd_clamp = ~0;
2021 tp->mss_cache_std = tp->mss_cache = 536; 2026 tp->mss_cache = 536;
2022 2027
2023 tp->reordering = sysctl_tcp_reordering; 2028 tp->reordering = sysctl_tcp_reordering;
2024 2029
2025 sk->sk_state = TCP_CLOSE; 2030 sk->sk_state = TCP_CLOSE;
2026 2031
2027 tp->af_specific = &ipv6_specific; 2032 tp->af_specific = &ipv6_specific;
2028 2033 tp->ca_ops = &tcp_init_congestion_ops;
2029 sk->sk_write_space = sk_stream_write_space; 2034 sk->sk_write_space = sk_stream_write_space;
2030 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 2035 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
2031 2036