aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/reassembly.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/reassembly.c')
-rw-r--r--net/ipv6/reassembly.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 798cabc7535b..6ab957ec2dd6 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: reassembly.c,v 1.26 2001/03/07 22:00:57 davem Exp $
9 *
10 * Based on: net/ipv4/ip_fragment.c 8 * Based on: net/ipv4/ip_fragment.c
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
@@ -247,6 +245,8 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
247 arg.id = id; 245 arg.id = id;
248 arg.src = src; 246 arg.src = src;
249 arg.dst = dst; 247 arg.dst = dst;
248
249 read_lock(&ip6_frags.lock);
250 hash = ip6qhashfn(id, src, dst); 250 hash = ip6qhashfn(id, src, dst);
251 251
252 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); 252 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
@@ -632,7 +632,7 @@ static struct inet6_protocol frag_protocol =
632}; 632};
633 633
634#ifdef CONFIG_SYSCTL 634#ifdef CONFIG_SYSCTL
635static struct ctl_table ip6_frags_ctl_table[] = { 635static struct ctl_table ip6_frags_ns_ctl_table[] = {
636 { 636 {
637 .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH, 637 .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH,
638 .procname = "ip6frag_high_thresh", 638 .procname = "ip6frag_high_thresh",
@@ -658,6 +658,10 @@ static struct ctl_table ip6_frags_ctl_table[] = {
658 .proc_handler = &proc_dointvec_jiffies, 658 .proc_handler = &proc_dointvec_jiffies,
659 .strategy = &sysctl_jiffies, 659 .strategy = &sysctl_jiffies,
660 }, 660 },
661 { }
662};
663
664static struct ctl_table ip6_frags_ctl_table[] = {
661 { 665 {
662 .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL, 666 .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL,
663 .procname = "ip6frag_secret_interval", 667 .procname = "ip6frag_secret_interval",
@@ -670,21 +674,20 @@ static struct ctl_table ip6_frags_ctl_table[] = {
670 { } 674 { }
671}; 675};
672 676
673static int ip6_frags_sysctl_register(struct net *net) 677static int ip6_frags_ns_sysctl_register(struct net *net)
674{ 678{
675 struct ctl_table *table; 679 struct ctl_table *table;
676 struct ctl_table_header *hdr; 680 struct ctl_table_header *hdr;
677 681
678 table = ip6_frags_ctl_table; 682 table = ip6_frags_ns_ctl_table;
679 if (net != &init_net) { 683 if (net != &init_net) {
680 table = kmemdup(table, sizeof(ip6_frags_ctl_table), GFP_KERNEL); 684 table = kmemdup(table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL);
681 if (table == NULL) 685 if (table == NULL)
682 goto err_alloc; 686 goto err_alloc;
683 687
684 table[0].data = &net->ipv6.frags.high_thresh; 688 table[0].data = &net->ipv6.frags.high_thresh;
685 table[1].data = &net->ipv6.frags.low_thresh; 689 table[1].data = &net->ipv6.frags.low_thresh;
686 table[2].data = &net->ipv6.frags.timeout; 690 table[2].data = &net->ipv6.frags.timeout;
687 table[3].mode &= ~0222;
688 } 691 }
689 692
690 hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, table); 693 hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, table);
@@ -701,7 +704,7 @@ err_alloc:
701 return -ENOMEM; 704 return -ENOMEM;
702} 705}
703 706
704static void ip6_frags_sysctl_unregister(struct net *net) 707static void ip6_frags_ns_sysctl_unregister(struct net *net)
705{ 708{
706 struct ctl_table *table; 709 struct ctl_table *table;
707 710
@@ -709,13 +712,36 @@ static void ip6_frags_sysctl_unregister(struct net *net)
709 unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr); 712 unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr);
710 kfree(table); 713 kfree(table);
711} 714}
715
716static struct ctl_table_header *ip6_ctl_header;
717
718static int ip6_frags_sysctl_register(void)
719{
720 ip6_ctl_header = register_net_sysctl_rotable(net_ipv6_ctl_path,
721 ip6_frags_ctl_table);
722 return ip6_ctl_header == NULL ? -ENOMEM : 0;
723}
724
725static void ip6_frags_sysctl_unregister(void)
726{
727 unregister_net_sysctl_table(ip6_ctl_header);
728}
712#else 729#else
713static inline int ip6_frags_sysctl_register(struct net *net) 730static inline int ip6_frags_ns_sysctl_register(struct net *net)
714{ 731{
715 return 0; 732 return 0;
716} 733}
717 734
718static inline void ip6_frags_sysctl_unregister(struct net *net) 735static inline void ip6_frags_ns_sysctl_unregister(struct net *net)
736{
737}
738
739static inline int ip6_frags_sysctl_register(void)
740{
741 return 0;
742}
743
744static inline void ip6_frags_sysctl_unregister(void)
719{ 745{
720} 746}
721#endif 747#endif
@@ -728,12 +754,12 @@ static int ipv6_frags_init_net(struct net *net)
728 754
729 inet_frags_init_net(&net->ipv6.frags); 755 inet_frags_init_net(&net->ipv6.frags);
730 756
731 return ip6_frags_sysctl_register(net); 757 return ip6_frags_ns_sysctl_register(net);
732} 758}
733 759
734static void ipv6_frags_exit_net(struct net *net) 760static void ipv6_frags_exit_net(struct net *net)
735{ 761{
736 ip6_frags_sysctl_unregister(net); 762 ip6_frags_ns_sysctl_unregister(net);
737 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags); 763 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
738} 764}
739 765
@@ -750,7 +776,13 @@ int __init ipv6_frag_init(void)
750 if (ret) 776 if (ret)
751 goto out; 777 goto out;
752 778
753 register_pernet_subsys(&ip6_frags_ops); 779 ret = ip6_frags_sysctl_register();
780 if (ret)
781 goto err_sysctl;
782
783 ret = register_pernet_subsys(&ip6_frags_ops);
784 if (ret)
785 goto err_pernet;
754 786
755 ip6_frags.hashfn = ip6_hashfn; 787 ip6_frags.hashfn = ip6_hashfn;
756 ip6_frags.constructor = ip6_frag_init; 788 ip6_frags.constructor = ip6_frag_init;
@@ -763,11 +795,18 @@ int __init ipv6_frag_init(void)
763 inet_frags_init(&ip6_frags); 795 inet_frags_init(&ip6_frags);
764out: 796out:
765 return ret; 797 return ret;
798
799err_pernet:
800 ip6_frags_sysctl_unregister();
801err_sysctl:
802 inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT);
803 goto out;
766} 804}
767 805
768void ipv6_frag_exit(void) 806void ipv6_frag_exit(void)
769{ 807{
770 inet_frags_fini(&ip6_frags); 808 inet_frags_fini(&ip6_frags);
809 ip6_frags_sysctl_unregister();
771 unregister_pernet_subsys(&ip6_frags_ops); 810 unregister_pernet_subsys(&ip6_frags_ops);
772 inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT); 811 inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT);
773} 812}