aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@sw.ru>2008-01-31 07:02:44 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:27:36 -0500
commit44d34e721e2c81ccdfb13cf34996309247ae2981 (patch)
treefec2063c8573700fd01cb6c11875769751744603 /net/ipv6
parent8d870052079d255917ec4f8431f5ec102707b7af (diff)
[NETFILTER]: x_tables: return new table from {arp,ip,ip6}t_register_table()
Typical table module registers xt_table structure (i.e. packet_filter) and link it to list during it. We can't use one template for it because corresponding list_head will become corrupted. We also can't unregister with template because it wasn't changed at all and thus doesn't know in which list it is. So, we duplicate template at the very first step of table registration. Table modules will save it for use during unregistration time and actual filtering. Do it at once to not screw bisection. P.S.: renaming i.e. packet_filter => __packet_filter is temporary until full netnsization of table modules is done. Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/ip6_tables.c24
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c17
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c17
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c15
4 files changed, 40 insertions, 33 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 1aac3ef39414..b89f133f41d0 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -2074,7 +2074,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2074 return ret; 2074 return ret;
2075} 2075}
2076 2076
2077int ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl) 2077struct xt_table *ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl)
2078{ 2078{
2079 int ret; 2079 int ret;
2080 struct xt_table_info *newinfo; 2080 struct xt_table_info *newinfo;
@@ -2084,8 +2084,10 @@ int ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl)
2084 struct xt_table *new_table; 2084 struct xt_table *new_table;
2085 2085
2086 newinfo = xt_alloc_table_info(repl->size); 2086 newinfo = xt_alloc_table_info(repl->size);
2087 if (!newinfo) 2087 if (!newinfo) {
2088 return -ENOMEM; 2088 ret = -ENOMEM;
2089 goto out;
2090 }
2089 2091
2090 /* choose the copy on our node/cpu, but dont care about preemption */ 2092 /* choose the copy on our node/cpu, but dont care about preemption */
2091 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; 2093 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
@@ -2096,18 +2098,20 @@ int ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl)
2096 repl->num_entries, 2098 repl->num_entries,
2097 repl->hook_entry, 2099 repl->hook_entry,
2098 repl->underflow); 2100 repl->underflow);
2099 if (ret != 0) { 2101 if (ret != 0)
2100 xt_free_table_info(newinfo); 2102 goto out_free;
2101 return ret;
2102 }
2103 2103
2104 new_table = xt_register_table(&init_net, table, &bootstrap, newinfo); 2104 new_table = xt_register_table(&init_net, table, &bootstrap, newinfo);
2105 if (IS_ERR(new_table)) { 2105 if (IS_ERR(new_table)) {
2106 xt_free_table_info(newinfo); 2106 ret = PTR_ERR(new_table);
2107 return PTR_ERR(new_table); 2107 goto out_free;
2108 } 2108 }
2109 return new_table;
2109 2110
2110 return 0; 2111out_free:
2112 xt_free_table_info(newinfo);
2113out:
2114 return ERR_PTR(ret);
2111} 2115}
2112 2116
2113void ip6t_unregister_table(struct xt_table *table) 2117void ip6t_unregister_table(struct xt_table *table)
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 87d38d08aad0..bffd67f32359 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -51,13 +51,14 @@ static struct
51 .term = IP6T_ERROR_INIT, /* ERROR */ 51 .term = IP6T_ERROR_INIT, /* ERROR */
52}; 52};
53 53
54static struct xt_table packet_filter = { 54static struct xt_table __packet_filter = {
55 .name = "filter", 55 .name = "filter",
56 .valid_hooks = FILTER_VALID_HOOKS, 56 .valid_hooks = FILTER_VALID_HOOKS,
57 .lock = RW_LOCK_UNLOCKED, 57 .lock = RW_LOCK_UNLOCKED,
58 .me = THIS_MODULE, 58 .me = THIS_MODULE,
59 .af = AF_INET6, 59 .af = AF_INET6,
60}; 60};
61static struct xt_table *packet_filter;
61 62
62/* The work comes in here from netfilter.c. */ 63/* The work comes in here from netfilter.c. */
63static unsigned int 64static unsigned int
@@ -67,7 +68,7 @@ ip6t_hook(unsigned int hook,
67 const struct net_device *out, 68 const struct net_device *out,
68 int (*okfn)(struct sk_buff *)) 69 int (*okfn)(struct sk_buff *))
69{ 70{
70 return ip6t_do_table(skb, hook, in, out, &packet_filter); 71 return ip6t_do_table(skb, hook, in, out, packet_filter);
71} 72}
72 73
73static unsigned int 74static unsigned int
@@ -87,7 +88,7 @@ ip6t_local_out_hook(unsigned int hook,
87 } 88 }
88#endif 89#endif
89 90
90 return ip6t_do_table(skb, hook, in, out, &packet_filter); 91 return ip6t_do_table(skb, hook, in, out, packet_filter);
91} 92}
92 93
93static struct nf_hook_ops ip6t_ops[] __read_mostly = { 94static struct nf_hook_ops ip6t_ops[] __read_mostly = {
@@ -131,9 +132,9 @@ static int __init ip6table_filter_init(void)
131 initial_table.entries[1].target.verdict = -forward - 1; 132 initial_table.entries[1].target.verdict = -forward - 1;
132 133
133 /* Register table */ 134 /* Register table */
134 ret = ip6t_register_table(&packet_filter, &initial_table.repl); 135 packet_filter = ip6t_register_table(&__packet_filter, &initial_table.repl);
135 if (ret < 0) 136 if (IS_ERR(packet_filter))
136 return ret; 137 return PTR_ERR(packet_filter);
137 138
138 /* Register hooks */ 139 /* Register hooks */
139 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 140 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
@@ -143,14 +144,14 @@ static int __init ip6table_filter_init(void)
143 return ret; 144 return ret;
144 145
145 cleanup_table: 146 cleanup_table:
146 ip6t_unregister_table(&packet_filter); 147 ip6t_unregister_table(packet_filter);
147 return ret; 148 return ret;
148} 149}
149 150
150static void __exit ip6table_filter_fini(void) 151static void __exit ip6table_filter_fini(void)
151{ 152{
152 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 153 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
153 ip6t_unregister_table(&packet_filter); 154 ip6t_unregister_table(packet_filter);
154} 155}
155 156
156module_init(ip6table_filter_init); 157module_init(ip6table_filter_init);
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index d6082600bc5d..63d334df3b40 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -57,13 +57,14 @@ static struct
57 .term = IP6T_ERROR_INIT, /* ERROR */ 57 .term = IP6T_ERROR_INIT, /* ERROR */
58}; 58};
59 59
60static struct xt_table packet_mangler = { 60static struct xt_table __packet_mangler = {
61 .name = "mangle", 61 .name = "mangle",
62 .valid_hooks = MANGLE_VALID_HOOKS, 62 .valid_hooks = MANGLE_VALID_HOOKS,
63 .lock = RW_LOCK_UNLOCKED, 63 .lock = RW_LOCK_UNLOCKED,
64 .me = THIS_MODULE, 64 .me = THIS_MODULE,
65 .af = AF_INET6, 65 .af = AF_INET6,
66}; 66};
67static struct xt_table *packet_mangler;
67 68
68/* The work comes in here from netfilter.c. */ 69/* The work comes in here from netfilter.c. */
69static unsigned int 70static unsigned int
@@ -73,7 +74,7 @@ ip6t_route_hook(unsigned int hook,
73 const struct net_device *out, 74 const struct net_device *out,
74 int (*okfn)(struct sk_buff *)) 75 int (*okfn)(struct sk_buff *))
75{ 76{
76 return ip6t_do_table(skb, hook, in, out, &packet_mangler); 77 return ip6t_do_table(skb, hook, in, out, packet_mangler);
77} 78}
78 79
79static unsigned int 80static unsigned int
@@ -108,7 +109,7 @@ ip6t_local_hook(unsigned int hook,
108 /* flowlabel and prio (includes version, which shouldn't change either */ 109 /* flowlabel and prio (includes version, which shouldn't change either */
109 flowlabel = *((u_int32_t *)ipv6_hdr(skb)); 110 flowlabel = *((u_int32_t *)ipv6_hdr(skb));
110 111
111 ret = ip6t_do_table(skb, hook, in, out, &packet_mangler); 112 ret = ip6t_do_table(skb, hook, in, out, packet_mangler);
112 113
113 if (ret != NF_DROP && ret != NF_STOLEN 114 if (ret != NF_DROP && ret != NF_STOLEN
114 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) 115 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
@@ -163,9 +164,9 @@ static int __init ip6table_mangle_init(void)
163 int ret; 164 int ret;
164 165
165 /* Register table */ 166 /* Register table */
166 ret = ip6t_register_table(&packet_mangler, &initial_table.repl); 167 packet_mangler = ip6t_register_table(&__packet_mangler, &initial_table.repl);
167 if (ret < 0) 168 if (IS_ERR(packet_mangler))
168 return ret; 169 return PTR_ERR(packet_mangler);
169 170
170 /* Register hooks */ 171 /* Register hooks */
171 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 172 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
@@ -175,14 +176,14 @@ static int __init ip6table_mangle_init(void)
175 return ret; 176 return ret;
176 177
177 cleanup_table: 178 cleanup_table:
178 ip6t_unregister_table(&packet_mangler); 179 ip6t_unregister_table(packet_mangler);
179 return ret; 180 return ret;
180} 181}
181 182
182static void __exit ip6table_mangle_fini(void) 183static void __exit ip6table_mangle_fini(void)
183{ 184{
184 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 185 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
185 ip6t_unregister_table(&packet_mangler); 186 ip6t_unregister_table(packet_mangler);
186} 187}
187 188
188module_init(ip6table_mangle_init); 189module_init(ip6table_mangle_init);
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index eccbaaa104af..7f55b236440e 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -35,13 +35,14 @@ static struct
35 .term = IP6T_ERROR_INIT, /* ERROR */ 35 .term = IP6T_ERROR_INIT, /* ERROR */
36}; 36};
37 37
38static struct xt_table packet_raw = { 38static struct xt_table __packet_raw = {
39 .name = "raw", 39 .name = "raw",
40 .valid_hooks = RAW_VALID_HOOKS, 40 .valid_hooks = RAW_VALID_HOOKS,
41 .lock = RW_LOCK_UNLOCKED, 41 .lock = RW_LOCK_UNLOCKED,
42 .me = THIS_MODULE, 42 .me = THIS_MODULE,
43 .af = AF_INET6, 43 .af = AF_INET6,
44}; 44};
45static struct xt_table *packet_raw;
45 46
46/* The work comes in here from netfilter.c. */ 47/* The work comes in here from netfilter.c. */
47static unsigned int 48static unsigned int
@@ -51,7 +52,7 @@ ip6t_hook(unsigned int hook,
51 const struct net_device *out, 52 const struct net_device *out,
52 int (*okfn)(struct sk_buff *)) 53 int (*okfn)(struct sk_buff *))
53{ 54{
54 return ip6t_do_table(skb, hook, in, out, &packet_raw); 55 return ip6t_do_table(skb, hook, in, out, packet_raw);
55} 56}
56 57
57static struct nf_hook_ops ip6t_ops[] __read_mostly = { 58static struct nf_hook_ops ip6t_ops[] __read_mostly = {
@@ -76,9 +77,9 @@ static int __init ip6table_raw_init(void)
76 int ret; 77 int ret;
77 78
78 /* Register table */ 79 /* Register table */
79 ret = ip6t_register_table(&packet_raw, &initial_table.repl); 80 packet_raw = ip6t_register_table(&__packet_raw, &initial_table.repl);
80 if (ret < 0) 81 if (IS_ERR(packet_raw))
81 return ret; 82 return PTR_ERR(packet_raw);
82 83
83 /* Register hooks */ 84 /* Register hooks */
84 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 85 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
@@ -88,14 +89,14 @@ static int __init ip6table_raw_init(void)
88 return ret; 89 return ret;
89 90
90 cleanup_table: 91 cleanup_table:
91 ip6t_unregister_table(&packet_raw); 92 ip6t_unregister_table(packet_raw);
92 return ret; 93 return ret;
93} 94}
94 95
95static void __exit ip6table_raw_fini(void) 96static void __exit ip6table_raw_fini(void)
96{ 97{
97 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 98 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
98 ip6t_unregister_table(&packet_raw); 99 ip6t_unregister_table(packet_raw);
99} 100}
100 101
101module_init(ip6table_raw_init); 102module_init(ip6table_raw_init);