aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/af_inet6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/af_inet6.c')
-rw-r--r--net/ipv6/af_inet6.c70
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
972static int __net_init ipv6_init_mibs(struct net *net) 971static 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
991err_icmpmsg_mib: 995err_icmpmsg_mib:
992 snmp_mib_free((void **)net->mib.icmpv6_statistics); 996 snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics);
993err_icmp_mib: 997err_icmp_mib:
994 snmp_mib_free((void **)net->mib.ipv6_statistics); 998 snmp_mib_free((void __percpu **)net->mib.ipv6_statistics);
995err_ip_mib: 999err_ip_mib:
996 snmp_mib_free((void **)net->mib.udplite_stats_in6); 1000 snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6);
997err_udplite_mib: 1001err_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
1002static void __net_exit ipv6_cleanup_mibs(struct net *net) 1006static 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
1011static int __net_init inet6_net_init(struct net *net) 1015static int __net_init inet6_net_init(struct net *net)
@@ -1042,7 +1046,7 @@ out:
1042#endif 1046#endif
1043} 1047}
1044 1048
1045static void inet6_net_exit(struct net *net) 1049static 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);