diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/Kconfig | 23 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 22 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 1 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 9 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 8 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 38 | ||||
-rw-r--r-- | net/ipv6/ipcomp6.c | 2 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 3 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 29 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 9 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_LOG.c | 11 | ||||
-rw-r--r-- | net/ipv6/raw.c | 2 | ||||
-rw-r--r-- | net/ipv6/sit.c | 21 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 13 |
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 | ||
6 | config 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 | |||
4 | config IPV6_PRIVACY | 24 | config 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 | |||
71 | config IPV6_TUNNEL | 91 | config 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; |
795 | out: | 796 | out: |
796 | return err; | 797 | return err; |
@@ -798,7 +799,6 @@ out: | |||
798 | addrconf_fail: | 799 | addrconf_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(); |
804 | proc_if6_fail: | 804 | proc_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 | ||
1113 | static struct xfrm6_tunnel ip6ip6_handler = { | 1114 | static 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 | ||
1119 | static inline int ip6ip6_register(void) | ||
1120 | { | ||
1121 | return xfrm6_tunnel_register(&ip6ip6_handler); | ||
1122 | } | ||
1123 | |||
1124 | static inline int ip6ip6_unregister(void) | ||
1125 | { | ||
1126 | return xfrm6_tunnel_deregister(&ip6ip6_handler); | ||
1127 | } | ||
1128 | #else | ||
1129 | static 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 | |||
1135 | static inline int ip6ip6_register(void) | ||
1136 | { | ||
1137 | return inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6); | ||
1138 | } | ||
1139 | |||
1140 | static 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; |
1146 | fail: | 1174 | fail: |
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 | ||
1155 | static void __exit ip6_tunnel_cleanup(void) | 1183 | static 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 | ||
287 | static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex) | 287 | static 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; | ||
547 | done: | 560 | done: |
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); | |||
76 | static void | 76 | static void |
77 | ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) | 77 | ipq_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 | ||
201 | failed: | 200 | failed: |
@@ -794,10 +793,28 @@ static struct net_protocol sit_protocol = { | |||
794 | .err_handler = ipip6_err, | 793 | .err_handler = ipip6_err, |
795 | }; | 794 | }; |
796 | 795 | ||
796 | static 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 | |||
797 | void __exit sit_cleanup(void) | 810 | void __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 | ||
803 | int __init sit_init(void) | 820 | int __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 | ||