aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Leblond <eric@inl.fr>2009-03-23 08:16:53 -0400
committerPatrick McHardy <kaber@trash.net>2009-03-23 08:16:53 -0400
commit176252746ebbc8db97e304345af1f2563c7dc139 (patch)
tree153bc3b193a1c9cd21a52ab67b622afd4db869d8 /net
parent0f5b3e85a3716efebb0150ebb7c6d022e2bf17d7 (diff)
netfilter: sysctl support of logger choice
This patchs adds support of modification of the used logger via sysctl. It can be used to change the logger to module that can not use the bind operation (ipt_LOG and ipt_ULOG). For this purpose, it creates a directory /proc/sys/net/netfilter/nf_log which contains a file per-protocol. The content of the file is the name current logger (NONE if not set) and a logger can be setup by simply echoing its name to the file. By echoing "NONE" to a /proc/sys/net/netfilter/nf_log/PROTO file, the logger corresponding to this PROTO is set to NULL. Signed-off-by: Eric Leblond <eric@inl.fr> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_log.c85
1 files changed, 84 insertions, 1 deletions
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 4fcbcc71aa32..8bb998fe098b 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -14,6 +14,7 @@
14 LOG target modules */ 14 LOG target modules */
15 15
16#define NF_LOG_PREFIXLEN 128 16#define NF_LOG_PREFIXLEN 128
17#define NFLOGGER_NAME_LEN 64
17 18
18static const struct nf_logger *nf_loggers[NFPROTO_NUMPROTO] __read_mostly; 19static const struct nf_logger *nf_loggers[NFPROTO_NUMPROTO] __read_mostly;
19static struct list_head nf_loggers_l[NFPROTO_NUMPROTO] __read_mostly; 20static struct list_head nf_loggers_l[NFPROTO_NUMPROTO] __read_mostly;
@@ -207,18 +208,100 @@ static const struct file_operations nflog_file_ops = {
207 .release = seq_release, 208 .release = seq_release,
208}; 209};
209 210
211
210#endif /* PROC_FS */ 212#endif /* PROC_FS */
211 213
214#ifdef CONFIG_SYSCTL
215struct ctl_path nf_log_sysctl_path[] = {
216 { .procname = "net", .ctl_name = CTL_NET, },
217 { .procname = "netfilter", .ctl_name = NET_NETFILTER, },
218 { .procname = "nf_log", .ctl_name = CTL_UNNUMBERED, },
219 { }
220};
221
222static char nf_log_sysctl_fnames[NFPROTO_NUMPROTO-NFPROTO_UNSPEC][3];
223static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1];
224static struct ctl_table_header *nf_log_dir_header;
212 225
213int __init netfilter_log_init(void) 226static int nf_log_proc_dostring(ctl_table *table, int write, struct file *filp,
227 void *buffer, size_t *lenp, loff_t *ppos)
228{
229 const struct nf_logger *logger;
230 int r = 0;
231 int tindex = (unsigned long)table->extra1;
232
233 if (write) {
234 if (!strcmp(buffer, "NONE")) {
235 nf_log_unbind_pf(tindex);
236 return 0;
237 }
238 mutex_lock(&nf_log_mutex);
239 logger = __find_logger(tindex, buffer);
240 if (logger == NULL) {
241 mutex_unlock(&nf_log_mutex);
242 return -ENOENT;
243 }
244 rcu_assign_pointer(nf_loggers[tindex], logger);
245 mutex_unlock(&nf_log_mutex);
246 } else {
247 rcu_read_lock();
248 logger = rcu_dereference(nf_loggers[tindex]);
249 if (!logger)
250 table->data = "NONE";
251 else
252 table->data = logger->name;
253 r = proc_dostring(table, write, filp, buffer, lenp, ppos);
254 rcu_read_unlock();
255 }
256
257 return r;
258}
259
260static __init int netfilter_log_sysctl_init(void)
214{ 261{
215 int i; 262 int i;
263
264 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) {
265 snprintf(nf_log_sysctl_fnames[i-NFPROTO_UNSPEC], 3, "%d", i);
266 nf_log_sysctl_table[i].ctl_name = CTL_UNNUMBERED;
267 nf_log_sysctl_table[i].procname =
268 nf_log_sysctl_fnames[i-NFPROTO_UNSPEC];
269 nf_log_sysctl_table[i].data = NULL;
270 nf_log_sysctl_table[i].maxlen =
271 NFLOGGER_NAME_LEN * sizeof(char);
272 nf_log_sysctl_table[i].mode = 0644;
273 nf_log_sysctl_table[i].proc_handler = nf_log_proc_dostring;
274 nf_log_sysctl_table[i].extra1 = (void *)(unsigned long) i;
275 }
276
277 nf_log_dir_header = register_sysctl_paths(nf_log_sysctl_path,
278 nf_log_sysctl_table);
279 if (!nf_log_dir_header)
280 return -ENOMEM;
281
282 return 0;
283}
284#else
285static __init int netfilter_log_sysctl_init(void)
286{
287 return 0;
288}
289#endif /* CONFIG_SYSCTL */
290
291int __init netfilter_log_init(void)
292{
293 int i, r;
216#ifdef CONFIG_PROC_FS 294#ifdef CONFIG_PROC_FS
217 if (!proc_create("nf_log", S_IRUGO, 295 if (!proc_create("nf_log", S_IRUGO,
218 proc_net_netfilter, &nflog_file_ops)) 296 proc_net_netfilter, &nflog_file_ops))
219 return -1; 297 return -1;
220#endif 298#endif
221 299
300 /* Errors will trigger panic, unroll on error is unnecessary. */
301 r = netfilter_log_sysctl_init();
302 if (r < 0)
303 return r;
304
222 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) 305 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
223 INIT_LIST_HEAD(&(nf_loggers_l[i])); 306 INIT_LIST_HEAD(&(nf_loggers_l[i]));
224 307