aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/icmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/icmp.c')
-rw-r--r--net/ipv6/icmp.c145
1 files changed, 95 insertions, 50 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 893287ecc628..d42dd16d3487 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -64,6 +64,7 @@
64#include <net/addrconf.h> 64#include <net/addrconf.h>
65#include <net/icmp.h> 65#include <net/icmp.h>
66#include <net/xfrm.h> 66#include <net/xfrm.h>
67#include <net/inet_common.h>
67 68
68#include <asm/uaccess.h> 69#include <asm/uaccess.h>
69#include <asm/system.h> 70#include <asm/system.h>
@@ -80,8 +81,10 @@ EXPORT_SYMBOL(icmpv6msg_statistics);
80 * 81 *
81 * On SMP we have one ICMP socket per-cpu. 82 * On SMP we have one ICMP socket per-cpu.
82 */ 83 */
83static DEFINE_PER_CPU(struct socket *, __icmpv6_socket) = NULL; 84static inline struct sock *icmpv6_sk(struct net *net)
84#define icmpv6_socket __get_cpu_var(__icmpv6_socket) 85{
86 return net->ipv6.icmp_sk[smp_processor_id()];
87}
85 88
86static int icmpv6_rcv(struct sk_buff *skb); 89static int icmpv6_rcv(struct sk_buff *skb);
87 90
@@ -90,11 +93,11 @@ static struct inet6_protocol icmpv6_protocol = {
90 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 93 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
91}; 94};
92 95
93static __inline__ int icmpv6_xmit_lock(void) 96static __inline__ int icmpv6_xmit_lock(struct sock *sk)
94{ 97{
95 local_bh_disable(); 98 local_bh_disable();
96 99
97 if (unlikely(!spin_trylock(&icmpv6_socket->sk->sk_lock.slock))) { 100 if (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
98 /* This can happen if the output path (f.e. SIT or 101 /* This can happen if the output path (f.e. SIT or
99 * ip6ip6 tunnel) signals dst_link_failure() for an 102 * ip6ip6 tunnel) signals dst_link_failure() for an
100 * outgoing ICMP6 packet. 103 * outgoing ICMP6 packet.
@@ -105,9 +108,9 @@ static __inline__ int icmpv6_xmit_lock(void)
105 return 0; 108 return 0;
106} 109}
107 110
108static __inline__ void icmpv6_xmit_unlock(void) 111static __inline__ void icmpv6_xmit_unlock(struct sock *sk)
109{ 112{
110 spin_unlock_bh(&icmpv6_socket->sk->sk_lock.slock); 113 spin_unlock_bh(&sk->sk_lock.slock);
111} 114}
112 115
113/* 116/*
@@ -161,6 +164,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
161 struct flowi *fl) 164 struct flowi *fl)
162{ 165{
163 struct dst_entry *dst; 166 struct dst_entry *dst;
167 struct net *net = sock_net(sk);
164 int res = 0; 168 int res = 0;
165 169
166 /* Informational messages are not limited. */ 170 /* Informational messages are not limited. */
@@ -176,7 +180,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
176 * XXX: perhaps the expire for routing entries cloned by 180 * XXX: perhaps the expire for routing entries cloned by
177 * this lookup should be more aggressive (not longer than timeout). 181 * this lookup should be more aggressive (not longer than timeout).
178 */ 182 */
179 dst = ip6_route_output(sk, fl); 183 dst = ip6_route_output(net, sk, fl);
180 if (dst->error) { 184 if (dst->error) {
181 IP6_INC_STATS(ip6_dst_idev(dst), 185 IP6_INC_STATS(ip6_dst_idev(dst),
182 IPSTATS_MIB_OUTNOROUTES); 186 IPSTATS_MIB_OUTNOROUTES);
@@ -184,7 +188,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
184 res = 1; 188 res = 1;
185 } else { 189 } else {
186 struct rt6_info *rt = (struct rt6_info *)dst; 190 struct rt6_info *rt = (struct rt6_info *)dst;
187 int tmo = init_net.ipv6.sysctl.icmpv6_time; 191 int tmo = net->ipv6.sysctl.icmpv6_time;
188 192
189 /* Give more bandwidth to wider prefixes. */ 193 /* Give more bandwidth to wider prefixes. */
190 if (rt->rt6i_dst.plen < 128) 194 if (rt->rt6i_dst.plen < 128)
@@ -303,6 +307,7 @@ static inline void mip6_addr_swap(struct sk_buff *skb) {}
303void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, 307void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
304 struct net_device *dev) 308 struct net_device *dev)
305{ 309{
310 struct net *net = dev_net(skb->dev);
306 struct inet6_dev *idev = NULL; 311 struct inet6_dev *idev = NULL;
307 struct ipv6hdr *hdr = ipv6_hdr(skb); 312 struct ipv6hdr *hdr = ipv6_hdr(skb);
308 struct sock *sk; 313 struct sock *sk;
@@ -332,7 +337,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
332 */ 337 */
333 addr_type = ipv6_addr_type(&hdr->daddr); 338 addr_type = ipv6_addr_type(&hdr->daddr);
334 339
335 if (ipv6_chk_addr(&init_net, &hdr->daddr, skb->dev, 0)) 340 if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0))
336 saddr = &hdr->daddr; 341 saddr = &hdr->daddr;
337 342
338 /* 343 /*
@@ -389,12 +394,12 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
389 fl.fl_icmp_code = code; 394 fl.fl_icmp_code = code;
390 security_skb_classify_flow(skb, &fl); 395 security_skb_classify_flow(skb, &fl);
391 396
392 if (icmpv6_xmit_lock()) 397 sk = icmpv6_sk(net);
393 return;
394
395 sk = icmpv6_socket->sk;
396 np = inet6_sk(sk); 398 np = inet6_sk(sk);
397 399
400 if (icmpv6_xmit_lock(sk))
401 return;
402
398 if (!icmpv6_xrlim_allow(sk, type, &fl)) 403 if (!icmpv6_xrlim_allow(sk, type, &fl))
399 goto out; 404 goto out;
400 405
@@ -462,9 +467,7 @@ route_done:
462 else 467 else
463 hlimit = np->hop_limit; 468 hlimit = np->hop_limit;
464 if (hlimit < 0) 469 if (hlimit < 0)
465 hlimit = dst_metric(dst, RTAX_HOPLIMIT); 470 hlimit = ip6_dst_hoplimit(dst);
466 if (hlimit < 0)
467 hlimit = ipv6_get_hoplimit(dst->dev);
468 471
469 tclass = np->tclass; 472 tclass = np->tclass;
470 if (tclass < 0) 473 if (tclass < 0)
@@ -500,13 +503,14 @@ out_put:
500out_dst_release: 503out_dst_release:
501 dst_release(dst); 504 dst_release(dst);
502out: 505out:
503 icmpv6_xmit_unlock(); 506 icmpv6_xmit_unlock(sk);
504} 507}
505 508
506EXPORT_SYMBOL(icmpv6_send); 509EXPORT_SYMBOL(icmpv6_send);
507 510
508static void icmpv6_echo_reply(struct sk_buff *skb) 511static void icmpv6_echo_reply(struct sk_buff *skb)
509{ 512{
513 struct net *net = dev_net(skb->dev);
510 struct sock *sk; 514 struct sock *sk;
511 struct inet6_dev *idev; 515 struct inet6_dev *idev;
512 struct ipv6_pinfo *np; 516 struct ipv6_pinfo *np;
@@ -537,12 +541,12 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
537 fl.fl_icmp_type = ICMPV6_ECHO_REPLY; 541 fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
538 security_skb_classify_flow(skb, &fl); 542 security_skb_classify_flow(skb, &fl);
539 543
540 if (icmpv6_xmit_lock()) 544 sk = icmpv6_sk(net);
541 return;
542
543 sk = icmpv6_socket->sk;
544 np = inet6_sk(sk); 545 np = inet6_sk(sk);
545 546
547 if (icmpv6_xmit_lock(sk))
548 return;
549
546 if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) 550 if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
547 fl.oif = np->mcast_oif; 551 fl.oif = np->mcast_oif;
548 552
@@ -557,9 +561,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
557 else 561 else
558 hlimit = np->hop_limit; 562 hlimit = np->hop_limit;
559 if (hlimit < 0) 563 if (hlimit < 0)
560 hlimit = dst_metric(dst, RTAX_HOPLIMIT); 564 hlimit = ip6_dst_hoplimit(dst);
561 if (hlimit < 0)
562 hlimit = ipv6_get_hoplimit(dst->dev);
563 565
564 tclass = np->tclass; 566 tclass = np->tclass;
565 if (tclass < 0) 567 if (tclass < 0)
@@ -586,7 +588,7 @@ out_put:
586 in6_dev_put(idev); 588 in6_dev_put(idev);
587 dst_release(dst); 589 dst_release(dst);
588out: 590out:
589 icmpv6_xmit_unlock(); 591 icmpv6_xmit_unlock(sk);
590} 592}
591 593
592static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info) 594static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
@@ -777,19 +779,40 @@ drop_no_count:
777 return 0; 779 return 0;
778} 780}
779 781
782void icmpv6_flow_init(struct sock *sk, struct flowi *fl,
783 u8 type,
784 const struct in6_addr *saddr,
785 const struct in6_addr *daddr,
786 int oif)
787{
788 memset(fl, 0, sizeof(*fl));
789 ipv6_addr_copy(&fl->fl6_src, saddr);
790 ipv6_addr_copy(&fl->fl6_dst, daddr);
791 fl->proto = IPPROTO_ICMPV6;
792 fl->fl_icmp_type = type;
793 fl->fl_icmp_code = 0;
794 fl->oif = oif;
795 security_sk_classify_flow(sk, fl);
796}
797
780/* 798/*
781 * Special lock-class for __icmpv6_socket: 799 * Special lock-class for __icmpv6_sk:
782 */ 800 */
783static struct lock_class_key icmpv6_socket_sk_dst_lock_key; 801static struct lock_class_key icmpv6_socket_sk_dst_lock_key;
784 802
785int __init icmpv6_init(struct net_proto_family *ops) 803static int __net_init icmpv6_sk_init(struct net *net)
786{ 804{
787 struct sock *sk; 805 struct sock *sk;
788 int err, i, j; 806 int err, i, j;
789 807
808 net->ipv6.icmp_sk =
809 kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL);
810 if (net->ipv6.icmp_sk == NULL)
811 return -ENOMEM;
812
790 for_each_possible_cpu(i) { 813 for_each_possible_cpu(i) {
791 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, 814 err = inet_ctl_sock_create(&sk, PF_INET6,
792 &per_cpu(__icmpv6_socket, i)); 815 SOCK_RAW, IPPROTO_ICMPV6, net);
793 if (err < 0) { 816 if (err < 0) {
794 printk(KERN_ERR 817 printk(KERN_ERR
795 "Failed to initialize the ICMP6 control socket " 818 "Failed to initialize the ICMP6 control socket "
@@ -798,12 +821,12 @@ int __init icmpv6_init(struct net_proto_family *ops)
798 goto fail; 821 goto fail;
799 } 822 }
800 823
801 sk = per_cpu(__icmpv6_socket, i)->sk; 824 net->ipv6.icmp_sk[i] = sk;
802 sk->sk_allocation = GFP_ATOMIC; 825
803 /* 826 /*
804 * Split off their lock-class, because sk->sk_dst_lock 827 * Split off their lock-class, because sk->sk_dst_lock
805 * gets used from softirqs, which is safe for 828 * gets used from softirqs, which is safe for
806 * __icmpv6_socket (because those never get directly used 829 * __icmpv6_sk (because those never get directly used
807 * via userspace syscalls), but unsafe for normal sockets. 830 * via userspace syscalls), but unsafe for normal sockets.
808 */ 831 */
809 lockdep_set_class(&sk->sk_dst_lock, 832 lockdep_set_class(&sk->sk_dst_lock,
@@ -814,39 +837,57 @@ int __init icmpv6_init(struct net_proto_family *ops)
814 */ 837 */
815 sk->sk_sndbuf = 838 sk->sk_sndbuf =
816 (2 * ((64 * 1024) + sizeof(struct sk_buff))); 839 (2 * ((64 * 1024) + sizeof(struct sk_buff)));
817
818 sk->sk_prot->unhash(sk);
819 } 840 }
820
821
822 if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0) {
823 printk(KERN_ERR "Failed to register ICMP6 protocol\n");
824 err = -EAGAIN;
825 goto fail;
826 }
827
828 return 0; 841 return 0;
829 842
830 fail: 843 fail:
831 for (j = 0; j < i; j++) { 844 for (j = 0; j < i; j++)
832 if (!cpu_possible(j)) 845 inet_ctl_sock_destroy(net->ipv6.icmp_sk[j]);
833 continue; 846 kfree(net->ipv6.icmp_sk);
834 sock_release(per_cpu(__icmpv6_socket, j));
835 }
836
837 return err; 847 return err;
838} 848}
839 849
840void icmpv6_cleanup(void) 850static void __net_exit icmpv6_sk_exit(struct net *net)
841{ 851{
842 int i; 852 int i;
843 853
844 for_each_possible_cpu(i) { 854 for_each_possible_cpu(i) {
845 sock_release(per_cpu(__icmpv6_socket, i)); 855 inet_ctl_sock_destroy(net->ipv6.icmp_sk[i]);
846 } 856 }
857 kfree(net->ipv6.icmp_sk);
858}
859
860static struct pernet_operations icmpv6_sk_ops = {
861 .init = icmpv6_sk_init,
862 .exit = icmpv6_sk_exit,
863};
864
865int __init icmpv6_init(void)
866{
867 int err;
868
869 err = register_pernet_subsys(&icmpv6_sk_ops);
870 if (err < 0)
871 return err;
872
873 err = -EAGAIN;
874 if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0)
875 goto fail;
876 return 0;
877
878fail:
879 printk(KERN_ERR "Failed to register ICMP6 protocol\n");
880 unregister_pernet_subsys(&icmpv6_sk_ops);
881 return err;
882}
883
884void icmpv6_cleanup(void)
885{
886 unregister_pernet_subsys(&icmpv6_sk_ops);
847 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); 887 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
848} 888}
849 889
890
850static const struct icmp6_err { 891static const struct icmp6_err {
851 int err; 892 int err;
852 int fatal; 893 int fatal;
@@ -927,6 +968,10 @@ struct ctl_table *ipv6_icmp_sysctl_init(struct net *net)
927 table = kmemdup(ipv6_icmp_table_template, 968 table = kmemdup(ipv6_icmp_table_template,
928 sizeof(ipv6_icmp_table_template), 969 sizeof(ipv6_icmp_table_template),
929 GFP_KERNEL); 970 GFP_KERNEL);
971
972 if (table)
973 table[0].data = &net->ipv6.sysctl.icmpv6_time;
974
930 return table; 975 return table;
931} 976}
932#endif 977#endif