xref: /linux/drivers/net/netconsole.c (revision 3f1c07fc21c68bd3bd2df9d2c9441f6485e934d9)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  linux/drivers/net/netconsole.c
4  *
5  *  Copyright (C) 2001  Ingo Molnar <mingo@redhat.com>
6  *
7  *  This file contains the implementation of an IRQ-safe, crash-safe
8  *  kernel console implementation that outputs kernel messages to the
9  *  network.
10  *
11  * Modification history:
12  *
13  * 2001-09-17    started by Ingo Molnar.
14  * 2003-08-11    2.6 port by Matt Mackall
15  *               simplified options
16  *               generic card hooks
17  *               works non-modular
18  * 2003-09-07    rewritten with netpoll api
19  */
20 
21 /****************************************************************
22  *
23  ****************************************************************/
24 
25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26 
27 #include <linux/mm.h>
28 #include <linux/init.h>
29 #include <linux/module.h>
30 #include <linux/slab.h>
31 #include <linux/console.h>
32 #include <linux/moduleparam.h>
33 #include <linux/kernel.h>
34 #include <linux/string.h>
35 #include <linux/netpoll.h>
36 #include <linux/inet.h>
37 #include <linux/configfs.h>
38 #include <linux/etherdevice.h>
39 #include <linux/u64_stats_sync.h>
40 #include <linux/utsname.h>
41 #include <linux/rtnetlink.h>
42 
43 MODULE_AUTHOR("Matt Mackall <mpm@selenic.com>");
44 MODULE_DESCRIPTION("Console driver for network interfaces");
45 MODULE_LICENSE("GPL");
46 
47 #define MAX_PARAM_LENGTH		256
48 #define MAX_EXTRADATA_ENTRY_LEN		256
49 #define MAX_EXTRADATA_VALUE_LEN	200
50 /* The number 3 comes from userdata entry format characters (' ', '=', '\n') */
51 #define MAX_EXTRADATA_NAME_LEN		(MAX_EXTRADATA_ENTRY_LEN - \
52 					MAX_EXTRADATA_VALUE_LEN - 3)
53 #define MAX_USERDATA_ITEMS		256
54 #define MAX_PRINT_CHUNK			1000
55 
56 static char config[MAX_PARAM_LENGTH];
57 module_param_string(netconsole, config, MAX_PARAM_LENGTH, 0);
58 MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]");
59 
60 static bool oops_only;
61 module_param(oops_only, bool, 0600);
62 MODULE_PARM_DESC(oops_only, "Only log oops messages");
63 
64 #define NETCONSOLE_PARAM_TARGET_PREFIX "cmdline"
65 
66 #ifndef	MODULE
option_setup(char * opt)67 static int __init option_setup(char *opt)
68 {
69 	strscpy(config, opt, MAX_PARAM_LENGTH);
70 	return 1;
71 }
72 __setup("netconsole=", option_setup);
73 #endif	/* MODULE */
74 
75 /* Linked list of all configured targets */
76 static LIST_HEAD(target_list);
77 /* target_cleanup_list is used to track targets that need to be cleaned outside
78  * of target_list_lock. It should be cleaned in the same function it is
79  * populated.
80  */
81 static LIST_HEAD(target_cleanup_list);
82 
83 /* This needs to be a spinlock because write_msg() cannot sleep */
84 static DEFINE_SPINLOCK(target_list_lock);
85 /* This needs to be a mutex because netpoll_cleanup might sleep */
86 static DEFINE_MUTEX(target_cleanup_list_lock);
87 
88 /*
89  * Console driver for netconsoles.  Register only consoles that have
90  * an associated target of the same type.
91  */
92 static struct console netconsole_ext, netconsole;
93 
94 struct netconsole_target_stats  {
95 	u64_stats_t xmit_drop_count;
96 	u64_stats_t enomem_count;
97 	struct u64_stats_sync syncp;
98 };
99 
100 enum console_type {
101 	CONS_BASIC = BIT(0),
102 	CONS_EXTENDED = BIT(1),
103 };
104 
105 /* Features enabled in sysdata. Contrary to userdata, this data is populated by
106  * the kernel. The fields are designed as bitwise flags, allowing multiple
107  * features to be set in sysdata_fields.
108  */
109 enum sysdata_feature {
110 	/* Populate the CPU that sends the message */
111 	SYSDATA_CPU_NR = BIT(0),
112 	/* Populate the task name (as in current->comm) in sysdata */
113 	SYSDATA_TASKNAME = BIT(1),
114 	/* Kernel release/version as part of sysdata */
115 	SYSDATA_RELEASE = BIT(2),
116 	/* Include a per-target message ID as part of sysdata */
117 	SYSDATA_MSGID = BIT(3),
118 	/* Sentinel: highest bit position */
119 	MAX_SYSDATA_ITEMS = 4,
120 };
121 
122 /**
123  * struct netconsole_target - Represents a configured netconsole target.
124  * @list:	Links this target into the target_list.
125  * @group:	Links us into the configfs subsystem hierarchy.
126  * @userdata_group:	Links to the userdata configfs hierarchy
127  * @userdata:		Cached, formatted string of append
128  * @userdata_length:	String length of userdata.
129  * @sysdata:		Cached, formatted string of append
130  * @sysdata_fields:	Sysdata features enabled.
131  * @msgcounter:	Message sent counter.
132  * @stats:	Packet send stats for the target. Used for debugging.
133  * @enabled:	On / off knob to enable / disable target.
134  *		Visible from userspace (read-write).
135  *		We maintain a strict 1:1 correspondence between this and
136  *		whether the corresponding netpoll is active or inactive.
137  *		Also, other parameters of a target may be modified at
138  *		runtime only when it is disabled (enabled == 0).
139  * @extended:	Denotes whether console is extended or not.
140  * @release:	Denotes whether kernel release version should be prepended
141  *		to the message. Depends on extended console.
142  * @np:		The netpoll structure for this target.
143  *		Contains the other userspace visible parameters:
144  *		dev_name	(read-write)
145  *		local_port	(read-write)
146  *		remote_port	(read-write)
147  *		local_ip	(read-write)
148  *		remote_ip	(read-write)
149  *		local_mac	(read-only)
150  *		remote_mac	(read-write)
151  * @buf:	The buffer used to send the full msg to the network stack
152  */
153 struct netconsole_target {
154 	struct list_head	list;
155 #ifdef	CONFIG_NETCONSOLE_DYNAMIC
156 	struct config_group	group;
157 	struct config_group	userdata_group;
158 	char			*userdata;
159 	size_t			userdata_length;
160 	char			sysdata[MAX_EXTRADATA_ENTRY_LEN * MAX_SYSDATA_ITEMS];
161 
162 	/* bit-wise with sysdata_feature bits */
163 	u32			sysdata_fields;
164 	/* protected by target_list_lock */
165 	u32			msgcounter;
166 #endif
167 	struct netconsole_target_stats stats;
168 	bool			enabled;
169 	bool			extended;
170 	bool			release;
171 	struct netpoll		np;
172 	/* protected by target_list_lock */
173 	char			buf[MAX_PRINT_CHUNK];
174 };
175 
176 #ifdef	CONFIG_NETCONSOLE_DYNAMIC
177 
178 static struct configfs_subsystem netconsole_subsys;
179 static DEFINE_MUTEX(dynamic_netconsole_mutex);
180 
dynamic_netconsole_init(void)181 static int __init dynamic_netconsole_init(void)
182 {
183 	config_group_init(&netconsole_subsys.su_group);
184 	mutex_init(&netconsole_subsys.su_mutex);
185 	return configfs_register_subsystem(&netconsole_subsys);
186 }
187 
dynamic_netconsole_exit(void)188 static void __exit dynamic_netconsole_exit(void)
189 {
190 	configfs_unregister_subsystem(&netconsole_subsys);
191 }
192 
193 /*
194  * Targets that were created by parsing the boot/module option string
195  * do not exist in the configfs hierarchy (and have NULL names) and will
196  * never go away, so make these a no-op for them.
197  */
netconsole_target_get(struct netconsole_target * nt)198 static void netconsole_target_get(struct netconsole_target *nt)
199 {
200 	if (config_item_name(&nt->group.cg_item))
201 		config_group_get(&nt->group);
202 }
203 
netconsole_target_put(struct netconsole_target * nt)204 static void netconsole_target_put(struct netconsole_target *nt)
205 {
206 	if (config_item_name(&nt->group.cg_item))
207 		config_group_put(&nt->group);
208 }
209 
210 #else	/* !CONFIG_NETCONSOLE_DYNAMIC */
211 
dynamic_netconsole_init(void)212 static int __init dynamic_netconsole_init(void)
213 {
214 	return 0;
215 }
216 
dynamic_netconsole_exit(void)217 static void __exit dynamic_netconsole_exit(void)
218 {
219 }
220 
221 /*
222  * No danger of targets going away from under us when dynamic
223  * reconfigurability is off.
224  */
netconsole_target_get(struct netconsole_target * nt)225 static void netconsole_target_get(struct netconsole_target *nt)
226 {
227 }
228 
netconsole_target_put(struct netconsole_target * nt)229 static void netconsole_target_put(struct netconsole_target *nt)
230 {
231 }
232 
populate_configfs_item(struct netconsole_target * nt,int cmdline_count)233 static void populate_configfs_item(struct netconsole_target *nt,
234 				   int cmdline_count)
235 {
236 }
237 #endif	/* CONFIG_NETCONSOLE_DYNAMIC */
238 
239 /* Allocate and initialize with defaults.
240  * Note that these targets get their config_item fields zeroed-out.
241  */
alloc_and_init(void)242 static struct netconsole_target *alloc_and_init(void)
243 {
244 	struct netconsole_target *nt;
245 
246 	nt = kzalloc(sizeof(*nt), GFP_KERNEL);
247 	if (!nt)
248 		return nt;
249 
250 	if (IS_ENABLED(CONFIG_NETCONSOLE_EXTENDED_LOG))
251 		nt->extended = true;
252 	if (IS_ENABLED(CONFIG_NETCONSOLE_PREPEND_RELEASE))
253 		nt->release = true;
254 
255 	nt->np.name = "netconsole";
256 	strscpy(nt->np.dev_name, "eth0", IFNAMSIZ);
257 	nt->np.local_port = 6665;
258 	nt->np.remote_port = 6666;
259 	eth_broadcast_addr(nt->np.remote_mac);
260 
261 	return nt;
262 }
263 
264 /* Clean up every target in the cleanup_list and move the clean targets back to
265  * the main target_list.
266  */
netconsole_process_cleanups_core(void)267 static void netconsole_process_cleanups_core(void)
268 {
269 	struct netconsole_target *nt, *tmp;
270 	unsigned long flags;
271 
272 	/* The cleanup needs RTNL locked */
273 	ASSERT_RTNL();
274 
275 	mutex_lock(&target_cleanup_list_lock);
276 	list_for_each_entry_safe(nt, tmp, &target_cleanup_list, list) {
277 		/* all entries in the cleanup_list needs to be disabled */
278 		WARN_ON_ONCE(nt->enabled);
279 		do_netpoll_cleanup(&nt->np);
280 		/* moved the cleaned target to target_list. Need to hold both
281 		 * locks
282 		 */
283 		spin_lock_irqsave(&target_list_lock, flags);
284 		list_move(&nt->list, &target_list);
285 		spin_unlock_irqrestore(&target_list_lock, flags);
286 	}
287 	WARN_ON_ONCE(!list_empty(&target_cleanup_list));
288 	mutex_unlock(&target_cleanup_list_lock);
289 }
290 
netconsole_print_banner(struct netpoll * np)291 static void netconsole_print_banner(struct netpoll *np)
292 {
293 	np_info(np, "local port %d\n", np->local_port);
294 	if (np->ipv6)
295 		np_info(np, "local IPv6 address %pI6c\n", &np->local_ip.in6);
296 	else
297 		np_info(np, "local IPv4 address %pI4\n", &np->local_ip.ip);
298 	np_info(np, "interface name '%s'\n", np->dev_name);
299 	np_info(np, "local ethernet address '%pM'\n", np->dev_mac);
300 	np_info(np, "remote port %d\n", np->remote_port);
301 	if (np->ipv6)
302 		np_info(np, "remote IPv6 address %pI6c\n", &np->remote_ip.in6);
303 	else
304 		np_info(np, "remote IPv4 address %pI4\n", &np->remote_ip.ip);
305 	np_info(np, "remote ethernet address %pM\n", np->remote_mac);
306 }
307 
308 /* Parse the string and populate the `inet_addr` union. Return 0 if IPv4 is
309  * populated, 1 if IPv6 is populated, and -1 upon failure.
310  */
netpoll_parse_ip_addr(const char * str,union inet_addr * addr)311 static int netpoll_parse_ip_addr(const char *str, union inet_addr *addr)
312 {
313 	const char *end = NULL;
314 	int len;
315 
316 	len = strlen(str);
317 	if (!len)
318 		return -1;
319 
320 	if (str[len - 1] == '\n')
321 		len -= 1;
322 
323 	if (in4_pton(str, len, (void *)addr, -1, &end) > 0 &&
324 	    (!end || *end == 0 || *end == '\n'))
325 		return 0;
326 
327 	if (IS_ENABLED(CONFIG_IPV6) &&
328 	    in6_pton(str, len, (void *)addr, -1, &end) > 0 &&
329 	    (!end || *end == 0 || *end == '\n'))
330 		return 1;
331 
332 	return -1;
333 }
334 
335 #ifdef	CONFIG_NETCONSOLE_DYNAMIC
336 
337 /*
338  * Our subsystem hierarchy is:
339  *
340  * /sys/kernel/config/netconsole/
341  *				|
342  *				<target>/
343  *				|	enabled
344  *				|	release
345  *				|	dev_name
346  *				|	local_port
347  *				|	remote_port
348  *				|	local_ip
349  *				|	remote_ip
350  *				|	local_mac
351  *				|	remote_mac
352  *				|	transmit_errors
353  *				|	userdata/
354  *				|		<key>/
355  *				|			value
356  *				|		...
357  *				|
358  *				<target>/...
359  */
360 
to_target(struct config_item * item)361 static struct netconsole_target *to_target(struct config_item *item)
362 {
363 	struct config_group *cfg_group;
364 
365 	cfg_group = to_config_group(item);
366 	if (!cfg_group)
367 		return NULL;
368 	return container_of(to_config_group(item),
369 			    struct netconsole_target, group);
370 }
371 
372 /* Do the list cleanup with the rtnl lock hold.  rtnl lock is necessary because
373  * netdev might be cleaned-up by calling __netpoll_cleanup(),
374  */
netconsole_process_cleanups(void)375 static void netconsole_process_cleanups(void)
376 {
377 	/* rtnl lock is called here, because it has precedence over
378 	 * target_cleanup_list_lock mutex and target_cleanup_list
379 	 */
380 	rtnl_lock();
381 	netconsole_process_cleanups_core();
382 	rtnl_unlock();
383 }
384 
385 /* Get rid of possible trailing newline, returning the new length */
trim_newline(char * s,size_t maxlen)386 static void trim_newline(char *s, size_t maxlen)
387 {
388 	size_t len;
389 
390 	len = strnlen(s, maxlen);
391 	if (s[len - 1] == '\n')
392 		s[len - 1] = '\0';
393 }
394 
395 /*
396  * Attribute operations for netconsole_target.
397  */
398 
enabled_show(struct config_item * item,char * buf)399 static ssize_t enabled_show(struct config_item *item, char *buf)
400 {
401 	return sysfs_emit(buf, "%d\n", to_target(item)->enabled);
402 }
403 
extended_show(struct config_item * item,char * buf)404 static ssize_t extended_show(struct config_item *item, char *buf)
405 {
406 	return sysfs_emit(buf, "%d\n", to_target(item)->extended);
407 }
408 
release_show(struct config_item * item,char * buf)409 static ssize_t release_show(struct config_item *item, char *buf)
410 {
411 	return sysfs_emit(buf, "%d\n", to_target(item)->release);
412 }
413 
dev_name_show(struct config_item * item,char * buf)414 static ssize_t dev_name_show(struct config_item *item, char *buf)
415 {
416 	return sysfs_emit(buf, "%s\n", to_target(item)->np.dev_name);
417 }
418 
local_port_show(struct config_item * item,char * buf)419 static ssize_t local_port_show(struct config_item *item, char *buf)
420 {
421 	return sysfs_emit(buf, "%d\n", to_target(item)->np.local_port);
422 }
423 
remote_port_show(struct config_item * item,char * buf)424 static ssize_t remote_port_show(struct config_item *item, char *buf)
425 {
426 	return sysfs_emit(buf, "%d\n", to_target(item)->np.remote_port);
427 }
428 
local_ip_show(struct config_item * item,char * buf)429 static ssize_t local_ip_show(struct config_item *item, char *buf)
430 {
431 	struct netconsole_target *nt = to_target(item);
432 
433 	if (nt->np.ipv6)
434 		return sysfs_emit(buf, "%pI6c\n", &nt->np.local_ip.in6);
435 	else
436 		return sysfs_emit(buf, "%pI4\n", &nt->np.local_ip);
437 }
438 
remote_ip_show(struct config_item * item,char * buf)439 static ssize_t remote_ip_show(struct config_item *item, char *buf)
440 {
441 	struct netconsole_target *nt = to_target(item);
442 
443 	if (nt->np.ipv6)
444 		return sysfs_emit(buf, "%pI6c\n", &nt->np.remote_ip.in6);
445 	else
446 		return sysfs_emit(buf, "%pI4\n", &nt->np.remote_ip);
447 }
448 
local_mac_show(struct config_item * item,char * buf)449 static ssize_t local_mac_show(struct config_item *item, char *buf)
450 {
451 	struct net_device *dev = to_target(item)->np.dev;
452 	static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
453 
454 	return sysfs_emit(buf, "%pM\n", dev ? dev->dev_addr : bcast);
455 }
456 
remote_mac_show(struct config_item * item,char * buf)457 static ssize_t remote_mac_show(struct config_item *item, char *buf)
458 {
459 	return sysfs_emit(buf, "%pM\n", to_target(item)->np.remote_mac);
460 }
461 
transmit_errors_show(struct config_item * item,char * buf)462 static ssize_t transmit_errors_show(struct config_item *item, char *buf)
463 {
464 	struct netconsole_target *nt = to_target(item);
465 	u64 xmit_drop_count, enomem_count;
466 	unsigned int start;
467 
468 	do {
469 		start = u64_stats_fetch_begin(&nt->stats.syncp);
470 		xmit_drop_count = u64_stats_read(&nt->stats.xmit_drop_count);
471 		enomem_count = u64_stats_read(&nt->stats.enomem_count);
472 	} while (u64_stats_fetch_retry(&nt->stats.syncp, start));
473 
474 	return sysfs_emit(buf, "%llu\n", xmit_drop_count + enomem_count);
475 }
476 
477 /* configfs helper to display if cpu_nr sysdata feature is enabled */
sysdata_cpu_nr_enabled_show(struct config_item * item,char * buf)478 static ssize_t sysdata_cpu_nr_enabled_show(struct config_item *item, char *buf)
479 {
480 	struct netconsole_target *nt = to_target(item->ci_parent);
481 	bool cpu_nr_enabled;
482 
483 	mutex_lock(&dynamic_netconsole_mutex);
484 	cpu_nr_enabled = !!(nt->sysdata_fields & SYSDATA_CPU_NR);
485 	mutex_unlock(&dynamic_netconsole_mutex);
486 
487 	return sysfs_emit(buf, "%d\n", cpu_nr_enabled);
488 }
489 
490 /* configfs helper to display if taskname sysdata feature is enabled */
sysdata_taskname_enabled_show(struct config_item * item,char * buf)491 static ssize_t sysdata_taskname_enabled_show(struct config_item *item,
492 					     char *buf)
493 {
494 	struct netconsole_target *nt = to_target(item->ci_parent);
495 	bool taskname_enabled;
496 
497 	mutex_lock(&dynamic_netconsole_mutex);
498 	taskname_enabled = !!(nt->sysdata_fields & SYSDATA_TASKNAME);
499 	mutex_unlock(&dynamic_netconsole_mutex);
500 
501 	return sysfs_emit(buf, "%d\n", taskname_enabled);
502 }
503 
sysdata_release_enabled_show(struct config_item * item,char * buf)504 static ssize_t sysdata_release_enabled_show(struct config_item *item,
505 					    char *buf)
506 {
507 	struct netconsole_target *nt = to_target(item->ci_parent);
508 	bool release_enabled;
509 
510 	mutex_lock(&dynamic_netconsole_mutex);
511 	release_enabled = !!(nt->sysdata_fields & SYSDATA_TASKNAME);
512 	mutex_unlock(&dynamic_netconsole_mutex);
513 
514 	return sysfs_emit(buf, "%d\n", release_enabled);
515 }
516 
517 /* Iterate in the list of target, and make sure we don't have any console
518  * register without targets of the same type
519  */
unregister_netcons_consoles(void)520 static void unregister_netcons_consoles(void)
521 {
522 	struct netconsole_target *nt;
523 	u32 console_type_needed = 0;
524 	unsigned long flags;
525 
526 	spin_lock_irqsave(&target_list_lock, flags);
527 	list_for_each_entry(nt, &target_list, list) {
528 		if (nt->extended)
529 			console_type_needed |= CONS_EXTENDED;
530 		else
531 			console_type_needed |= CONS_BASIC;
532 	}
533 	spin_unlock_irqrestore(&target_list_lock, flags);
534 
535 	if (!(console_type_needed & CONS_EXTENDED) &&
536 	    console_is_registered(&netconsole_ext))
537 		unregister_console(&netconsole_ext);
538 
539 	if (!(console_type_needed & CONS_BASIC) &&
540 	    console_is_registered(&netconsole))
541 		unregister_console(&netconsole);
542 }
543 
sysdata_msgid_enabled_show(struct config_item * item,char * buf)544 static ssize_t sysdata_msgid_enabled_show(struct config_item *item,
545 					  char *buf)
546 {
547 	struct netconsole_target *nt = to_target(item->ci_parent);
548 	bool msgid_enabled;
549 
550 	mutex_lock(&dynamic_netconsole_mutex);
551 	msgid_enabled = !!(nt->sysdata_fields & SYSDATA_MSGID);
552 	mutex_unlock(&dynamic_netconsole_mutex);
553 
554 	return sysfs_emit(buf, "%d\n", msgid_enabled);
555 }
556 
557 /*
558  * This one is special -- targets created through the configfs interface
559  * are not enabled (and the corresponding netpoll activated) by default.
560  * The user is expected to set the desired parameters first (which
561  * would enable him to dynamically add new netpoll targets for new
562  * network interfaces as and when they come up).
563  */
enabled_store(struct config_item * item,const char * buf,size_t count)564 static ssize_t enabled_store(struct config_item *item,
565 		const char *buf, size_t count)
566 {
567 	struct netconsole_target *nt = to_target(item);
568 	unsigned long flags;
569 	bool enabled;
570 	ssize_t ret;
571 
572 	mutex_lock(&dynamic_netconsole_mutex);
573 	ret = kstrtobool(buf, &enabled);
574 	if (ret)
575 		goto out_unlock;
576 
577 	ret = -EINVAL;
578 	if (enabled == nt->enabled) {
579 		pr_info("network logging has already %s\n",
580 			nt->enabled ? "started" : "stopped");
581 		goto out_unlock;
582 	}
583 
584 	if (enabled) {	/* true */
585 		if (nt->release && !nt->extended) {
586 			pr_err("Not enabling netconsole. Release feature requires extended log message");
587 			goto out_unlock;
588 		}
589 
590 		if (nt->extended && !console_is_registered(&netconsole_ext)) {
591 			netconsole_ext.flags |= CON_ENABLED;
592 			register_console(&netconsole_ext);
593 		}
594 
595 		/* User might be enabling the basic format target for the very
596 		 * first time, make sure the console is registered.
597 		 */
598 		if (!nt->extended && !console_is_registered(&netconsole)) {
599 			netconsole.flags |= CON_ENABLED;
600 			register_console(&netconsole);
601 		}
602 
603 		/*
604 		 * Skip netconsole_parser_cmdline() -- all the attributes are
605 		 * already configured via configfs. Just print them out.
606 		 */
607 		netconsole_print_banner(&nt->np);
608 
609 		ret = netpoll_setup(&nt->np);
610 		if (ret)
611 			goto out_unlock;
612 
613 		nt->enabled = true;
614 		pr_info("network logging started\n");
615 	} else {	/* false */
616 		/* We need to disable the netconsole before cleaning it up
617 		 * otherwise we might end up in write_msg() with
618 		 * nt->np.dev == NULL and nt->enabled == true
619 		 */
620 		mutex_lock(&target_cleanup_list_lock);
621 		spin_lock_irqsave(&target_list_lock, flags);
622 		nt->enabled = false;
623 		/* Remove the target from the list, while holding
624 		 * target_list_lock
625 		 */
626 		list_move(&nt->list, &target_cleanup_list);
627 		spin_unlock_irqrestore(&target_list_lock, flags);
628 		mutex_unlock(&target_cleanup_list_lock);
629 		/* Unregister consoles, whose the last target of that type got
630 		 * disabled.
631 		 */
632 		unregister_netcons_consoles();
633 	}
634 
635 	ret = strnlen(buf, count);
636 	/* Deferred cleanup */
637 	netconsole_process_cleanups();
638 out_unlock:
639 	mutex_unlock(&dynamic_netconsole_mutex);
640 	return ret;
641 }
642 
release_store(struct config_item * item,const char * buf,size_t count)643 static ssize_t release_store(struct config_item *item, const char *buf,
644 			     size_t count)
645 {
646 	struct netconsole_target *nt = to_target(item);
647 	bool release;
648 	ssize_t ret;
649 
650 	mutex_lock(&dynamic_netconsole_mutex);
651 	if (nt->enabled) {
652 		pr_err("target (%s) is enabled, disable to update parameters\n",
653 		       config_item_name(&nt->group.cg_item));
654 		ret = -EINVAL;
655 		goto out_unlock;
656 	}
657 
658 	ret = kstrtobool(buf, &release);
659 	if (ret)
660 		goto out_unlock;
661 
662 	nt->release = release;
663 
664 	ret = strnlen(buf, count);
665 out_unlock:
666 	mutex_unlock(&dynamic_netconsole_mutex);
667 	return ret;
668 }
669 
extended_store(struct config_item * item,const char * buf,size_t count)670 static ssize_t extended_store(struct config_item *item, const char *buf,
671 		size_t count)
672 {
673 	struct netconsole_target *nt = to_target(item);
674 	bool extended;
675 	ssize_t ret;
676 
677 	mutex_lock(&dynamic_netconsole_mutex);
678 	if (nt->enabled) {
679 		pr_err("target (%s) is enabled, disable to update parameters\n",
680 		       config_item_name(&nt->group.cg_item));
681 		ret = -EINVAL;
682 		goto out_unlock;
683 	}
684 
685 	ret = kstrtobool(buf, &extended);
686 	if (ret)
687 		goto out_unlock;
688 
689 	nt->extended = extended;
690 	ret = strnlen(buf, count);
691 out_unlock:
692 	mutex_unlock(&dynamic_netconsole_mutex);
693 	return ret;
694 }
695 
dev_name_store(struct config_item * item,const char * buf,size_t count)696 static ssize_t dev_name_store(struct config_item *item, const char *buf,
697 		size_t count)
698 {
699 	struct netconsole_target *nt = to_target(item);
700 
701 	mutex_lock(&dynamic_netconsole_mutex);
702 	if (nt->enabled) {
703 		pr_err("target (%s) is enabled, disable to update parameters\n",
704 		       config_item_name(&nt->group.cg_item));
705 		mutex_unlock(&dynamic_netconsole_mutex);
706 		return -EINVAL;
707 	}
708 
709 	strscpy(nt->np.dev_name, buf, IFNAMSIZ);
710 	trim_newline(nt->np.dev_name, IFNAMSIZ);
711 
712 	mutex_unlock(&dynamic_netconsole_mutex);
713 	return strnlen(buf, count);
714 }
715 
local_port_store(struct config_item * item,const char * buf,size_t count)716 static ssize_t local_port_store(struct config_item *item, const char *buf,
717 		size_t count)
718 {
719 	struct netconsole_target *nt = to_target(item);
720 	ssize_t ret = -EINVAL;
721 
722 	mutex_lock(&dynamic_netconsole_mutex);
723 	if (nt->enabled) {
724 		pr_err("target (%s) is enabled, disable to update parameters\n",
725 		       config_item_name(&nt->group.cg_item));
726 		goto out_unlock;
727 	}
728 
729 	ret = kstrtou16(buf, 10, &nt->np.local_port);
730 	if (ret < 0)
731 		goto out_unlock;
732 	ret = strnlen(buf, count);
733 out_unlock:
734 	mutex_unlock(&dynamic_netconsole_mutex);
735 	return ret;
736 }
737 
remote_port_store(struct config_item * item,const char * buf,size_t count)738 static ssize_t remote_port_store(struct config_item *item,
739 		const char *buf, size_t count)
740 {
741 	struct netconsole_target *nt = to_target(item);
742 	ssize_t ret = -EINVAL;
743 
744 	mutex_lock(&dynamic_netconsole_mutex);
745 	if (nt->enabled) {
746 		pr_err("target (%s) is enabled, disable to update parameters\n",
747 		       config_item_name(&nt->group.cg_item));
748 		goto out_unlock;
749 	}
750 
751 	ret = kstrtou16(buf, 10, &nt->np.remote_port);
752 	if (ret < 0)
753 		goto out_unlock;
754 	ret = strnlen(buf, count);
755 out_unlock:
756 	mutex_unlock(&dynamic_netconsole_mutex);
757 	return ret;
758 }
759 
local_ip_store(struct config_item * item,const char * buf,size_t count)760 static ssize_t local_ip_store(struct config_item *item, const char *buf,
761 		size_t count)
762 {
763 	struct netconsole_target *nt = to_target(item);
764 	ssize_t ret = -EINVAL;
765 	int ipv6;
766 
767 	mutex_lock(&dynamic_netconsole_mutex);
768 	if (nt->enabled) {
769 		pr_err("target (%s) is enabled, disable to update parameters\n",
770 		       config_item_name(&nt->group.cg_item));
771 		goto out_unlock;
772 	}
773 
774 	ipv6 = netpoll_parse_ip_addr(buf, &nt->np.local_ip);
775 	if (ipv6 == -1)
776 		goto out_unlock;
777 	nt->np.ipv6 = !!ipv6;
778 
779 	ret = strnlen(buf, count);
780 out_unlock:
781 	mutex_unlock(&dynamic_netconsole_mutex);
782 	return ret;
783 }
784 
remote_ip_store(struct config_item * item,const char * buf,size_t count)785 static ssize_t remote_ip_store(struct config_item *item, const char *buf,
786 	       size_t count)
787 {
788 	struct netconsole_target *nt = to_target(item);
789 	ssize_t ret = -EINVAL;
790 	int ipv6;
791 
792 	mutex_lock(&dynamic_netconsole_mutex);
793 	if (nt->enabled) {
794 		pr_err("target (%s) is enabled, disable to update parameters\n",
795 		       config_item_name(&nt->group.cg_item));
796 		goto out_unlock;
797 	}
798 
799 	ipv6 = netpoll_parse_ip_addr(buf, &nt->np.remote_ip);
800 	if (ipv6 == -1)
801 		goto out_unlock;
802 	nt->np.ipv6 = !!ipv6;
803 
804 	ret = strnlen(buf, count);
805 out_unlock:
806 	mutex_unlock(&dynamic_netconsole_mutex);
807 	return ret;
808 }
809 
810 /* Count number of entries we have in userdata.
811  * This is important because userdata only supports MAX_USERDATA_ITEMS
812  * entries. Before enabling any new userdata feature, number of entries needs
813  * to checked for available space.
814  */
count_userdata_entries(struct netconsole_target * nt)815 static size_t count_userdata_entries(struct netconsole_target *nt)
816 {
817 	return list_count_nodes(&nt->userdata_group.cg_children);
818 }
819 
remote_mac_store(struct config_item * item,const char * buf,size_t count)820 static ssize_t remote_mac_store(struct config_item *item, const char *buf,
821 		size_t count)
822 {
823 	struct netconsole_target *nt = to_target(item);
824 	u8 remote_mac[ETH_ALEN];
825 	ssize_t ret = -EINVAL;
826 
827 	mutex_lock(&dynamic_netconsole_mutex);
828 	if (nt->enabled) {
829 		pr_err("target (%s) is enabled, disable to update parameters\n",
830 		       config_item_name(&nt->group.cg_item));
831 		goto out_unlock;
832 	}
833 
834 	if (!mac_pton(buf, remote_mac))
835 		goto out_unlock;
836 	if (buf[MAC_ADDR_STR_LEN] && buf[MAC_ADDR_STR_LEN] != '\n')
837 		goto out_unlock;
838 	memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
839 
840 	ret = strnlen(buf, count);
841 out_unlock:
842 	mutex_unlock(&dynamic_netconsole_mutex);
843 	return ret;
844 }
845 
846 struct userdatum {
847 	struct config_item item;
848 	char value[MAX_EXTRADATA_VALUE_LEN];
849 };
850 
to_userdatum(struct config_item * item)851 static struct userdatum *to_userdatum(struct config_item *item)
852 {
853 	return container_of(item, struct userdatum, item);
854 }
855 
856 struct userdata {
857 	struct config_group group;
858 };
859 
to_userdata(struct config_item * item)860 static struct userdata *to_userdata(struct config_item *item)
861 {
862 	return container_of(to_config_group(item), struct userdata, group);
863 }
864 
userdata_to_target(struct userdata * ud)865 static struct netconsole_target *userdata_to_target(struct userdata *ud)
866 {
867 	struct config_group *netconsole_group;
868 
869 	netconsole_group = to_config_group(ud->group.cg_item.ci_parent);
870 	return to_target(&netconsole_group->cg_item);
871 }
872 
userdatum_value_show(struct config_item * item,char * buf)873 static ssize_t userdatum_value_show(struct config_item *item, char *buf)
874 {
875 	return sysfs_emit(buf, "%s\n", &(to_userdatum(item)->value[0]));
876 }
877 
878 /* Navigate configfs and calculate the lentgh of the formatted string
879  * representing userdata.
880  * Must be called holding netconsole_subsys.su_mutex
881  */
calc_userdata_len(struct netconsole_target * nt)882 static int calc_userdata_len(struct netconsole_target *nt)
883 {
884 	struct userdatum *udm_item;
885 	struct config_item *item;
886 	struct list_head *entry;
887 	int len = 0;
888 
889 	list_for_each(entry, &nt->userdata_group.cg_children) {
890 		item = container_of(entry, struct config_item, ci_entry);
891 		udm_item = to_userdatum(item);
892 		/* Skip userdata with no value set */
893 		if (udm_item->value[0]) {
894 			len += snprintf(NULL, 0, " %s=%s\n", item->ci_name,
895 					udm_item->value);
896 		}
897 	}
898 	return len;
899 }
900 
update_userdata(struct netconsole_target * nt)901 static int update_userdata(struct netconsole_target *nt)
902 {
903 	struct userdatum *udm_item;
904 	struct config_item *item;
905 	struct list_head *entry;
906 	char *old_buf = NULL;
907 	char *new_buf = NULL;
908 	unsigned long flags;
909 	int offset = 0;
910 	int len;
911 
912 	/* Calculate required buffer size */
913 	len = calc_userdata_len(nt);
914 
915 	if (WARN_ON_ONCE(len > MAX_EXTRADATA_ENTRY_LEN * MAX_USERDATA_ITEMS))
916 		return -ENOSPC;
917 
918 	/* Allocate new buffer */
919 	if (len) {
920 		new_buf = kmalloc(len + 1, GFP_KERNEL);
921 		if (!new_buf)
922 			return -ENOMEM;
923 	}
924 
925 	/* Write userdata to new buffer */
926 	list_for_each(entry, &nt->userdata_group.cg_children) {
927 		item = container_of(entry, struct config_item, ci_entry);
928 		udm_item = to_userdatum(item);
929 		/* Skip userdata with no value set */
930 		if (udm_item->value[0]) {
931 			offset += scnprintf(&new_buf[offset], len + 1 - offset,
932 					    " %s=%s\n", item->ci_name,
933 					    udm_item->value);
934 		}
935 	}
936 
937 	WARN_ON_ONCE(offset != len);
938 
939 	/* Switch to new buffer and free old buffer */
940 	spin_lock_irqsave(&target_list_lock, flags);
941 	old_buf = nt->userdata;
942 	nt->userdata = new_buf;
943 	nt->userdata_length = offset;
944 	spin_unlock_irqrestore(&target_list_lock, flags);
945 
946 	kfree(old_buf);
947 
948 	return 0;
949 }
950 
userdatum_value_store(struct config_item * item,const char * buf,size_t count)951 static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
952 				     size_t count)
953 {
954 	struct userdatum *udm = to_userdatum(item);
955 	struct netconsole_target *nt;
956 	struct userdata *ud;
957 	ssize_t ret;
958 
959 	if (count > MAX_EXTRADATA_VALUE_LEN)
960 		return -EMSGSIZE;
961 
962 	mutex_lock(&netconsole_subsys.su_mutex);
963 	mutex_lock(&dynamic_netconsole_mutex);
964 
965 	ret = strscpy(udm->value, buf, sizeof(udm->value));
966 	if (ret < 0)
967 		goto out_unlock;
968 	trim_newline(udm->value, sizeof(udm->value));
969 
970 	ud = to_userdata(item->ci_parent);
971 	nt = userdata_to_target(ud);
972 	ret = update_userdata(nt);
973 	if (ret < 0)
974 		goto out_unlock;
975 	ret = count;
976 out_unlock:
977 	mutex_unlock(&dynamic_netconsole_mutex);
978 	mutex_unlock(&netconsole_subsys.su_mutex);
979 	return ret;
980 }
981 
982 /* disable_sysdata_feature - Disable sysdata feature and clean sysdata
983  * @nt: target that is disabling the feature
984  * @feature: feature being disabled
985  */
disable_sysdata_feature(struct netconsole_target * nt,enum sysdata_feature feature)986 static void disable_sysdata_feature(struct netconsole_target *nt,
987 				    enum sysdata_feature feature)
988 {
989 	nt->sysdata_fields &= ~feature;
990 	nt->sysdata[0] = 0;
991 }
992 
sysdata_msgid_enabled_store(struct config_item * item,const char * buf,size_t count)993 static ssize_t sysdata_msgid_enabled_store(struct config_item *item,
994 					   const char *buf, size_t count)
995 {
996 	struct netconsole_target *nt = to_target(item->ci_parent);
997 	bool msgid_enabled, curr;
998 	ssize_t ret;
999 
1000 	ret = kstrtobool(buf, &msgid_enabled);
1001 	if (ret)
1002 		return ret;
1003 
1004 	mutex_lock(&netconsole_subsys.su_mutex);
1005 	mutex_lock(&dynamic_netconsole_mutex);
1006 	curr = !!(nt->sysdata_fields & SYSDATA_MSGID);
1007 	if (msgid_enabled == curr)
1008 		goto unlock_ok;
1009 
1010 	if (msgid_enabled)
1011 		nt->sysdata_fields |= SYSDATA_MSGID;
1012 	else
1013 		disable_sysdata_feature(nt, SYSDATA_MSGID);
1014 
1015 unlock_ok:
1016 	ret = strnlen(buf, count);
1017 	mutex_unlock(&dynamic_netconsole_mutex);
1018 	mutex_unlock(&netconsole_subsys.su_mutex);
1019 	return ret;
1020 }
1021 
sysdata_release_enabled_store(struct config_item * item,const char * buf,size_t count)1022 static ssize_t sysdata_release_enabled_store(struct config_item *item,
1023 					     const char *buf, size_t count)
1024 {
1025 	struct netconsole_target *nt = to_target(item->ci_parent);
1026 	bool release_enabled, curr;
1027 	ssize_t ret;
1028 
1029 	ret = kstrtobool(buf, &release_enabled);
1030 	if (ret)
1031 		return ret;
1032 
1033 	mutex_lock(&netconsole_subsys.su_mutex);
1034 	mutex_lock(&dynamic_netconsole_mutex);
1035 	curr = !!(nt->sysdata_fields & SYSDATA_RELEASE);
1036 	if (release_enabled == curr)
1037 		goto unlock_ok;
1038 
1039 	if (release_enabled)
1040 		nt->sysdata_fields |= SYSDATA_RELEASE;
1041 	else
1042 		disable_sysdata_feature(nt, SYSDATA_RELEASE);
1043 
1044 unlock_ok:
1045 	ret = strnlen(buf, count);
1046 	mutex_unlock(&dynamic_netconsole_mutex);
1047 	mutex_unlock(&netconsole_subsys.su_mutex);
1048 	return ret;
1049 }
1050 
sysdata_taskname_enabled_store(struct config_item * item,const char * buf,size_t count)1051 static ssize_t sysdata_taskname_enabled_store(struct config_item *item,
1052 					      const char *buf, size_t count)
1053 {
1054 	struct netconsole_target *nt = to_target(item->ci_parent);
1055 	bool taskname_enabled, curr;
1056 	ssize_t ret;
1057 
1058 	ret = kstrtobool(buf, &taskname_enabled);
1059 	if (ret)
1060 		return ret;
1061 
1062 	mutex_lock(&netconsole_subsys.su_mutex);
1063 	mutex_lock(&dynamic_netconsole_mutex);
1064 	curr = !!(nt->sysdata_fields & SYSDATA_TASKNAME);
1065 	if (taskname_enabled == curr)
1066 		goto unlock_ok;
1067 
1068 	if (taskname_enabled)
1069 		nt->sysdata_fields |= SYSDATA_TASKNAME;
1070 	else
1071 		disable_sysdata_feature(nt, SYSDATA_TASKNAME);
1072 
1073 unlock_ok:
1074 	ret = strnlen(buf, count);
1075 	mutex_unlock(&dynamic_netconsole_mutex);
1076 	mutex_unlock(&netconsole_subsys.su_mutex);
1077 	return ret;
1078 }
1079 
1080 /* configfs helper to sysdata cpu_nr feature */
sysdata_cpu_nr_enabled_store(struct config_item * item,const char * buf,size_t count)1081 static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item,
1082 					    const char *buf, size_t count)
1083 {
1084 	struct netconsole_target *nt = to_target(item->ci_parent);
1085 	bool cpu_nr_enabled, curr;
1086 	ssize_t ret;
1087 
1088 	ret = kstrtobool(buf, &cpu_nr_enabled);
1089 	if (ret)
1090 		return ret;
1091 
1092 	mutex_lock(&netconsole_subsys.su_mutex);
1093 	mutex_lock(&dynamic_netconsole_mutex);
1094 	curr = !!(nt->sysdata_fields & SYSDATA_CPU_NR);
1095 	if (cpu_nr_enabled == curr)
1096 		/* no change requested */
1097 		goto unlock_ok;
1098 
1099 	if (cpu_nr_enabled)
1100 		nt->sysdata_fields |= SYSDATA_CPU_NR;
1101 	else
1102 		/* This is special because sysdata might have remaining data
1103 		 * from previous sysdata, and it needs to be cleaned.
1104 		 */
1105 		disable_sysdata_feature(nt, SYSDATA_CPU_NR);
1106 
1107 unlock_ok:
1108 	ret = strnlen(buf, count);
1109 	mutex_unlock(&dynamic_netconsole_mutex);
1110 	mutex_unlock(&netconsole_subsys.su_mutex);
1111 	return ret;
1112 }
1113 
1114 CONFIGFS_ATTR(userdatum_, value);
1115 CONFIGFS_ATTR(sysdata_, cpu_nr_enabled);
1116 CONFIGFS_ATTR(sysdata_, taskname_enabled);
1117 CONFIGFS_ATTR(sysdata_, release_enabled);
1118 CONFIGFS_ATTR(sysdata_, msgid_enabled);
1119 
1120 static struct configfs_attribute *userdatum_attrs[] = {
1121 	&userdatum_attr_value,
1122 	NULL,
1123 };
1124 
userdatum_release(struct config_item * item)1125 static void userdatum_release(struct config_item *item)
1126 {
1127 	kfree(to_userdatum(item));
1128 }
1129 
1130 static struct configfs_item_operations userdatum_ops = {
1131 	.release = userdatum_release,
1132 };
1133 
1134 static const struct config_item_type userdatum_type = {
1135 	.ct_item_ops	= &userdatum_ops,
1136 	.ct_attrs	= userdatum_attrs,
1137 	.ct_owner	= THIS_MODULE,
1138 };
1139 
userdatum_make_item(struct config_group * group,const char * name)1140 static struct config_item *userdatum_make_item(struct config_group *group,
1141 					       const char *name)
1142 {
1143 	struct netconsole_target *nt;
1144 	struct userdatum *udm;
1145 	struct userdata *ud;
1146 
1147 	if (strlen(name) > MAX_EXTRADATA_NAME_LEN)
1148 		return ERR_PTR(-ENAMETOOLONG);
1149 
1150 	ud = to_userdata(&group->cg_item);
1151 	nt = userdata_to_target(ud);
1152 	if (count_userdata_entries(nt) >= MAX_USERDATA_ITEMS)
1153 		return ERR_PTR(-ENOSPC);
1154 
1155 	udm = kzalloc(sizeof(*udm), GFP_KERNEL);
1156 	if (!udm)
1157 		return ERR_PTR(-ENOMEM);
1158 
1159 	config_item_init_type_name(&udm->item, name, &userdatum_type);
1160 	return &udm->item;
1161 }
1162 
userdatum_drop(struct config_group * group,struct config_item * item)1163 static void userdatum_drop(struct config_group *group, struct config_item *item)
1164 {
1165 	struct netconsole_target *nt;
1166 	struct userdata *ud;
1167 
1168 	ud = to_userdata(&group->cg_item);
1169 	nt = userdata_to_target(ud);
1170 
1171 	mutex_lock(&dynamic_netconsole_mutex);
1172 	update_userdata(nt);
1173 	config_item_put(item);
1174 	mutex_unlock(&dynamic_netconsole_mutex);
1175 }
1176 
1177 static struct configfs_attribute *userdata_attrs[] = {
1178 	&sysdata_attr_cpu_nr_enabled,
1179 	&sysdata_attr_taskname_enabled,
1180 	&sysdata_attr_release_enabled,
1181 	&sysdata_attr_msgid_enabled,
1182 	NULL,
1183 };
1184 
1185 static struct configfs_group_operations userdata_ops = {
1186 	.make_item		= userdatum_make_item,
1187 	.drop_item		= userdatum_drop,
1188 };
1189 
1190 static const struct config_item_type userdata_type = {
1191 	.ct_item_ops	= &userdatum_ops,
1192 	.ct_group_ops	= &userdata_ops,
1193 	.ct_attrs	= userdata_attrs,
1194 	.ct_owner	= THIS_MODULE,
1195 };
1196 
1197 CONFIGFS_ATTR(, enabled);
1198 CONFIGFS_ATTR(, extended);
1199 CONFIGFS_ATTR(, dev_name);
1200 CONFIGFS_ATTR(, local_port);
1201 CONFIGFS_ATTR(, remote_port);
1202 CONFIGFS_ATTR(, local_ip);
1203 CONFIGFS_ATTR(, remote_ip);
1204 CONFIGFS_ATTR_RO(, local_mac);
1205 CONFIGFS_ATTR(, remote_mac);
1206 CONFIGFS_ATTR(, release);
1207 CONFIGFS_ATTR_RO(, transmit_errors);
1208 
1209 static struct configfs_attribute *netconsole_target_attrs[] = {
1210 	&attr_enabled,
1211 	&attr_extended,
1212 	&attr_release,
1213 	&attr_dev_name,
1214 	&attr_local_port,
1215 	&attr_remote_port,
1216 	&attr_local_ip,
1217 	&attr_remote_ip,
1218 	&attr_local_mac,
1219 	&attr_remote_mac,
1220 	&attr_transmit_errors,
1221 	NULL,
1222 };
1223 
1224 /*
1225  * Item operations and type for netconsole_target.
1226  */
1227 
netconsole_target_release(struct config_item * item)1228 static void netconsole_target_release(struct config_item *item)
1229 {
1230 	struct netconsole_target *nt = to_target(item);
1231 
1232 	kfree(nt->userdata);
1233 	kfree(nt);
1234 }
1235 
1236 static struct configfs_item_operations netconsole_target_item_ops = {
1237 	.release		= netconsole_target_release,
1238 };
1239 
1240 static const struct config_item_type netconsole_target_type = {
1241 	.ct_attrs		= netconsole_target_attrs,
1242 	.ct_item_ops		= &netconsole_target_item_ops,
1243 	.ct_owner		= THIS_MODULE,
1244 };
1245 
init_target_config_group(struct netconsole_target * nt,const char * name)1246 static void init_target_config_group(struct netconsole_target *nt,
1247 				     const char *name)
1248 {
1249 	config_group_init_type_name(&nt->group, name, &netconsole_target_type);
1250 	config_group_init_type_name(&nt->userdata_group, "userdata",
1251 				    &userdata_type);
1252 	configfs_add_default_group(&nt->userdata_group, &nt->group);
1253 }
1254 
find_cmdline_target(const char * name)1255 static struct netconsole_target *find_cmdline_target(const char *name)
1256 {
1257 	struct netconsole_target *nt, *ret = NULL;
1258 	unsigned long flags;
1259 
1260 	spin_lock_irqsave(&target_list_lock, flags);
1261 	list_for_each_entry(nt, &target_list, list) {
1262 		if (!strcmp(nt->group.cg_item.ci_name, name)) {
1263 			ret = nt;
1264 			break;
1265 		}
1266 	}
1267 	spin_unlock_irqrestore(&target_list_lock, flags);
1268 
1269 	return ret;
1270 }
1271 
1272 /*
1273  * Group operations and type for netconsole_subsys.
1274  */
1275 
make_netconsole_target(struct config_group * group,const char * name)1276 static struct config_group *make_netconsole_target(struct config_group *group,
1277 						   const char *name)
1278 {
1279 	struct netconsole_target *nt;
1280 	unsigned long flags;
1281 
1282 	/* Checking if a target by this name was created at boot time.  If so,
1283 	 * attach a configfs entry to that target.  This enables dynamic
1284 	 * control.
1285 	 */
1286 	if (!strncmp(name, NETCONSOLE_PARAM_TARGET_PREFIX,
1287 		     strlen(NETCONSOLE_PARAM_TARGET_PREFIX))) {
1288 		nt = find_cmdline_target(name);
1289 		if (nt) {
1290 			init_target_config_group(nt, name);
1291 			return &nt->group;
1292 		}
1293 	}
1294 
1295 	nt = alloc_and_init();
1296 	if (!nt)
1297 		return ERR_PTR(-ENOMEM);
1298 
1299 	/* Initialize the config_group member */
1300 	init_target_config_group(nt, name);
1301 
1302 	/* Adding, but it is disabled */
1303 	spin_lock_irqsave(&target_list_lock, flags);
1304 	list_add(&nt->list, &target_list);
1305 	spin_unlock_irqrestore(&target_list_lock, flags);
1306 
1307 	return &nt->group;
1308 }
1309 
drop_netconsole_target(struct config_group * group,struct config_item * item)1310 static void drop_netconsole_target(struct config_group *group,
1311 				   struct config_item *item)
1312 {
1313 	unsigned long flags;
1314 	struct netconsole_target *nt = to_target(item);
1315 
1316 	spin_lock_irqsave(&target_list_lock, flags);
1317 	list_del(&nt->list);
1318 	spin_unlock_irqrestore(&target_list_lock, flags);
1319 
1320 	/*
1321 	 * The target may have never been enabled, or was manually disabled
1322 	 * before being removed so netpoll may have already been cleaned up.
1323 	 */
1324 	if (nt->enabled)
1325 		netpoll_cleanup(&nt->np);
1326 
1327 	config_item_put(&nt->group.cg_item);
1328 }
1329 
1330 static struct configfs_group_operations netconsole_subsys_group_ops = {
1331 	.make_group	= make_netconsole_target,
1332 	.drop_item	= drop_netconsole_target,
1333 };
1334 
1335 static const struct config_item_type netconsole_subsys_type = {
1336 	.ct_group_ops	= &netconsole_subsys_group_ops,
1337 	.ct_owner	= THIS_MODULE,
1338 };
1339 
1340 /* The netconsole configfs subsystem */
1341 static struct configfs_subsystem netconsole_subsys = {
1342 	.su_group	= {
1343 		.cg_item	= {
1344 			.ci_namebuf	= "netconsole",
1345 			.ci_type	= &netconsole_subsys_type,
1346 		},
1347 	},
1348 };
1349 
populate_configfs_item(struct netconsole_target * nt,int cmdline_count)1350 static void populate_configfs_item(struct netconsole_target *nt,
1351 				   int cmdline_count)
1352 {
1353 	char target_name[16];
1354 
1355 	snprintf(target_name, sizeof(target_name), "%s%d",
1356 		 NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);
1357 	init_target_config_group(nt, target_name);
1358 }
1359 
sysdata_append_cpu_nr(struct netconsole_target * nt,int offset)1360 static int sysdata_append_cpu_nr(struct netconsole_target *nt, int offset)
1361 {
1362 	return scnprintf(&nt->sysdata[offset],
1363 			 MAX_EXTRADATA_ENTRY_LEN, " cpu=%u\n",
1364 			 raw_smp_processor_id());
1365 }
1366 
sysdata_append_taskname(struct netconsole_target * nt,int offset)1367 static int sysdata_append_taskname(struct netconsole_target *nt, int offset)
1368 {
1369 	return scnprintf(&nt->sysdata[offset],
1370 			 MAX_EXTRADATA_ENTRY_LEN, " taskname=%s\n",
1371 			 current->comm);
1372 }
1373 
sysdata_append_release(struct netconsole_target * nt,int offset)1374 static int sysdata_append_release(struct netconsole_target *nt, int offset)
1375 {
1376 	return scnprintf(&nt->sysdata[offset],
1377 			 MAX_EXTRADATA_ENTRY_LEN, " release=%s\n",
1378 			 init_utsname()->release);
1379 }
1380 
sysdata_append_msgid(struct netconsole_target * nt,int offset)1381 static int sysdata_append_msgid(struct netconsole_target *nt, int offset)
1382 {
1383 	wrapping_assign_add(nt->msgcounter, 1);
1384 	return scnprintf(&nt->sysdata[offset],
1385 			 MAX_EXTRADATA_ENTRY_LEN, " msgid=%u\n",
1386 			 nt->msgcounter);
1387 }
1388 
1389 /*
1390  * prepare_sysdata - append sysdata in runtime
1391  * @nt: target to send message to
1392  */
prepare_sysdata(struct netconsole_target * nt)1393 static int prepare_sysdata(struct netconsole_target *nt)
1394 {
1395 	int sysdata_len = 0;
1396 
1397 	if (!nt->sysdata_fields)
1398 		goto out;
1399 
1400 	if (nt->sysdata_fields & SYSDATA_CPU_NR)
1401 		sysdata_len += sysdata_append_cpu_nr(nt, sysdata_len);
1402 	if (nt->sysdata_fields & SYSDATA_TASKNAME)
1403 		sysdata_len += sysdata_append_taskname(nt, sysdata_len);
1404 	if (nt->sysdata_fields & SYSDATA_RELEASE)
1405 		sysdata_len += sysdata_append_release(nt, sysdata_len);
1406 	if (nt->sysdata_fields & SYSDATA_MSGID)
1407 		sysdata_len += sysdata_append_msgid(nt, sysdata_len);
1408 
1409 	WARN_ON_ONCE(sysdata_len >
1410 		     MAX_EXTRADATA_ENTRY_LEN * MAX_SYSDATA_ITEMS);
1411 
1412 out:
1413 	return sysdata_len;
1414 }
1415 #endif	/* CONFIG_NETCONSOLE_DYNAMIC */
1416 
1417 /* Handle network interface device notifications */
netconsole_netdev_event(struct notifier_block * this,unsigned long event,void * ptr)1418 static int netconsole_netdev_event(struct notifier_block *this,
1419 				   unsigned long event, void *ptr)
1420 {
1421 	unsigned long flags;
1422 	struct netconsole_target *nt, *tmp;
1423 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1424 	bool stopped = false;
1425 
1426 	if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER ||
1427 	      event == NETDEV_RELEASE || event == NETDEV_JOIN))
1428 		goto done;
1429 
1430 	mutex_lock(&target_cleanup_list_lock);
1431 	spin_lock_irqsave(&target_list_lock, flags);
1432 	list_for_each_entry_safe(nt, tmp, &target_list, list) {
1433 		netconsole_target_get(nt);
1434 		if (nt->np.dev == dev) {
1435 			switch (event) {
1436 			case NETDEV_CHANGENAME:
1437 				strscpy(nt->np.dev_name, dev->name, IFNAMSIZ);
1438 				break;
1439 			case NETDEV_RELEASE:
1440 			case NETDEV_JOIN:
1441 			case NETDEV_UNREGISTER:
1442 				nt->enabled = false;
1443 				list_move(&nt->list, &target_cleanup_list);
1444 				stopped = true;
1445 			}
1446 		}
1447 		netconsole_target_put(nt);
1448 	}
1449 	spin_unlock_irqrestore(&target_list_lock, flags);
1450 	mutex_unlock(&target_cleanup_list_lock);
1451 
1452 	if (stopped) {
1453 		const char *msg = "had an event";
1454 
1455 		switch (event) {
1456 		case NETDEV_UNREGISTER:
1457 			msg = "unregistered";
1458 			break;
1459 		case NETDEV_RELEASE:
1460 			msg = "released slaves";
1461 			break;
1462 		case NETDEV_JOIN:
1463 			msg = "is joining a master device";
1464 			break;
1465 		}
1466 		pr_info("network logging stopped on interface %s as it %s\n",
1467 			dev->name, msg);
1468 	}
1469 
1470 	/* Process target_cleanup_list entries. By the end, target_cleanup_list
1471 	 * should be empty
1472 	 */
1473 	netconsole_process_cleanups_core();
1474 
1475 done:
1476 	return NOTIFY_DONE;
1477 }
1478 
1479 static struct notifier_block netconsole_netdev_notifier = {
1480 	.notifier_call  = netconsole_netdev_event,
1481 };
1482 
1483 /**
1484  * send_udp - Wrapper for netpoll_send_udp that counts errors
1485  * @nt: target to send message to
1486  * @msg: message to send
1487  * @len: length of message
1488  *
1489  * Calls netpoll_send_udp and classifies the return value. If an error
1490  * occurred it increments statistics in nt->stats accordingly.
1491  * Only calls netpoll_send_udp if CONFIG_NETCONSOLE_DYNAMIC is disabled.
1492  */
send_udp(struct netconsole_target * nt,const char * msg,int len)1493 static void send_udp(struct netconsole_target *nt, const char *msg, int len)
1494 {
1495 	int result = netpoll_send_udp(&nt->np, msg, len);
1496 
1497 	if (IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC)) {
1498 		if (result == NET_XMIT_DROP) {
1499 			u64_stats_update_begin(&nt->stats.syncp);
1500 			u64_stats_inc(&nt->stats.xmit_drop_count);
1501 			u64_stats_update_end(&nt->stats.syncp);
1502 		} else if (result == -ENOMEM) {
1503 			u64_stats_update_begin(&nt->stats.syncp);
1504 			u64_stats_inc(&nt->stats.enomem_count);
1505 			u64_stats_update_end(&nt->stats.syncp);
1506 		}
1507 	}
1508 }
1509 
send_msg_no_fragmentation(struct netconsole_target * nt,const char * msg,int msg_len,int release_len)1510 static void send_msg_no_fragmentation(struct netconsole_target *nt,
1511 				      const char *msg,
1512 				      int msg_len,
1513 				      int release_len)
1514 {
1515 	const char *userdata = NULL;
1516 	const char *sysdata = NULL;
1517 	const char *release;
1518 
1519 #ifdef CONFIG_NETCONSOLE_DYNAMIC
1520 	userdata = nt->userdata;
1521 	sysdata = nt->sysdata;
1522 #endif
1523 
1524 	if (release_len) {
1525 		release = init_utsname()->release;
1526 
1527 		scnprintf(nt->buf, MAX_PRINT_CHUNK, "%s,%s", release, msg);
1528 		msg_len += release_len;
1529 	} else {
1530 		memcpy(nt->buf, msg, msg_len);
1531 	}
1532 
1533 	if (userdata)
1534 		msg_len += scnprintf(&nt->buf[msg_len],
1535 				     MAX_PRINT_CHUNK - msg_len, "%s",
1536 				     userdata);
1537 
1538 	if (sysdata)
1539 		msg_len += scnprintf(&nt->buf[msg_len],
1540 				     MAX_PRINT_CHUNK - msg_len, "%s",
1541 				     sysdata);
1542 
1543 	send_udp(nt, nt->buf, msg_len);
1544 }
1545 
append_release(char * buf)1546 static void append_release(char *buf)
1547 {
1548 	const char *release;
1549 
1550 	release = init_utsname()->release;
1551 	scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
1552 }
1553 
send_fragmented_body(struct netconsole_target * nt,const char * msgbody_ptr,int header_len,int msgbody_len,int sysdata_len)1554 static void send_fragmented_body(struct netconsole_target *nt,
1555 				 const char *msgbody_ptr, int header_len,
1556 				 int msgbody_len, int sysdata_len)
1557 {
1558 	const char *userdata_ptr = NULL;
1559 	const char *sysdata_ptr = NULL;
1560 	int data_len, data_sent = 0;
1561 	int userdata_offset = 0;
1562 	int sysdata_offset = 0;
1563 	int msgbody_offset = 0;
1564 	int userdata_len = 0;
1565 
1566 #ifdef CONFIG_NETCONSOLE_DYNAMIC
1567 	userdata_ptr = nt->userdata;
1568 	sysdata_ptr = nt->sysdata;
1569 	userdata_len = nt->userdata_length;
1570 #endif
1571 	if (WARN_ON_ONCE(!userdata_ptr && userdata_len != 0))
1572 		return;
1573 
1574 	if (WARN_ON_ONCE(!sysdata_ptr && sysdata_len != 0))
1575 		return;
1576 
1577 	/* data_len represents the number of bytes that will be sent. This is
1578 	 * bigger than MAX_PRINT_CHUNK, thus, it will be split in multiple
1579 	 * packets
1580 	 */
1581 	data_len = msgbody_len + userdata_len + sysdata_len;
1582 
1583 	/* In each iteration of the while loop below, we send a packet
1584 	 * containing the header and a portion of the data. The data is
1585 	 * composed of three parts: msgbody, userdata, and sysdata.
1586 	 * We keep track of how many bytes have been sent from each part using
1587 	 * the *_offset variables.
1588 	 * We keep track of how many bytes have been sent overall using the
1589 	 * data_sent variable, which ranges from 0 to the total bytes to be
1590 	 * sent.
1591 	 */
1592 	while (data_sent < data_len) {
1593 		int userdata_left = userdata_len - userdata_offset;
1594 		int sysdata_left = sysdata_len - sysdata_offset;
1595 		int msgbody_left = msgbody_len - msgbody_offset;
1596 		int buf_offset = 0;
1597 		int this_chunk = 0;
1598 
1599 		/* header is already populated in nt->buf, just append to it */
1600 		buf_offset = header_len;
1601 
1602 		buf_offset += scnprintf(nt->buf + buf_offset,
1603 					 MAX_PRINT_CHUNK - buf_offset,
1604 					 ",ncfrag=%d/%d;", data_sent,
1605 					 data_len);
1606 
1607 		/* append msgbody first */
1608 		this_chunk = min(msgbody_left, MAX_PRINT_CHUNK - buf_offset);
1609 		memcpy(nt->buf + buf_offset, msgbody_ptr + msgbody_offset,
1610 		       this_chunk);
1611 		msgbody_offset += this_chunk;
1612 		buf_offset += this_chunk;
1613 		data_sent += this_chunk;
1614 
1615 		/* after msgbody, append userdata */
1616 		if (userdata_ptr && userdata_left) {
1617 			this_chunk = min(userdata_left,
1618 					 MAX_PRINT_CHUNK - buf_offset);
1619 			memcpy(nt->buf + buf_offset,
1620 			       userdata_ptr + userdata_offset, this_chunk);
1621 			userdata_offset += this_chunk;
1622 			buf_offset += this_chunk;
1623 			data_sent += this_chunk;
1624 		}
1625 
1626 		/* after userdata, append sysdata */
1627 		if (sysdata_ptr && sysdata_left) {
1628 			this_chunk = min(sysdata_left,
1629 					 MAX_PRINT_CHUNK - buf_offset);
1630 			memcpy(nt->buf + buf_offset,
1631 			       sysdata_ptr + sysdata_offset, this_chunk);
1632 			sysdata_offset += this_chunk;
1633 			buf_offset += this_chunk;
1634 			data_sent += this_chunk;
1635 		}
1636 
1637 		/* if all is good, send the packet out */
1638 		if (WARN_ON_ONCE(data_sent > data_len))
1639 			return;
1640 
1641 		send_udp(nt, nt->buf, buf_offset);
1642 	}
1643 }
1644 
send_msg_fragmented(struct netconsole_target * nt,const char * msg,int msg_len,int release_len,int sysdata_len)1645 static void send_msg_fragmented(struct netconsole_target *nt,
1646 				const char *msg,
1647 				int msg_len,
1648 				int release_len,
1649 				int sysdata_len)
1650 {
1651 	int header_len, msgbody_len;
1652 	const char *msgbody;
1653 
1654 	/* need to insert extra header fields, detect header and msgbody */
1655 	msgbody = memchr(msg, ';', msg_len);
1656 	if (WARN_ON_ONCE(!msgbody))
1657 		return;
1658 
1659 	header_len = msgbody - msg;
1660 	msgbody_len = msg_len - header_len - 1;
1661 	msgbody++;
1662 
1663 	/*
1664 	 * Transfer multiple chunks with the following extra header.
1665 	 * "ncfrag=<byte-offset>/<total-bytes>"
1666 	 */
1667 	if (release_len)
1668 		append_release(nt->buf);
1669 
1670 	/* Copy the header into the buffer */
1671 	memcpy(nt->buf + release_len, msg, header_len);
1672 	header_len += release_len;
1673 
1674 	/* for now on, the header will be persisted, and the msgbody
1675 	 * will be replaced
1676 	 */
1677 	send_fragmented_body(nt, msgbody, header_len, msgbody_len,
1678 			     sysdata_len);
1679 }
1680 
1681 /**
1682  * send_ext_msg_udp - send extended log message to target
1683  * @nt: target to send message to
1684  * @msg: extended log message to send
1685  * @msg_len: length of message
1686  *
1687  * Transfer extended log @msg to @nt.  If @msg is longer than
1688  * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
1689  * ncfrag header field added to identify them.
1690  */
send_ext_msg_udp(struct netconsole_target * nt,const char * msg,int msg_len)1691 static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
1692 			     int msg_len)
1693 {
1694 	int userdata_len = 0;
1695 	int release_len = 0;
1696 	int sysdata_len = 0;
1697 
1698 #ifdef CONFIG_NETCONSOLE_DYNAMIC
1699 	sysdata_len = prepare_sysdata(nt);
1700 	userdata_len = nt->userdata_length;
1701 #endif
1702 	if (nt->release)
1703 		release_len = strlen(init_utsname()->release) + 1;
1704 
1705 	if (msg_len + release_len + sysdata_len + userdata_len <= MAX_PRINT_CHUNK)
1706 		return send_msg_no_fragmentation(nt, msg, msg_len, release_len);
1707 
1708 	return send_msg_fragmented(nt, msg, msg_len, release_len,
1709 				   sysdata_len);
1710 }
1711 
write_ext_msg(struct console * con,const char * msg,unsigned int len)1712 static void write_ext_msg(struct console *con, const char *msg,
1713 			  unsigned int len)
1714 {
1715 	struct netconsole_target *nt;
1716 	unsigned long flags;
1717 
1718 	if ((oops_only && !oops_in_progress) || list_empty(&target_list))
1719 		return;
1720 
1721 	spin_lock_irqsave(&target_list_lock, flags);
1722 	list_for_each_entry(nt, &target_list, list)
1723 		if (nt->extended && nt->enabled && netif_running(nt->np.dev))
1724 			send_ext_msg_udp(nt, msg, len);
1725 	spin_unlock_irqrestore(&target_list_lock, flags);
1726 }
1727 
write_msg(struct console * con,const char * msg,unsigned int len)1728 static void write_msg(struct console *con, const char *msg, unsigned int len)
1729 {
1730 	int frag, left;
1731 	unsigned long flags;
1732 	struct netconsole_target *nt;
1733 	const char *tmp;
1734 
1735 	if (oops_only && !oops_in_progress)
1736 		return;
1737 	/* Avoid taking lock and disabling interrupts unnecessarily */
1738 	if (list_empty(&target_list))
1739 		return;
1740 
1741 	spin_lock_irqsave(&target_list_lock, flags);
1742 	list_for_each_entry(nt, &target_list, list) {
1743 		if (!nt->extended && nt->enabled && netif_running(nt->np.dev)) {
1744 			/*
1745 			 * We nest this inside the for-each-target loop above
1746 			 * so that we're able to get as much logging out to
1747 			 * at least one target if we die inside here, instead
1748 			 * of unnecessarily keeping all targets in lock-step.
1749 			 */
1750 			tmp = msg;
1751 			for (left = len; left;) {
1752 				frag = min(left, MAX_PRINT_CHUNK);
1753 				send_udp(nt, tmp, frag);
1754 				tmp += frag;
1755 				left -= frag;
1756 			}
1757 		}
1758 	}
1759 	spin_unlock_irqrestore(&target_list_lock, flags);
1760 }
1761 
netconsole_parser_cmdline(struct netpoll * np,char * opt)1762 static int netconsole_parser_cmdline(struct netpoll *np, char *opt)
1763 {
1764 	bool ipversion_set = false;
1765 	char *cur = opt;
1766 	char *delim;
1767 	int ipv6;
1768 
1769 	if (*cur != '@') {
1770 		delim = strchr(cur, '@');
1771 		if (!delim)
1772 			goto parse_failed;
1773 		*delim = 0;
1774 		if (kstrtou16(cur, 10, &np->local_port))
1775 			goto parse_failed;
1776 		cur = delim;
1777 	}
1778 	cur++;
1779 
1780 	if (*cur != '/') {
1781 		ipversion_set = true;
1782 		delim = strchr(cur, '/');
1783 		if (!delim)
1784 			goto parse_failed;
1785 		*delim = 0;
1786 		ipv6 = netpoll_parse_ip_addr(cur, &np->local_ip);
1787 		if (ipv6 < 0)
1788 			goto parse_failed;
1789 		else
1790 			np->ipv6 = (bool)ipv6;
1791 		cur = delim;
1792 	}
1793 	cur++;
1794 
1795 	if (*cur != ',') {
1796 		/* parse out dev_name or dev_mac */
1797 		delim = strchr(cur, ',');
1798 		if (!delim)
1799 			goto parse_failed;
1800 		*delim = 0;
1801 
1802 		np->dev_name[0] = '\0';
1803 		eth_broadcast_addr(np->dev_mac);
1804 		if (!strchr(cur, ':'))
1805 			strscpy(np->dev_name, cur, sizeof(np->dev_name));
1806 		else if (!mac_pton(cur, np->dev_mac))
1807 			goto parse_failed;
1808 
1809 		cur = delim;
1810 	}
1811 	cur++;
1812 
1813 	if (*cur != '@') {
1814 		/* dst port */
1815 		delim = strchr(cur, '@');
1816 		if (!delim)
1817 			goto parse_failed;
1818 		*delim = 0;
1819 		if (*cur == ' ' || *cur == '\t')
1820 			np_info(np, "warning: whitespace is not allowed\n");
1821 		if (kstrtou16(cur, 10, &np->remote_port))
1822 			goto parse_failed;
1823 		cur = delim;
1824 	}
1825 	cur++;
1826 
1827 	/* dst ip */
1828 	delim = strchr(cur, '/');
1829 	if (!delim)
1830 		goto parse_failed;
1831 	*delim = 0;
1832 	ipv6 = netpoll_parse_ip_addr(cur, &np->remote_ip);
1833 	if (ipv6 < 0)
1834 		goto parse_failed;
1835 	else if (ipversion_set && np->ipv6 != (bool)ipv6)
1836 		goto parse_failed;
1837 	else
1838 		np->ipv6 = (bool)ipv6;
1839 	cur = delim + 1;
1840 
1841 	if (*cur != 0) {
1842 		/* MAC address */
1843 		if (!mac_pton(cur, np->remote_mac))
1844 			goto parse_failed;
1845 	}
1846 
1847 	netconsole_print_banner(np);
1848 
1849 	return 0;
1850 
1851  parse_failed:
1852 	np_info(np, "couldn't parse config at '%s'!\n", cur);
1853 	return -1;
1854 }
1855 
1856 /* Allocate new target (from boot/module param) and setup netpoll for it */
alloc_param_target(char * target_config,int cmdline_count)1857 static struct netconsole_target *alloc_param_target(char *target_config,
1858 						    int cmdline_count)
1859 {
1860 	struct netconsole_target *nt;
1861 	int err;
1862 
1863 	nt = alloc_and_init();
1864 	if (!nt) {
1865 		err = -ENOMEM;
1866 		goto fail;
1867 	}
1868 
1869 	if (*target_config == '+') {
1870 		nt->extended = true;
1871 		target_config++;
1872 	}
1873 
1874 	if (*target_config == 'r') {
1875 		if (!nt->extended) {
1876 			pr_err("Netconsole configuration error. Release feature requires extended log message");
1877 			err = -EINVAL;
1878 			goto fail;
1879 		}
1880 		nt->release = true;
1881 		target_config++;
1882 	}
1883 
1884 	/* Parse parameters and setup netpoll */
1885 	err = netconsole_parser_cmdline(&nt->np, target_config);
1886 	if (err)
1887 		goto fail;
1888 
1889 	err = netpoll_setup(&nt->np);
1890 	if (err) {
1891 		pr_err("Not enabling netconsole for %s%d. Netpoll setup failed\n",
1892 		       NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);
1893 		if (!IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC))
1894 			/* only fail if dynamic reconfiguration is set,
1895 			 * otherwise, keep the target in the list, but disabled.
1896 			 */
1897 			goto fail;
1898 	} else {
1899 		nt->enabled = true;
1900 	}
1901 	populate_configfs_item(nt, cmdline_count);
1902 
1903 	return nt;
1904 
1905 fail:
1906 	kfree(nt);
1907 	return ERR_PTR(err);
1908 }
1909 
1910 /* Cleanup netpoll for given target (from boot/module param) and free it */
free_param_target(struct netconsole_target * nt)1911 static void free_param_target(struct netconsole_target *nt)
1912 {
1913 	netpoll_cleanup(&nt->np);
1914 #ifdef	CONFIG_NETCONSOLE_DYNAMIC
1915 	kfree(nt->userdata);
1916 #endif
1917 	kfree(nt);
1918 }
1919 
1920 static struct console netconsole_ext = {
1921 	.name	= "netcon_ext",
1922 	.flags	= CON_ENABLED | CON_EXTENDED,
1923 	.write	= write_ext_msg,
1924 };
1925 
1926 static struct console netconsole = {
1927 	.name	= "netcon",
1928 	.flags	= CON_ENABLED,
1929 	.write	= write_msg,
1930 };
1931 
init_netconsole(void)1932 static int __init init_netconsole(void)
1933 {
1934 	int err;
1935 	struct netconsole_target *nt, *tmp;
1936 	u32 console_type_needed = 0;
1937 	unsigned int count = 0;
1938 	unsigned long flags;
1939 	char *target_config;
1940 	char *input = config;
1941 
1942 	if (strnlen(input, MAX_PARAM_LENGTH)) {
1943 		while ((target_config = strsep(&input, ";"))) {
1944 			nt = alloc_param_target(target_config, count);
1945 			if (IS_ERR(nt)) {
1946 				if (IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC))
1947 					continue;
1948 				err = PTR_ERR(nt);
1949 				goto fail;
1950 			}
1951 			/* Dump existing printks when we register */
1952 			if (nt->extended) {
1953 				console_type_needed |= CONS_EXTENDED;
1954 				netconsole_ext.flags |= CON_PRINTBUFFER;
1955 			} else {
1956 				console_type_needed |= CONS_BASIC;
1957 				netconsole.flags |= CON_PRINTBUFFER;
1958 			}
1959 
1960 			spin_lock_irqsave(&target_list_lock, flags);
1961 			list_add(&nt->list, &target_list);
1962 			spin_unlock_irqrestore(&target_list_lock, flags);
1963 			count++;
1964 		}
1965 	}
1966 
1967 	err = register_netdevice_notifier(&netconsole_netdev_notifier);
1968 	if (err)
1969 		goto fail;
1970 
1971 	err = dynamic_netconsole_init();
1972 	if (err)
1973 		goto undonotifier;
1974 
1975 	if (console_type_needed & CONS_EXTENDED)
1976 		register_console(&netconsole_ext);
1977 	if (console_type_needed & CONS_BASIC)
1978 		register_console(&netconsole);
1979 	pr_info("network logging started\n");
1980 
1981 	return err;
1982 
1983 undonotifier:
1984 	unregister_netdevice_notifier(&netconsole_netdev_notifier);
1985 
1986 fail:
1987 	pr_err("cleaning up\n");
1988 
1989 	/*
1990 	 * Remove all targets and destroy them (only targets created
1991 	 * from the boot/module option exist here). Skipping the list
1992 	 * lock is safe here, and netpoll_cleanup() will sleep.
1993 	 */
1994 	list_for_each_entry_safe(nt, tmp, &target_list, list) {
1995 		list_del(&nt->list);
1996 		free_param_target(nt);
1997 	}
1998 
1999 	return err;
2000 }
2001 
cleanup_netconsole(void)2002 static void __exit cleanup_netconsole(void)
2003 {
2004 	struct netconsole_target *nt, *tmp;
2005 
2006 	if (console_is_registered(&netconsole_ext))
2007 		unregister_console(&netconsole_ext);
2008 	if (console_is_registered(&netconsole))
2009 		unregister_console(&netconsole);
2010 	dynamic_netconsole_exit();
2011 	unregister_netdevice_notifier(&netconsole_netdev_notifier);
2012 
2013 	/*
2014 	 * Targets created via configfs pin references on our module
2015 	 * and would first be rmdir(2)'ed from userspace. We reach
2016 	 * here only when they are already destroyed, and only those
2017 	 * created from the boot/module option are left, so remove and
2018 	 * destroy them. Skipping the list lock is safe here, and
2019 	 * netpoll_cleanup() will sleep.
2020 	 */
2021 	list_for_each_entry_safe(nt, tmp, &target_list, list) {
2022 		list_del(&nt->list);
2023 		free_param_target(nt);
2024 	}
2025 }
2026 
2027 /*
2028  * Use late_initcall to ensure netconsole is
2029  * initialized after network device driver if built-in.
2030  *
2031  * late_initcall() and module_init() are identical if built as module.
2032  */
2033 late_initcall(init_netconsole);
2034 module_exit(cleanup_netconsole);
2035