diff options
Diffstat (limited to 'net/ipv6/af_inet6.c')
| -rw-r--r-- | net/ipv6/af_inet6.c | 70 |
1 files changed, 37 insertions, 33 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 12e69d364dd5..56b9bf2516f4 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/proc_fs.h> | 36 | #include <linux/proc_fs.h> |
| 37 | #include <linux/stat.h> | 37 | #include <linux/stat.h> |
| 38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
| 39 | #include <linux/slab.h> | ||
| 39 | 40 | ||
| 40 | #include <linux/inet.h> | 41 | #include <linux/inet.h> |
| 41 | #include <linux/netdevice.h> | 42 | #include <linux/netdevice.h> |
| @@ -199,7 +200,7 @@ lookup_protocol: | |||
| 199 | 200 | ||
| 200 | inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk); | 201 | inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk); |
| 201 | np->hop_limit = -1; | 202 | np->hop_limit = -1; |
| 202 | np->mcast_hops = -1; | 203 | np->mcast_hops = IPV6_DEFAULT_MCASTHOPS; |
| 203 | np->mc_loop = 1; | 204 | np->mc_loop = 1; |
| 204 | np->pmtudisc = IPV6_PMTUDISC_WANT; | 205 | np->pmtudisc = IPV6_PMTUDISC_WANT; |
| 205 | np->ipv6only = net->ipv6.sysctl.bindv6only; | 206 | np->ipv6only = net->ipv6.sysctl.bindv6only; |
| @@ -416,6 +417,9 @@ void inet6_destroy_sock(struct sock *sk) | |||
| 416 | if ((skb = xchg(&np->pktoptions, NULL)) != NULL) | 417 | if ((skb = xchg(&np->pktoptions, NULL)) != NULL) |
| 417 | kfree_skb(skb); | 418 | kfree_skb(skb); |
| 418 | 419 | ||
| 420 | if ((skb = xchg(&np->rxpmtu, NULL)) != NULL) | ||
| 421 | kfree_skb(skb); | ||
| 422 | |||
| 419 | /* Free flowlabels */ | 423 | /* Free flowlabels */ |
| 420 | fl6_free_socklist(sk); | 424 | fl6_free_socklist(sk); |
| 421 | 425 | ||
| @@ -518,10 +522,10 @@ const struct proto_ops inet6_stream_ops = { | |||
| 518 | .shutdown = inet_shutdown, /* ok */ | 522 | .shutdown = inet_shutdown, /* ok */ |
| 519 | .setsockopt = sock_common_setsockopt, /* ok */ | 523 | .setsockopt = sock_common_setsockopt, /* ok */ |
| 520 | .getsockopt = sock_common_getsockopt, /* ok */ | 524 | .getsockopt = sock_common_getsockopt, /* ok */ |
| 521 | .sendmsg = tcp_sendmsg, /* ok */ | 525 | .sendmsg = inet_sendmsg, /* ok */ |
| 522 | .recvmsg = sock_common_recvmsg, /* ok */ | 526 | .recvmsg = inet_recvmsg, /* ok */ |
| 523 | .mmap = sock_no_mmap, | 527 | .mmap = sock_no_mmap, |
| 524 | .sendpage = tcp_sendpage, | 528 | .sendpage = inet_sendpage, |
| 525 | .splice_read = tcp_splice_read, | 529 | .splice_read = tcp_splice_read, |
| 526 | #ifdef CONFIG_COMPAT | 530 | #ifdef CONFIG_COMPAT |
| 527 | .compat_setsockopt = compat_sock_common_setsockopt, | 531 | .compat_setsockopt = compat_sock_common_setsockopt, |
| @@ -545,7 +549,7 @@ const struct proto_ops inet6_dgram_ops = { | |||
| 545 | .setsockopt = sock_common_setsockopt, /* ok */ | 549 | .setsockopt = sock_common_setsockopt, /* ok */ |
| 546 | .getsockopt = sock_common_getsockopt, /* ok */ | 550 | .getsockopt = sock_common_getsockopt, /* ok */ |
| 547 | .sendmsg = inet_sendmsg, /* ok */ | 551 | .sendmsg = inet_sendmsg, /* ok */ |
| 548 | .recvmsg = sock_common_recvmsg, /* ok */ | 552 | .recvmsg = inet_recvmsg, /* ok */ |
| 549 | .mmap = sock_no_mmap, | 553 | .mmap = sock_no_mmap, |
| 550 | .sendpage = sock_no_sendpage, | 554 | .sendpage = sock_no_sendpage, |
| 551 | #ifdef CONFIG_COMPAT | 555 | #ifdef CONFIG_COMPAT |
| @@ -647,7 +651,7 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
| 647 | 651 | ||
| 648 | if (dst == NULL) { | 652 | if (dst == NULL) { |
| 649 | struct inet_sock *inet = inet_sk(sk); | 653 | struct inet_sock *inet = inet_sk(sk); |
| 650 | struct in6_addr *final_p = NULL, final; | 654 | struct in6_addr *final_p, final; |
| 651 | struct flowi fl; | 655 | struct flowi fl; |
| 652 | 656 | ||
| 653 | memset(&fl, 0, sizeof(fl)); | 657 | memset(&fl, 0, sizeof(fl)); |
| @@ -661,12 +665,7 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
| 661 | fl.fl_ip_sport = inet->inet_sport; | 665 | fl.fl_ip_sport = inet->inet_sport; |
| 662 | security_sk_classify_flow(sk, &fl); | 666 | security_sk_classify_flow(sk, &fl); |
| 663 | 667 | ||
| 664 | if (np->opt && np->opt->srcrt) { | 668 | final_p = fl6_update_dst(&fl, np->opt, &final); |
| 665 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; | ||
| 666 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
| 667 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
| 668 | final_p = &final; | ||
| 669 | } | ||
| 670 | 669 | ||
| 671 | err = ip6_dst_lookup(sk, &dst, &fl); | 670 | err = ip6_dst_lookup(sk, &dst, &fl); |
| 672 | if (err) { | 671 | if (err) { |
| @@ -971,41 +970,46 @@ static void ipv6_packet_cleanup(void) | |||
| 971 | 970 | ||
| 972 | static int __net_init ipv6_init_mibs(struct net *net) | 971 | static int __net_init ipv6_init_mibs(struct net *net) |
| 973 | { | 972 | { |
| 974 | if (snmp_mib_init((void **)net->mib.udp_stats_in6, | 973 | if (snmp_mib_init((void __percpu **)net->mib.udp_stats_in6, |
| 975 | sizeof (struct udp_mib)) < 0) | 974 | sizeof(struct udp_mib), |
| 975 | __alignof__(struct udp_mib)) < 0) | ||
| 976 | return -ENOMEM; | 976 | return -ENOMEM; |
| 977 | if (snmp_mib_init((void **)net->mib.udplite_stats_in6, | 977 | if (snmp_mib_init((void __percpu **)net->mib.udplite_stats_in6, |
| 978 | sizeof (struct udp_mib)) < 0) | 978 | sizeof(struct udp_mib), |
| 979 | __alignof__(struct udp_mib)) < 0) | ||
| 979 | goto err_udplite_mib; | 980 | goto err_udplite_mib; |
| 980 | if (snmp_mib_init((void **)net->mib.ipv6_statistics, | 981 | if (snmp_mib_init((void __percpu **)net->mib.ipv6_statistics, |
| 981 | sizeof(struct ipstats_mib)) < 0) | 982 | sizeof(struct ipstats_mib), |
| 983 | __alignof__(struct ipstats_mib)) < 0) | ||
| 982 | goto err_ip_mib; | 984 | goto err_ip_mib; |
| 983 | if (snmp_mib_init((void **)net->mib.icmpv6_statistics, | 985 | if (snmp_mib_init((void __percpu **)net->mib.icmpv6_statistics, |
| 984 | sizeof(struct icmpv6_mib)) < 0) | 986 | sizeof(struct icmpv6_mib), |
| 987 | __alignof__(struct icmpv6_mib)) < 0) | ||
| 985 | goto err_icmp_mib; | 988 | goto err_icmp_mib; |
| 986 | if (snmp_mib_init((void **)net->mib.icmpv6msg_statistics, | 989 | if (snmp_mib_init((void __percpu **)net->mib.icmpv6msg_statistics, |
| 987 | sizeof(struct icmpv6msg_mib)) < 0) | 990 | sizeof(struct icmpv6msg_mib), |
| 991 | __alignof__(struct icmpv6msg_mib)) < 0) | ||
| 988 | goto err_icmpmsg_mib; | 992 | goto err_icmpmsg_mib; |
| 989 | return 0; | 993 | return 0; |
| 990 | 994 | ||
| 991 | err_icmpmsg_mib: | 995 | err_icmpmsg_mib: |
| 992 | snmp_mib_free((void **)net->mib.icmpv6_statistics); | 996 | snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics); |
| 993 | err_icmp_mib: | 997 | err_icmp_mib: |
| 994 | snmp_mib_free((void **)net->mib.ipv6_statistics); | 998 | snmp_mib_free((void __percpu **)net->mib.ipv6_statistics); |
| 995 | err_ip_mib: | 999 | err_ip_mib: |
| 996 | snmp_mib_free((void **)net->mib.udplite_stats_in6); | 1000 | snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6); |
| 997 | err_udplite_mib: | 1001 | err_udplite_mib: |
| 998 | snmp_mib_free((void **)net->mib.udp_stats_in6); | 1002 | snmp_mib_free((void __percpu **)net->mib.udp_stats_in6); |
| 999 | return -ENOMEM; | 1003 | return -ENOMEM; |
| 1000 | } | 1004 | } |
| 1001 | 1005 | ||
| 1002 | static void __net_exit ipv6_cleanup_mibs(struct net *net) | 1006 | static void ipv6_cleanup_mibs(struct net *net) |
| 1003 | { | 1007 | { |
| 1004 | snmp_mib_free((void **)net->mib.udp_stats_in6); | 1008 | snmp_mib_free((void __percpu **)net->mib.udp_stats_in6); |
| 1005 | snmp_mib_free((void **)net->mib.udplite_stats_in6); | 1009 | snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6); |
| 1006 | snmp_mib_free((void **)net->mib.ipv6_statistics); | 1010 | snmp_mib_free((void __percpu **)net->mib.ipv6_statistics); |
| 1007 | snmp_mib_free((void **)net->mib.icmpv6_statistics); | 1011 | snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics); |
| 1008 | snmp_mib_free((void **)net->mib.icmpv6msg_statistics); | 1012 | snmp_mib_free((void __percpu **)net->mib.icmpv6msg_statistics); |
| 1009 | } | 1013 | } |
| 1010 | 1014 | ||
| 1011 | static int __net_init inet6_net_init(struct net *net) | 1015 | static int __net_init inet6_net_init(struct net *net) |
| @@ -1042,7 +1046,7 @@ out: | |||
| 1042 | #endif | 1046 | #endif |
| 1043 | } | 1047 | } |
| 1044 | 1048 | ||
| 1045 | static void inet6_net_exit(struct net *net) | 1049 | static void __net_exit inet6_net_exit(struct net *net) |
| 1046 | { | 1050 | { |
| 1047 | #ifdef CONFIG_PROC_FS | 1051 | #ifdef CONFIG_PROC_FS |
| 1048 | udp6_proc_exit(net); | 1052 | udp6_proc_exit(net); |
