diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_log.c | 85 |
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 | ||
18 | static const struct nf_logger *nf_loggers[NFPROTO_NUMPROTO] __read_mostly; | 19 | static const struct nf_logger *nf_loggers[NFPROTO_NUMPROTO] __read_mostly; |
19 | static struct list_head nf_loggers_l[NFPROTO_NUMPROTO] __read_mostly; | 20 | static 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 | ||
215 | struct 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 | |||
222 | static char nf_log_sysctl_fnames[NFPROTO_NUMPROTO-NFPROTO_UNSPEC][3]; | ||
223 | static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1]; | ||
224 | static struct ctl_table_header *nf_log_dir_header; | ||
212 | 225 | ||
213 | int __init netfilter_log_init(void) | 226 | static 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 | |||
260 | static __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 | ||
285 | static __init int netfilter_log_sysctl_init(void) | ||
286 | { | ||
287 | return 0; | ||
288 | } | ||
289 | #endif /* CONFIG_SYSCTL */ | ||
290 | |||
291 | int __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 | ||