aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
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