Skip to content

Commit 1762527

Browse files
regitkaber
authored andcommitted
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>
1 parent 0f5b3e8 commit 1762527

File tree

1 file changed

+84
-1
lines changed

1 file changed

+84
-1
lines changed

net/netfilter/nf_log.c

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
LOG target modules */
1515

1616
#define NF_LOG_PREFIXLEN 128
17+
#define NFLOGGER_NAME_LEN 64
1718

1819
static const struct nf_logger *nf_loggers[NFPROTO_NUMPROTO] __read_mostly;
1920
static struct list_head nf_loggers_l[NFPROTO_NUMPROTO] __read_mostly;
@@ -207,18 +208,100 @@ static const struct file_operations nflog_file_ops = {
207208
.release = seq_release,
208209
};
209210

211+
210212
#endif /* PROC_FS */
211213

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;
212225

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)
214261
{
215262
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;
216294
#ifdef CONFIG_PROC_FS
217295
if (!proc_create("nf_log", S_IRUGO,
218296
proc_net_netfilter, &nflog_file_ops))
219297
return -1;
220298
#endif
221299

300+
/* Errors will trigger panic, unroll on error is unnecessary. */
301+
r = netfilter_log_sysctl_init();
302+
if (r < 0)
303+
return r;
304+
222305
for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
223306
INIT_LIST_HEAD(&(nf_loggers_l[i]));
224307

0 commit comments

Comments
 (0)