diff options
-rw-r--r-- | include/net/netns/ipv4.h | 1 | ||||
-rw-r--r-- | include/net/netns/ipv6.h | 1 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 42 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 41 |
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; | |||
16 | struct netns_ipv4 { | 16 | struct 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; | |||
12 | struct netns_sysctl_ipv6 { | 12 | struct 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 | ||
662 | static int ip4_frags_ctl_register(struct net *net) | 662 | static 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 | |||
687 | err_reg: | ||
688 | if (net != &init_net) | ||
689 | kfree(table); | ||
690 | err_alloc: | ||
691 | return -ENOMEM; | ||
692 | } | ||
693 | |||
694 | static 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 |
671 | static inline int ip4_frags_ctl_register(struct net *net) | 703 | static inline int ip4_frags_ctl_register(struct net *net) |
672 | { | 704 | { |
673 | return 0; | 705 | return 0; |
674 | } | 706 | } |
707 | |||
708 | static inline void ip4_frags_ctl_unregister(struct net *net) | ||
709 | { | ||
710 | } | ||
675 | #endif | 711 | #endif |
676 | 712 | ||
677 | static int ipv4_frags_init_net(struct net *net) | 713 | static 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 | ||
671 | static int ip6_frags_sysctl_register(struct net *net) | 671 | static 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 | |||
695 | err_reg: | ||
696 | if (net != &init_net) | ||
697 | kfree(table); | ||
698 | err_alloc: | ||
699 | return -ENOMEM; | ||
700 | } | ||
701 | |||
702 | static 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 |
680 | static inline int ip6_frags_sysctl_register(struct net *net) | 711 | static inline int ip6_frags_sysctl_register(struct net *net) |
681 | { | 712 | { |
682 | return 0; | 713 | return 0; |
683 | } | 714 | } |
715 | |||
716 | static inline void ip6_frags_sysctl_unregister(struct net *net) | ||
717 | { | ||
718 | } | ||
684 | #endif | 719 | #endif |
685 | 720 | ||
686 | static int ipv6_frags_init_net(struct net *net) | 721 | static int ipv6_frags_init_net(struct net *net) |