diff options
| -rw-r--r-- | include/net/netns/ipv4.h | 5 | ||||
| -rw-r--r-- | net/ipv4/netfilter/iptable_filter.c | 41 | ||||
| -rw-r--r-- | net/ipv4/netfilter/iptable_mangle.c | 41 | ||||
| -rw-r--r-- | net/ipv4/netfilter/iptable_raw.c | 41 |
4 files changed, 92 insertions, 36 deletions
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 15a0b052df22..aeb0c3b8df11 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h | |||
| @@ -27,5 +27,10 @@ struct netns_ipv4 { | |||
| 27 | struct sock *fibnl; | 27 | struct sock *fibnl; |
| 28 | 28 | ||
| 29 | struct netns_frags frags; | 29 | struct netns_frags frags; |
| 30 | #ifdef CONFIG_NETFILTER | ||
| 31 | struct xt_table *iptable_filter; | ||
| 32 | struct xt_table *iptable_mangle; | ||
| 33 | struct xt_table *iptable_raw; | ||
| 34 | #endif | ||
| 30 | }; | 35 | }; |
| 31 | #endif | 36 | #endif |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 3b43ca07a26c..69f3d7e6e96f 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
| @@ -28,7 +28,7 @@ static struct | |||
| 28 | struct ipt_replace repl; | 28 | struct ipt_replace repl; |
| 29 | struct ipt_standard entries[3]; | 29 | struct ipt_standard entries[3]; |
| 30 | struct ipt_error term; | 30 | struct ipt_error term; |
| 31 | } initial_table __initdata = { | 31 | } initial_table __net_initdata = { |
| 32 | .repl = { | 32 | .repl = { |
| 33 | .name = "filter", | 33 | .name = "filter", |
| 34 | .valid_hooks = FILTER_VALID_HOOKS, | 34 | .valid_hooks = FILTER_VALID_HOOKS, |
| @@ -53,14 +53,13 @@ static struct | |||
| 53 | .term = IPT_ERROR_INIT, /* ERROR */ | 53 | .term = IPT_ERROR_INIT, /* ERROR */ |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | static struct xt_table __packet_filter = { | 56 | static struct xt_table packet_filter = { |
| 57 | .name = "filter", | 57 | .name = "filter", |
| 58 | .valid_hooks = FILTER_VALID_HOOKS, | 58 | .valid_hooks = FILTER_VALID_HOOKS, |
| 59 | .lock = RW_LOCK_UNLOCKED, | 59 | .lock = RW_LOCK_UNLOCKED, |
| 60 | .me = THIS_MODULE, | 60 | .me = THIS_MODULE, |
| 61 | .af = AF_INET, | 61 | .af = AF_INET, |
| 62 | }; | 62 | }; |
| 63 | static struct xt_table *packet_filter; | ||
| 64 | 63 | ||
| 65 | /* The work comes in here from netfilter.c. */ | 64 | /* The work comes in here from netfilter.c. */ |
| 66 | static unsigned int | 65 | static unsigned int |
| @@ -70,7 +69,7 @@ ipt_hook(unsigned int hook, | |||
| 70 | const struct net_device *out, | 69 | const struct net_device *out, |
| 71 | int (*okfn)(struct sk_buff *)) | 70 | int (*okfn)(struct sk_buff *)) |
| 72 | { | 71 | { |
| 73 | return ipt_do_table(skb, hook, in, out, packet_filter); | 72 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter); |
| 74 | } | 73 | } |
| 75 | 74 | ||
| 76 | static unsigned int | 75 | static unsigned int |
| @@ -89,7 +88,7 @@ ipt_local_out_hook(unsigned int hook, | |||
| 89 | return NF_ACCEPT; | 88 | return NF_ACCEPT; |
| 90 | } | 89 | } |
| 91 | 90 | ||
| 92 | return ipt_do_table(skb, hook, in, out, packet_filter); | 91 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter); |
| 93 | } | 92 | } |
| 94 | 93 | ||
| 95 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 94 | static struct nf_hook_ops ipt_ops[] __read_mostly = { |
| @@ -120,6 +119,26 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = { | |||
| 120 | static int forward = NF_ACCEPT; | 119 | static int forward = NF_ACCEPT; |
| 121 | module_param(forward, bool, 0000); | 120 | module_param(forward, bool, 0000); |
| 122 | 121 | ||
| 122 | static int __net_init iptable_filter_net_init(struct net *net) | ||
| 123 | { | ||
| 124 | /* Register table */ | ||
| 125 | net->ipv4.iptable_filter = | ||
| 126 | ipt_register_table(net, &packet_filter, &initial_table.repl); | ||
| 127 | if (IS_ERR(net->ipv4.iptable_filter)) | ||
| 128 | return PTR_ERR(net->ipv4.iptable_filter); | ||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | static void __net_exit iptable_filter_net_exit(struct net *net) | ||
| 133 | { | ||
| 134 | ipt_unregister_table(net->ipv4.iptable_filter); | ||
| 135 | } | ||
| 136 | |||
| 137 | static struct pernet_operations iptable_filter_net_ops = { | ||
| 138 | .init = iptable_filter_net_init, | ||
| 139 | .exit = iptable_filter_net_exit, | ||
| 140 | }; | ||
| 141 | |||
| 123 | static int __init iptable_filter_init(void) | 142 | static int __init iptable_filter_init(void) |
| 124 | { | 143 | { |
| 125 | int ret; | 144 | int ret; |
| @@ -132,11 +151,9 @@ static int __init iptable_filter_init(void) | |||
| 132 | /* Entry 1 is the FORWARD hook */ | 151 | /* Entry 1 is the FORWARD hook */ |
| 133 | initial_table.entries[1].target.verdict = -forward - 1; | 152 | initial_table.entries[1].target.verdict = -forward - 1; |
| 134 | 153 | ||
| 135 | /* Register table */ | 154 | ret = register_pernet_subsys(&iptable_filter_net_ops); |
| 136 | packet_filter = ipt_register_table(&init_net, &__packet_filter, | 155 | if (ret < 0) |
| 137 | &initial_table.repl); | 156 | return ret; |
| 138 | if (IS_ERR(packet_filter)) | ||
| 139 | return PTR_ERR(packet_filter); | ||
| 140 | 157 | ||
| 141 | /* Register hooks */ | 158 | /* Register hooks */ |
| 142 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | 159 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
| @@ -146,14 +163,14 @@ static int __init iptable_filter_init(void) | |||
| 146 | return ret; | 163 | return ret; |
| 147 | 164 | ||
| 148 | cleanup_table: | 165 | cleanup_table: |
| 149 | ipt_unregister_table(packet_filter); | 166 | unregister_pernet_subsys(&iptable_filter_net_ops); |
| 150 | return ret; | 167 | return ret; |
| 151 | } | 168 | } |
| 152 | 169 | ||
| 153 | static void __exit iptable_filter_fini(void) | 170 | static void __exit iptable_filter_fini(void) |
| 154 | { | 171 | { |
| 155 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | 172 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
| 156 | ipt_unregister_table(packet_filter); | 173 | unregister_pernet_subsys(&iptable_filter_net_ops); |
| 157 | } | 174 | } |
| 158 | 175 | ||
| 159 | module_init(iptable_filter_init); | 176 | module_init(iptable_filter_init); |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 292f2ed4416f..c55a210853a7 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
| @@ -33,7 +33,7 @@ static struct | |||
| 33 | struct ipt_replace repl; | 33 | struct ipt_replace repl; |
| 34 | struct ipt_standard entries[5]; | 34 | struct ipt_standard entries[5]; |
| 35 | struct ipt_error term; | 35 | struct ipt_error term; |
| 36 | } initial_table __initdata = { | 36 | } initial_table __net_initdata = { |
| 37 | .repl = { | 37 | .repl = { |
| 38 | .name = "mangle", | 38 | .name = "mangle", |
| 39 | .valid_hooks = MANGLE_VALID_HOOKS, | 39 | .valid_hooks = MANGLE_VALID_HOOKS, |
| @@ -64,14 +64,13 @@ static struct | |||
| 64 | .term = IPT_ERROR_INIT, /* ERROR */ | 64 | .term = IPT_ERROR_INIT, /* ERROR */ |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | static struct xt_table __packet_mangler = { | 67 | static struct xt_table packet_mangler = { |
| 68 | .name = "mangle", | 68 | .name = "mangle", |
| 69 | .valid_hooks = MANGLE_VALID_HOOKS, | 69 | .valid_hooks = MANGLE_VALID_HOOKS, |
| 70 | .lock = RW_LOCK_UNLOCKED, | 70 | .lock = RW_LOCK_UNLOCKED, |
| 71 | .me = THIS_MODULE, | 71 | .me = THIS_MODULE, |
| 72 | .af = AF_INET, | 72 | .af = AF_INET, |
| 73 | }; | 73 | }; |
| 74 | static struct xt_table *packet_mangler; | ||
| 75 | 74 | ||
| 76 | /* The work comes in here from netfilter.c. */ | 75 | /* The work comes in here from netfilter.c. */ |
| 77 | static unsigned int | 76 | static unsigned int |
| @@ -81,7 +80,7 @@ ipt_route_hook(unsigned int hook, | |||
| 81 | const struct net_device *out, | 80 | const struct net_device *out, |
| 82 | int (*okfn)(struct sk_buff *)) | 81 | int (*okfn)(struct sk_buff *)) |
| 83 | { | 82 | { |
| 84 | return ipt_do_table(skb, hook, in, out, packet_mangler); | 83 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle); |
| 85 | } | 84 | } |
| 86 | 85 | ||
| 87 | static unsigned int | 86 | static unsigned int |
| @@ -113,7 +112,7 @@ ipt_local_hook(unsigned int hook, | |||
| 113 | daddr = iph->daddr; | 112 | daddr = iph->daddr; |
| 114 | tos = iph->tos; | 113 | tos = iph->tos; |
| 115 | 114 | ||
| 116 | ret = ipt_do_table(skb, hook, in, out, packet_mangler); | 115 | ret = ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle); |
| 117 | /* Reroute for ANY change. */ | 116 | /* Reroute for ANY change. */ |
| 118 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { | 117 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { |
| 119 | iph = ip_hdr(skb); | 118 | iph = ip_hdr(skb); |
| @@ -167,15 +166,33 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = { | |||
| 167 | }, | 166 | }, |
| 168 | }; | 167 | }; |
| 169 | 168 | ||
| 169 | static int __net_init iptable_mangle_net_init(struct net *net) | ||
| 170 | { | ||
| 171 | /* Register table */ | ||
| 172 | net->ipv4.iptable_mangle = | ||
| 173 | ipt_register_table(net, &packet_mangler, &initial_table.repl); | ||
| 174 | if (IS_ERR(net->ipv4.iptable_mangle)) | ||
| 175 | return PTR_ERR(net->ipv4.iptable_mangle); | ||
| 176 | return 0; | ||
| 177 | } | ||
| 178 | |||
| 179 | static void __net_exit iptable_mangle_net_exit(struct net *net) | ||
| 180 | { | ||
| 181 | ipt_unregister_table(net->ipv4.iptable_mangle); | ||
| 182 | } | ||
| 183 | |||
| 184 | static struct pernet_operations iptable_mangle_net_ops = { | ||
| 185 | .init = iptable_mangle_net_init, | ||
| 186 | .exit = iptable_mangle_net_exit, | ||
| 187 | }; | ||
| 188 | |||
| 170 | static int __init iptable_mangle_init(void) | 189 | static int __init iptable_mangle_init(void) |
| 171 | { | 190 | { |
| 172 | int ret; | 191 | int ret; |
| 173 | 192 | ||
| 174 | /* Register table */ | 193 | ret = register_pernet_subsys(&iptable_mangle_net_ops); |
| 175 | packet_mangler = ipt_register_table(&init_net, &__packet_mangler, | 194 | if (ret < 0) |
| 176 | &initial_table.repl); | 195 | return ret; |
| 177 | if (IS_ERR(packet_mangler)) | ||
| 178 | return PTR_ERR(packet_mangler); | ||
| 179 | 196 | ||
| 180 | /* Register hooks */ | 197 | /* Register hooks */ |
| 181 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | 198 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
| @@ -185,14 +202,14 @@ static int __init iptable_mangle_init(void) | |||
| 185 | return ret; | 202 | return ret; |
| 186 | 203 | ||
| 187 | cleanup_table: | 204 | cleanup_table: |
| 188 | ipt_unregister_table(packet_mangler); | 205 | unregister_pernet_subsys(&iptable_mangle_net_ops); |
| 189 | return ret; | 206 | return ret; |
| 190 | } | 207 | } |
| 191 | 208 | ||
| 192 | static void __exit iptable_mangle_fini(void) | 209 | static void __exit iptable_mangle_fini(void) |
| 193 | { | 210 | { |
| 194 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | 211 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
| 195 | ipt_unregister_table(packet_mangler); | 212 | unregister_pernet_subsys(&iptable_mangle_net_ops); |
| 196 | } | 213 | } |
| 197 | 214 | ||
| 198 | module_init(iptable_mangle_init); | 215 | module_init(iptable_mangle_init); |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index dab863dd0558..e41fe8ca4e1c 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
| @@ -14,7 +14,7 @@ static struct | |||
| 14 | struct ipt_replace repl; | 14 | struct ipt_replace repl; |
| 15 | struct ipt_standard entries[2]; | 15 | struct ipt_standard entries[2]; |
| 16 | struct ipt_error term; | 16 | struct ipt_error term; |
| 17 | } initial_table __initdata = { | 17 | } initial_table __net_initdata = { |
| 18 | .repl = { | 18 | .repl = { |
| 19 | .name = "raw", | 19 | .name = "raw", |
| 20 | .valid_hooks = RAW_VALID_HOOKS, | 20 | .valid_hooks = RAW_VALID_HOOKS, |
| @@ -36,14 +36,13 @@ static struct | |||
| 36 | .term = IPT_ERROR_INIT, /* ERROR */ | 36 | .term = IPT_ERROR_INIT, /* ERROR */ |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | static struct xt_table __packet_raw = { | 39 | static struct xt_table packet_raw = { |
| 40 | .name = "raw", | 40 | .name = "raw", |
| 41 | .valid_hooks = RAW_VALID_HOOKS, | 41 | .valid_hooks = RAW_VALID_HOOKS, |
| 42 | .lock = RW_LOCK_UNLOCKED, | 42 | .lock = RW_LOCK_UNLOCKED, |
| 43 | .me = THIS_MODULE, | 43 | .me = THIS_MODULE, |
| 44 | .af = AF_INET, | 44 | .af = AF_INET, |
| 45 | }; | 45 | }; |
| 46 | static struct xt_table *packet_raw; | ||
| 47 | 46 | ||
| 48 | /* The work comes in here from netfilter.c. */ | 47 | /* The work comes in here from netfilter.c. */ |
| 49 | static unsigned int | 48 | static unsigned int |
| @@ -53,7 +52,7 @@ ipt_hook(unsigned int hook, | |||
| 53 | const struct net_device *out, | 52 | const struct net_device *out, |
| 54 | int (*okfn)(struct sk_buff *)) | 53 | int (*okfn)(struct sk_buff *)) |
| 55 | { | 54 | { |
| 56 | return ipt_do_table(skb, hook, in, out, packet_raw); | 55 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw); |
| 57 | } | 56 | } |
| 58 | 57 | ||
| 59 | static unsigned int | 58 | static unsigned int |
| @@ -71,7 +70,7 @@ ipt_local_hook(unsigned int hook, | |||
| 71 | "packet.\n"); | 70 | "packet.\n"); |
| 72 | return NF_ACCEPT; | 71 | return NF_ACCEPT; |
| 73 | } | 72 | } |
| 74 | return ipt_do_table(skb, hook, in, out, packet_raw); | 73 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw); |
| 75 | } | 74 | } |
| 76 | 75 | ||
| 77 | /* 'raw' is the very first table. */ | 76 | /* 'raw' is the very first table. */ |
| @@ -92,15 +91,33 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = { | |||
| 92 | }, | 91 | }, |
| 93 | }; | 92 | }; |
| 94 | 93 | ||
| 94 | static int __net_init iptable_raw_net_init(struct net *net) | ||
| 95 | { | ||
| 96 | /* Register table */ | ||
| 97 | net->ipv4.iptable_raw = | ||
| 98 | ipt_register_table(net, &packet_raw, &initial_table.repl); | ||
| 99 | if (IS_ERR(net->ipv4.iptable_raw)) | ||
| 100 | return PTR_ERR(net->ipv4.iptable_raw); | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | static void __net_exit iptable_raw_net_exit(struct net *net) | ||
| 105 | { | ||
| 106 | ipt_unregister_table(net->ipv4.iptable_raw); | ||
| 107 | } | ||
| 108 | |||
| 109 | static struct pernet_operations iptable_raw_net_ops = { | ||
| 110 | .init = iptable_raw_net_init, | ||
| 111 | .exit = iptable_raw_net_exit, | ||
| 112 | }; | ||
| 113 | |||
| 95 | static int __init iptable_raw_init(void) | 114 | static int __init iptable_raw_init(void) |
| 96 | { | 115 | { |
| 97 | int ret; | 116 | int ret; |
| 98 | 117 | ||
| 99 | /* Register table */ | 118 | ret = register_pernet_subsys(&iptable_raw_net_ops); |
| 100 | packet_raw = ipt_register_table(&init_net, &__packet_raw, | 119 | if (ret < 0) |
| 101 | &initial_table.repl); | 120 | return ret; |
| 102 | if (IS_ERR(packet_raw)) | ||
| 103 | return PTR_ERR(packet_raw); | ||
| 104 | 121 | ||
| 105 | /* Register hooks */ | 122 | /* Register hooks */ |
| 106 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | 123 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
| @@ -110,14 +127,14 @@ static int __init iptable_raw_init(void) | |||
| 110 | return ret; | 127 | return ret; |
| 111 | 128 | ||
| 112 | cleanup_table: | 129 | cleanup_table: |
| 113 | ipt_unregister_table(packet_raw); | 130 | unregister_pernet_subsys(&iptable_raw_net_ops); |
| 114 | return ret; | 131 | return ret; |
| 115 | } | 132 | } |
| 116 | 133 | ||
| 117 | static void __exit iptable_raw_fini(void) | 134 | static void __exit iptable_raw_fini(void) |
| 118 | { | 135 | { |
| 119 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | 136 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
| 120 | ipt_unregister_table(packet_raw); | 137 | unregister_pernet_subsys(&iptable_raw_net_ops); |
| 121 | } | 138 | } |
| 122 | 139 | ||
| 123 | module_init(iptable_raw_init); | 140 | module_init(iptable_raw_init); |
