aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/ipv4.h1
-rw-r--r--include/net/netns/ipv6.h1
-rw-r--r--net/ipv4/ip_fragment.c42
-rw-r--r--net/ipv6/reassembly.c41
4 files changed, 79 insertions, 6 deletions
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 80680e09443c..15a0b052df22 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -16,6 +16,7 @@ struct sock;
16struct netns_ipv4 { 16struct netns_ipv4 {
17#ifdef CONFIG_SYSCTL 17#ifdef CONFIG_SYSCTL
18 struct ctl_table_header *forw_hdr; 18 struct ctl_table_header *forw_hdr;
19 struct ctl_table_header *frags_hdr;
19#endif 20#endif
20 struct ipv4_devconf *devconf_all; 21 struct ipv4_devconf *devconf_all;
21 struct ipv4_devconf *devconf_dflt; 22 struct ipv4_devconf *devconf_dflt;
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 057c8e473a75..87ab56ab93fc 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -12,6 +12,7 @@ struct ctl_table_header;
12struct netns_sysctl_ipv6 { 12struct netns_sysctl_ipv6 {
13#ifdef CONFIG_SYSCTL 13#ifdef CONFIG_SYSCTL
14 struct ctl_table_header *table; 14 struct ctl_table_header *table;
15 struct ctl_table_header *frags_hdr;
15#endif 16#endif
16 struct inet_frags_ctl frags; 17 struct inet_frags_ctl frags;
17 int bindv6only; 18 int bindv6only;
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 4f013343cef7..c51e1a11dc6b 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -661,17 +661,53 @@ static struct ctl_table ip4_frags_ctl_table[] = {
661 661
662static int ip4_frags_ctl_register(struct net *net) 662static int ip4_frags_ctl_register(struct net *net)
663{ 663{
664 struct ctl_table *table;
664 struct ctl_table_header *hdr; 665 struct ctl_table_header *hdr;
665 666
666 hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, 667 table = ip4_frags_ctl_table;
667 ip4_frags_ctl_table); 668 if (net != &init_net) {
668 return hdr == NULL ? -ENOMEM : 0; 669 table = kmemdup(table, sizeof(ip4_frags_ctl_table), GFP_KERNEL);
670 if (table == NULL)
671 goto err_alloc;
672
673 table[0].mode &= ~0222;
674 table[1].mode &= ~0222;
675 table[2].mode &= ~0222;
676 table[3].mode &= ~0222;
677 table[4].mode &= ~0222;
678 }
679
680 hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, table);
681 if (hdr == NULL)
682 goto err_reg;
683
684 net->ipv4.frags_hdr = hdr;
685 return 0;
686
687err_reg:
688 if (net != &init_net)
689 kfree(table);
690err_alloc:
691 return -ENOMEM;
692}
693
694static void ip4_frags_ctl_unregister(struct net *net)
695{
696 struct ctl_table *table;
697
698 table = net->ipv4.frags_hdr->ctl_table_arg;
699 unregister_net_sysctl_table(net->ipv4.frags_hdr);
700 kfree(table);
669} 701}
670#else 702#else
671static inline int ip4_frags_ctl_register(struct net *net) 703static inline int ip4_frags_ctl_register(struct net *net)
672{ 704{
673 return 0; 705 return 0;
674} 706}
707
708static inline void ip4_frags_ctl_unregister(struct net *net)
709{
710}
675#endif 711#endif
676 712
677static int ipv4_frags_init_net(struct net *net) 713static int ipv4_frags_init_net(struct net *net)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 241b2cc49bf5..0300dcbf1a75 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -670,17 +670,52 @@ static struct ctl_table ip6_frags_ctl_table[] = {
670 670
671static int ip6_frags_sysctl_register(struct net *net) 671static int ip6_frags_sysctl_register(struct net *net)
672{ 672{
673 struct ctl_table *table;
673 struct ctl_table_header *hdr; 674 struct ctl_table_header *hdr;
674 675
675 hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, 676 table = ip6_frags_ctl_table;
676 ip6_frags_ctl_table); 677 if (net != &init_net) {
677 return hdr == NULL ? -ENOMEM : 0; 678 table = kmemdup(table, sizeof(ip6_frags_ctl_table), GFP_KERNEL);
679 if (table == NULL)
680 goto err_alloc;
681
682 table[0].mode &= ~0222;
683 table[1].mode &= ~0222;
684 table[2].mode &= ~0222;
685 table[3].mode &= ~0222;
686 }
687
688 hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, table);
689 if (hdr == NULL)
690 goto err_reg;
691
692 net->ipv6.sysctl.frags_hdr = hdr;
693 return 0;
694
695err_reg:
696 if (net != &init_net)
697 kfree(table);
698err_alloc:
699 return -ENOMEM;
700}
701
702static void ip6_frags_sysctl_unregister(struct net *net)
703{
704 struct ctl_table *table;
705
706 table = net->ipv6.sysctl.frags_hdr->ctl_table_arg;
707 unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr);
708 kfree(table);
678} 709}
679#else 710#else
680static inline int ip6_frags_sysctl_register(struct net *net) 711static inline int ip6_frags_sysctl_register(struct net *net)
681{ 712{
682 return 0; 713 return 0;
683} 714}
715
716static inline void ip6_frags_sysctl_unregister(struct net *net)
717{
718}
684#endif 719#endif
685 720
686static int ipv6_frags_init_net(struct net *net) 721static int ipv6_frags_init_net(struct net *net)