xref: /linux/drivers/net/netconsole.c (revision d1e879ec600f9b3bdd253167533959facfefb17b)
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_EXTRADATA_ITEMS		16
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
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 extended netconsoles.  Registered on the first use to
90  * avoid unnecessarily enabling ext message formatting.
91  */
92 static struct console netconsole_ext;
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 /* Features enabled in sysdata. Contrary to userdata, this data is populated by
101  * the kernel. The fields are designed as bitwise flags, allowing multiple
102  * features to be set in sysdata_fields.
103  */
104 enum sysdata_feature {
105 	/* Populate the CPU that sends the message */
106 	SYSDATA_CPU_NR = BIT(0),
107 	/* Populate the task name (as in current->comm) in sysdata */
108 	SYSDATA_TASKNAME = BIT(1),
109 };
110 
111 /**
112  * struct netconsole_target - Represents a configured netconsole target.
113  * @list:	Links this target into the target_list.
114  * @group:	Links us into the configfs subsystem hierarchy.
115  * @userdata_group:	Links to the userdata configfs hierarchy
116  * @extradata_complete:	Cached, formatted string of append
117  * @userdata_length:	String length of usedata in extradata_complete.
118  * @sysdata_fields:	Sysdata features enabled.
119  * @stats:	Packet send stats for the target. Used for debugging.
120  * @enabled:	On / off knob to enable / disable target.
121  *		Visible from userspace (read-write).
122  *		We maintain a strict 1:1 correspondence between this and
123  *		whether the corresponding netpoll is active or inactive.
124  *		Also, other parameters of a target may be modified at
125  *		runtime only when it is disabled (enabled == 0).
126  * @extended:	Denotes whether console is extended or not.
127  * @release:	Denotes whether kernel release version should be prepended
128  *		to the message. Depends on extended console.
129  * @np:		The netpoll structure for this target.
130  *		Contains the other userspace visible parameters:
131  *		dev_name	(read-write)
132  *		local_port	(read-write)
133  *		remote_port	(read-write)
134  *		local_ip	(read-write)
135  *		remote_ip	(read-write)
136  *		local_mac	(read-only)
137  *		remote_mac	(read-write)
138  * @buf:	The buffer used to send the full msg to the network stack
139  */
140 struct netconsole_target {
141 	struct list_head	list;
142 #ifdef	CONFIG_NETCONSOLE_DYNAMIC
143 	struct config_group	group;
144 	struct config_group	userdata_group;
145 	char extradata_complete[MAX_EXTRADATA_ENTRY_LEN * MAX_EXTRADATA_ITEMS];
146 	size_t			userdata_length;
147 	/* bit-wise with sysdata_feature bits */
148 	u32			sysdata_fields;
149 #endif
150 	struct netconsole_target_stats stats;
151 	bool			enabled;
152 	bool			extended;
153 	bool			release;
154 	struct netpoll		np;
155 	/* protected by target_list_lock */
156 	char			buf[MAX_PRINT_CHUNK];
157 };
158 
159 #ifdef	CONFIG_NETCONSOLE_DYNAMIC
160 
161 static struct configfs_subsystem netconsole_subsys;
162 static DEFINE_MUTEX(dynamic_netconsole_mutex);
163 
164 static int __init dynamic_netconsole_init(void)
165 {
166 	config_group_init(&netconsole_subsys.su_group);
167 	mutex_init(&netconsole_subsys.su_mutex);
168 	return configfs_register_subsystem(&netconsole_subsys);
169 }
170 
171 static void __exit dynamic_netconsole_exit(void)
172 {
173 	configfs_unregister_subsystem(&netconsole_subsys);
174 }
175 
176 /*
177  * Targets that were created by parsing the boot/module option string
178  * do not exist in the configfs hierarchy (and have NULL names) and will
179  * never go away, so make these a no-op for them.
180  */
181 static void netconsole_target_get(struct netconsole_target *nt)
182 {
183 	if (config_item_name(&nt->group.cg_item))
184 		config_group_get(&nt->group);
185 }
186 
187 static void netconsole_target_put(struct netconsole_target *nt)
188 {
189 	if (config_item_name(&nt->group.cg_item))
190 		config_group_put(&nt->group);
191 }
192 
193 #else	/* !CONFIG_NETCONSOLE_DYNAMIC */
194 
195 static int __init dynamic_netconsole_init(void)
196 {
197 	return 0;
198 }
199 
200 static void __exit dynamic_netconsole_exit(void)
201 {
202 }
203 
204 /*
205  * No danger of targets going away from under us when dynamic
206  * reconfigurability is off.
207  */
208 static void netconsole_target_get(struct netconsole_target *nt)
209 {
210 }
211 
212 static void netconsole_target_put(struct netconsole_target *nt)
213 {
214 }
215 
216 static void populate_configfs_item(struct netconsole_target *nt,
217 				   int cmdline_count)
218 {
219 }
220 #endif	/* CONFIG_NETCONSOLE_DYNAMIC */
221 
222 /* Allocate and initialize with defaults.
223  * Note that these targets get their config_item fields zeroed-out.
224  */
225 static struct netconsole_target *alloc_and_init(void)
226 {
227 	struct netconsole_target *nt;
228 
229 	nt = kzalloc(sizeof(*nt), GFP_KERNEL);
230 	if (!nt)
231 		return nt;
232 
233 	if (IS_ENABLED(CONFIG_NETCONSOLE_EXTENDED_LOG))
234 		nt->extended = true;
235 	if (IS_ENABLED(CONFIG_NETCONSOLE_PREPEND_RELEASE))
236 		nt->release = true;
237 
238 	nt->np.name = "netconsole";
239 	strscpy(nt->np.dev_name, "eth0", IFNAMSIZ);
240 	nt->np.local_port = 6665;
241 	nt->np.remote_port = 6666;
242 	eth_broadcast_addr(nt->np.remote_mac);
243 
244 	return nt;
245 }
246 
247 /* Clean up every target in the cleanup_list and move the clean targets back to
248  * the main target_list.
249  */
250 static void netconsole_process_cleanups_core(void)
251 {
252 	struct netconsole_target *nt, *tmp;
253 	unsigned long flags;
254 
255 	/* The cleanup needs RTNL locked */
256 	ASSERT_RTNL();
257 
258 	mutex_lock(&target_cleanup_list_lock);
259 	list_for_each_entry_safe(nt, tmp, &target_cleanup_list, list) {
260 		/* all entries in the cleanup_list needs to be disabled */
261 		WARN_ON_ONCE(nt->enabled);
262 		do_netpoll_cleanup(&nt->np);
263 		/* moved the cleaned target to target_list. Need to hold both
264 		 * locks
265 		 */
266 		spin_lock_irqsave(&target_list_lock, flags);
267 		list_move(&nt->list, &target_list);
268 		spin_unlock_irqrestore(&target_list_lock, flags);
269 	}
270 	WARN_ON_ONCE(!list_empty(&target_cleanup_list));
271 	mutex_unlock(&target_cleanup_list_lock);
272 }
273 
274 #ifdef	CONFIG_NETCONSOLE_DYNAMIC
275 
276 /*
277  * Our subsystem hierarchy is:
278  *
279  * /sys/kernel/config/netconsole/
280  *				|
281  *				<target>/
282  *				|	enabled
283  *				|	release
284  *				|	dev_name
285  *				|	local_port
286  *				|	remote_port
287  *				|	local_ip
288  *				|	remote_ip
289  *				|	local_mac
290  *				|	remote_mac
291  *				|	transmit_errors
292  *				|	userdata/
293  *				|		<key>/
294  *				|			value
295  *				|		...
296  *				|
297  *				<target>/...
298  */
299 
300 static struct netconsole_target *to_target(struct config_item *item)
301 {
302 	struct config_group *cfg_group;
303 
304 	cfg_group = to_config_group(item);
305 	if (!cfg_group)
306 		return NULL;
307 	return container_of(to_config_group(item),
308 			    struct netconsole_target, group);
309 }
310 
311 /* Do the list cleanup with the rtnl lock hold.  rtnl lock is necessary because
312  * netdev might be cleaned-up by calling __netpoll_cleanup(),
313  */
314 static void netconsole_process_cleanups(void)
315 {
316 	/* rtnl lock is called here, because it has precedence over
317 	 * target_cleanup_list_lock mutex and target_cleanup_list
318 	 */
319 	rtnl_lock();
320 	netconsole_process_cleanups_core();
321 	rtnl_unlock();
322 }
323 
324 /* Get rid of possible trailing newline, returning the new length */
325 static void trim_newline(char *s, size_t maxlen)
326 {
327 	size_t len;
328 
329 	len = strnlen(s, maxlen);
330 	if (s[len - 1] == '\n')
331 		s[len - 1] = '\0';
332 }
333 
334 /*
335  * Attribute operations for netconsole_target.
336  */
337 
338 static ssize_t enabled_show(struct config_item *item, char *buf)
339 {
340 	return sysfs_emit(buf, "%d\n", to_target(item)->enabled);
341 }
342 
343 static ssize_t extended_show(struct config_item *item, char *buf)
344 {
345 	return sysfs_emit(buf, "%d\n", to_target(item)->extended);
346 }
347 
348 static ssize_t release_show(struct config_item *item, char *buf)
349 {
350 	return sysfs_emit(buf, "%d\n", to_target(item)->release);
351 }
352 
353 static ssize_t dev_name_show(struct config_item *item, char *buf)
354 {
355 	return sysfs_emit(buf, "%s\n", to_target(item)->np.dev_name);
356 }
357 
358 static ssize_t local_port_show(struct config_item *item, char *buf)
359 {
360 	return sysfs_emit(buf, "%d\n", to_target(item)->np.local_port);
361 }
362 
363 static ssize_t remote_port_show(struct config_item *item, char *buf)
364 {
365 	return sysfs_emit(buf, "%d\n", to_target(item)->np.remote_port);
366 }
367 
368 static ssize_t local_ip_show(struct config_item *item, char *buf)
369 {
370 	struct netconsole_target *nt = to_target(item);
371 
372 	if (nt->np.ipv6)
373 		return sysfs_emit(buf, "%pI6c\n", &nt->np.local_ip.in6);
374 	else
375 		return sysfs_emit(buf, "%pI4\n", &nt->np.local_ip);
376 }
377 
378 static ssize_t remote_ip_show(struct config_item *item, char *buf)
379 {
380 	struct netconsole_target *nt = to_target(item);
381 
382 	if (nt->np.ipv6)
383 		return sysfs_emit(buf, "%pI6c\n", &nt->np.remote_ip.in6);
384 	else
385 		return sysfs_emit(buf, "%pI4\n", &nt->np.remote_ip);
386 }
387 
388 static ssize_t local_mac_show(struct config_item *item, char *buf)
389 {
390 	struct net_device *dev = to_target(item)->np.dev;
391 	static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
392 
393 	return sysfs_emit(buf, "%pM\n", dev ? dev->dev_addr : bcast);
394 }
395 
396 static ssize_t remote_mac_show(struct config_item *item, char *buf)
397 {
398 	return sysfs_emit(buf, "%pM\n", to_target(item)->np.remote_mac);
399 }
400 
401 static ssize_t transmit_errors_show(struct config_item *item, char *buf)
402 {
403 	struct netconsole_target *nt = to_target(item);
404 	u64 xmit_drop_count, enomem_count;
405 	unsigned int start;
406 
407 	do {
408 		start = u64_stats_fetch_begin(&nt->stats.syncp);
409 		xmit_drop_count = u64_stats_read(&nt->stats.xmit_drop_count);
410 		enomem_count = u64_stats_read(&nt->stats.enomem_count);
411 	} while (u64_stats_fetch_retry(&nt->stats.syncp, start));
412 
413 	return sysfs_emit(buf, "%llu\n", xmit_drop_count + enomem_count);
414 }
415 
416 /* configfs helper to display if cpu_nr sysdata feature is enabled */
417 static ssize_t sysdata_cpu_nr_enabled_show(struct config_item *item, char *buf)
418 {
419 	struct netconsole_target *nt = to_target(item->ci_parent);
420 	bool cpu_nr_enabled;
421 
422 	mutex_lock(&dynamic_netconsole_mutex);
423 	cpu_nr_enabled = !!(nt->sysdata_fields & SYSDATA_CPU_NR);
424 	mutex_unlock(&dynamic_netconsole_mutex);
425 
426 	return sysfs_emit(buf, "%d\n", cpu_nr_enabled);
427 }
428 
429 /* configfs helper to display if taskname sysdata feature is enabled */
430 static ssize_t sysdata_taskname_enabled_show(struct config_item *item,
431 					     char *buf)
432 {
433 	struct netconsole_target *nt = to_target(item->ci_parent);
434 	bool taskname_enabled;
435 
436 	mutex_lock(&dynamic_netconsole_mutex);
437 	taskname_enabled = !!(nt->sysdata_fields & SYSDATA_TASKNAME);
438 	mutex_unlock(&dynamic_netconsole_mutex);
439 
440 	return sysfs_emit(buf, "%d\n", taskname_enabled);
441 }
442 
443 /*
444  * This one is special -- targets created through the configfs interface
445  * are not enabled (and the corresponding netpoll activated) by default.
446  * The user is expected to set the desired parameters first (which
447  * would enable him to dynamically add new netpoll targets for new
448  * network interfaces as and when they come up).
449  */
450 static ssize_t enabled_store(struct config_item *item,
451 		const char *buf, size_t count)
452 {
453 	struct netconsole_target *nt = to_target(item);
454 	unsigned long flags;
455 	bool enabled;
456 	ssize_t ret;
457 
458 	mutex_lock(&dynamic_netconsole_mutex);
459 	ret = kstrtobool(buf, &enabled);
460 	if (ret)
461 		goto out_unlock;
462 
463 	ret = -EINVAL;
464 	if (enabled == nt->enabled) {
465 		pr_info("network logging has already %s\n",
466 			nt->enabled ? "started" : "stopped");
467 		goto out_unlock;
468 	}
469 
470 	if (enabled) {	/* true */
471 		if (nt->release && !nt->extended) {
472 			pr_err("Not enabling netconsole. Release feature requires extended log message");
473 			goto out_unlock;
474 		}
475 
476 		if (nt->extended && !console_is_registered(&netconsole_ext))
477 			register_console(&netconsole_ext);
478 
479 		/*
480 		 * Skip netpoll_parse_options() -- all the attributes are
481 		 * already configured via configfs. Just print them out.
482 		 */
483 		netpoll_print_options(&nt->np);
484 
485 		ret = netpoll_setup(&nt->np);
486 		if (ret)
487 			goto out_unlock;
488 
489 		nt->enabled = true;
490 		pr_info("network logging started\n");
491 	} else {	/* false */
492 		/* We need to disable the netconsole before cleaning it up
493 		 * otherwise we might end up in write_msg() with
494 		 * nt->np.dev == NULL and nt->enabled == true
495 		 */
496 		mutex_lock(&target_cleanup_list_lock);
497 		spin_lock_irqsave(&target_list_lock, flags);
498 		nt->enabled = false;
499 		/* Remove the target from the list, while holding
500 		 * target_list_lock
501 		 */
502 		list_move(&nt->list, &target_cleanup_list);
503 		spin_unlock_irqrestore(&target_list_lock, flags);
504 		mutex_unlock(&target_cleanup_list_lock);
505 	}
506 
507 	ret = strnlen(buf, count);
508 	/* Deferred cleanup */
509 	netconsole_process_cleanups();
510 out_unlock:
511 	mutex_unlock(&dynamic_netconsole_mutex);
512 	return ret;
513 }
514 
515 static ssize_t release_store(struct config_item *item, const char *buf,
516 			     size_t count)
517 {
518 	struct netconsole_target *nt = to_target(item);
519 	bool release;
520 	ssize_t ret;
521 
522 	mutex_lock(&dynamic_netconsole_mutex);
523 	if (nt->enabled) {
524 		pr_err("target (%s) is enabled, disable to update parameters\n",
525 		       config_item_name(&nt->group.cg_item));
526 		ret = -EINVAL;
527 		goto out_unlock;
528 	}
529 
530 	ret = kstrtobool(buf, &release);
531 	if (ret)
532 		goto out_unlock;
533 
534 	nt->release = release;
535 
536 	ret = strnlen(buf, count);
537 out_unlock:
538 	mutex_unlock(&dynamic_netconsole_mutex);
539 	return ret;
540 }
541 
542 static ssize_t extended_store(struct config_item *item, const char *buf,
543 		size_t count)
544 {
545 	struct netconsole_target *nt = to_target(item);
546 	bool extended;
547 	ssize_t ret;
548 
549 	mutex_lock(&dynamic_netconsole_mutex);
550 	if (nt->enabled) {
551 		pr_err("target (%s) is enabled, disable to update parameters\n",
552 		       config_item_name(&nt->group.cg_item));
553 		ret = -EINVAL;
554 		goto out_unlock;
555 	}
556 
557 	ret = kstrtobool(buf, &extended);
558 	if (ret)
559 		goto out_unlock;
560 
561 	nt->extended = extended;
562 	ret = strnlen(buf, count);
563 out_unlock:
564 	mutex_unlock(&dynamic_netconsole_mutex);
565 	return ret;
566 }
567 
568 static ssize_t dev_name_store(struct config_item *item, const char *buf,
569 		size_t count)
570 {
571 	struct netconsole_target *nt = to_target(item);
572 
573 	mutex_lock(&dynamic_netconsole_mutex);
574 	if (nt->enabled) {
575 		pr_err("target (%s) is enabled, disable to update parameters\n",
576 		       config_item_name(&nt->group.cg_item));
577 		mutex_unlock(&dynamic_netconsole_mutex);
578 		return -EINVAL;
579 	}
580 
581 	strscpy(nt->np.dev_name, buf, IFNAMSIZ);
582 	trim_newline(nt->np.dev_name, IFNAMSIZ);
583 
584 	mutex_unlock(&dynamic_netconsole_mutex);
585 	return strnlen(buf, count);
586 }
587 
588 static ssize_t local_port_store(struct config_item *item, const char *buf,
589 		size_t count)
590 {
591 	struct netconsole_target *nt = to_target(item);
592 	ssize_t ret = -EINVAL;
593 
594 	mutex_lock(&dynamic_netconsole_mutex);
595 	if (nt->enabled) {
596 		pr_err("target (%s) is enabled, disable to update parameters\n",
597 		       config_item_name(&nt->group.cg_item));
598 		goto out_unlock;
599 	}
600 
601 	ret = kstrtou16(buf, 10, &nt->np.local_port);
602 	if (ret < 0)
603 		goto out_unlock;
604 	ret = strnlen(buf, count);
605 out_unlock:
606 	mutex_unlock(&dynamic_netconsole_mutex);
607 	return ret;
608 }
609 
610 static ssize_t remote_port_store(struct config_item *item,
611 		const char *buf, size_t count)
612 {
613 	struct netconsole_target *nt = to_target(item);
614 	ssize_t ret = -EINVAL;
615 
616 	mutex_lock(&dynamic_netconsole_mutex);
617 	if (nt->enabled) {
618 		pr_err("target (%s) is enabled, disable to update parameters\n",
619 		       config_item_name(&nt->group.cg_item));
620 		goto out_unlock;
621 	}
622 
623 	ret = kstrtou16(buf, 10, &nt->np.remote_port);
624 	if (ret < 0)
625 		goto out_unlock;
626 	ret = strnlen(buf, count);
627 out_unlock:
628 	mutex_unlock(&dynamic_netconsole_mutex);
629 	return ret;
630 }
631 
632 static ssize_t local_ip_store(struct config_item *item, const char *buf,
633 		size_t count)
634 {
635 	struct netconsole_target *nt = to_target(item);
636 	ssize_t ret = -EINVAL;
637 
638 	mutex_lock(&dynamic_netconsole_mutex);
639 	if (nt->enabled) {
640 		pr_err("target (%s) is enabled, disable to update parameters\n",
641 		       config_item_name(&nt->group.cg_item));
642 		goto out_unlock;
643 	}
644 
645 	if (strnchr(buf, count, ':')) {
646 		const char *end;
647 
648 		if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) {
649 			if (*end && *end != '\n') {
650 				pr_err("invalid IPv6 address at: <%c>\n", *end);
651 				goto out_unlock;
652 			}
653 			nt->np.ipv6 = true;
654 		} else
655 			goto out_unlock;
656 	} else {
657 		if (!nt->np.ipv6)
658 			nt->np.local_ip.ip = in_aton(buf);
659 		else
660 			goto out_unlock;
661 	}
662 
663 	ret = strnlen(buf, count);
664 out_unlock:
665 	mutex_unlock(&dynamic_netconsole_mutex);
666 	return ret;
667 }
668 
669 static ssize_t remote_ip_store(struct config_item *item, const char *buf,
670 	       size_t count)
671 {
672 	struct netconsole_target *nt = to_target(item);
673 	ssize_t ret = -EINVAL;
674 
675 	mutex_lock(&dynamic_netconsole_mutex);
676 	if (nt->enabled) {
677 		pr_err("target (%s) is enabled, disable to update parameters\n",
678 		       config_item_name(&nt->group.cg_item));
679 		goto out_unlock;
680 	}
681 
682 	if (strnchr(buf, count, ':')) {
683 		const char *end;
684 
685 		if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) {
686 			if (*end && *end != '\n') {
687 				pr_err("invalid IPv6 address at: <%c>\n", *end);
688 				goto out_unlock;
689 			}
690 			nt->np.ipv6 = true;
691 		} else
692 			goto out_unlock;
693 	} else {
694 		if (!nt->np.ipv6)
695 			nt->np.remote_ip.ip = in_aton(buf);
696 		else
697 			goto out_unlock;
698 	}
699 
700 	ret = strnlen(buf, count);
701 out_unlock:
702 	mutex_unlock(&dynamic_netconsole_mutex);
703 	return ret;
704 }
705 
706 /* Count number of entries we have in extradata.
707  * This is important because the extradata_complete only supports
708  * MAX_EXTRADATA_ITEMS entries. Before enabling any new {user,sys}data
709  * feature, number of entries needs to checked for available space.
710  */
711 static size_t count_extradata_entries(struct netconsole_target *nt)
712 {
713 	size_t entries;
714 
715 	/* Userdata entries */
716 	entries = list_count_nodes(&nt->userdata_group.cg_children);
717 	/* Plus sysdata entries */
718 	if (nt->sysdata_fields & SYSDATA_CPU_NR)
719 		entries += 1;
720 	if (nt->sysdata_fields & SYSDATA_TASKNAME)
721 		entries += 1;
722 
723 	return entries;
724 }
725 
726 static ssize_t remote_mac_store(struct config_item *item, const char *buf,
727 		size_t count)
728 {
729 	struct netconsole_target *nt = to_target(item);
730 	u8 remote_mac[ETH_ALEN];
731 	ssize_t ret = -EINVAL;
732 
733 	mutex_lock(&dynamic_netconsole_mutex);
734 	if (nt->enabled) {
735 		pr_err("target (%s) is enabled, disable to update parameters\n",
736 		       config_item_name(&nt->group.cg_item));
737 		goto out_unlock;
738 	}
739 
740 	if (!mac_pton(buf, remote_mac))
741 		goto out_unlock;
742 	if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
743 		goto out_unlock;
744 	memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
745 
746 	ret = strnlen(buf, count);
747 out_unlock:
748 	mutex_unlock(&dynamic_netconsole_mutex);
749 	return ret;
750 }
751 
752 struct userdatum {
753 	struct config_item item;
754 	char value[MAX_EXTRADATA_VALUE_LEN];
755 };
756 
757 static struct userdatum *to_userdatum(struct config_item *item)
758 {
759 	return container_of(item, struct userdatum, item);
760 }
761 
762 struct userdata {
763 	struct config_group group;
764 };
765 
766 static struct userdata *to_userdata(struct config_item *item)
767 {
768 	return container_of(to_config_group(item), struct userdata, group);
769 }
770 
771 static struct netconsole_target *userdata_to_target(struct userdata *ud)
772 {
773 	struct config_group *netconsole_group;
774 
775 	netconsole_group = to_config_group(ud->group.cg_item.ci_parent);
776 	return to_target(&netconsole_group->cg_item);
777 }
778 
779 static ssize_t userdatum_value_show(struct config_item *item, char *buf)
780 {
781 	return sysfs_emit(buf, "%s\n", &(to_userdatum(item)->value[0]));
782 }
783 
784 static void update_userdata(struct netconsole_target *nt)
785 {
786 	int complete_idx = 0, child_count = 0;
787 	struct list_head *entry;
788 
789 	/* Clear the current string in case the last userdatum was deleted */
790 	nt->userdata_length = 0;
791 	nt->extradata_complete[0] = 0;
792 
793 	list_for_each(entry, &nt->userdata_group.cg_children) {
794 		struct userdatum *udm_item;
795 		struct config_item *item;
796 
797 		if (WARN_ON_ONCE(child_count >= MAX_EXTRADATA_ITEMS))
798 			break;
799 		child_count++;
800 
801 		item = container_of(entry, struct config_item, ci_entry);
802 		udm_item = to_userdatum(item);
803 
804 		/* Skip userdata with no value set */
805 		if (strnlen(udm_item->value, MAX_EXTRADATA_VALUE_LEN) == 0)
806 			continue;
807 
808 		/* This doesn't overflow extradata_complete since it will write
809 		 * one entry length (1/MAX_EXTRADATA_ITEMS long), entry count is
810 		 * checked to not exceed MAX items with child_count above
811 		 */
812 		complete_idx += scnprintf(&nt->extradata_complete[complete_idx],
813 					  MAX_EXTRADATA_ENTRY_LEN, " %s=%s\n",
814 					  item->ci_name, udm_item->value);
815 	}
816 	nt->userdata_length = strnlen(nt->extradata_complete,
817 				      sizeof(nt->extradata_complete));
818 }
819 
820 static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
821 				     size_t count)
822 {
823 	struct userdatum *udm = to_userdatum(item);
824 	struct netconsole_target *nt;
825 	struct userdata *ud;
826 	ssize_t ret;
827 
828 	if (count > MAX_EXTRADATA_VALUE_LEN)
829 		return -EMSGSIZE;
830 
831 	mutex_lock(&dynamic_netconsole_mutex);
832 
833 	ret = strscpy(udm->value, buf, sizeof(udm->value));
834 	if (ret < 0)
835 		goto out_unlock;
836 	trim_newline(udm->value, sizeof(udm->value));
837 
838 	ud = to_userdata(item->ci_parent);
839 	nt = userdata_to_target(ud);
840 	update_userdata(nt);
841 	ret = count;
842 out_unlock:
843 	mutex_unlock(&dynamic_netconsole_mutex);
844 	return ret;
845 }
846 
847 /* disable_sysdata_feature - Disable sysdata feature and clean sysdata
848  * @nt: target that is disabling the feature
849  * @feature: feature being disabled
850  */
851 static void disable_sysdata_feature(struct netconsole_target *nt,
852 				    enum sysdata_feature feature)
853 {
854 	nt->sysdata_fields &= ~feature;
855 	nt->extradata_complete[nt->userdata_length] = 0;
856 }
857 
858 static ssize_t sysdata_taskname_enabled_store(struct config_item *item,
859 					      const char *buf, size_t count)
860 {
861 	struct netconsole_target *nt = to_target(item->ci_parent);
862 	bool taskname_enabled, curr;
863 	ssize_t ret;
864 
865 	ret = kstrtobool(buf, &taskname_enabled);
866 	if (ret)
867 		return ret;
868 
869 	mutex_lock(&dynamic_netconsole_mutex);
870 	curr = !!(nt->sysdata_fields & SYSDATA_TASKNAME);
871 	if (taskname_enabled == curr)
872 		goto unlock_ok;
873 
874 	if (taskname_enabled &&
875 	    count_extradata_entries(nt) >= MAX_EXTRADATA_ITEMS) {
876 		ret = -ENOSPC;
877 		goto unlock;
878 	}
879 
880 	if (taskname_enabled)
881 		nt->sysdata_fields |= SYSDATA_TASKNAME;
882 	else
883 		disable_sysdata_feature(nt, SYSDATA_TASKNAME);
884 
885 unlock_ok:
886 	ret = strnlen(buf, count);
887 unlock:
888 	mutex_unlock(&dynamic_netconsole_mutex);
889 	return ret;
890 }
891 
892 /* configfs helper to sysdata cpu_nr feature */
893 static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item,
894 					    const char *buf, size_t count)
895 {
896 	struct netconsole_target *nt = to_target(item->ci_parent);
897 	bool cpu_nr_enabled, curr;
898 	ssize_t ret;
899 
900 	ret = kstrtobool(buf, &cpu_nr_enabled);
901 	if (ret)
902 		return ret;
903 
904 	mutex_lock(&dynamic_netconsole_mutex);
905 	curr = !!(nt->sysdata_fields & SYSDATA_CPU_NR);
906 	if (cpu_nr_enabled == curr)
907 		/* no change requested */
908 		goto unlock_ok;
909 
910 	if (cpu_nr_enabled &&
911 	    count_extradata_entries(nt) >= MAX_EXTRADATA_ITEMS) {
912 		/* user wants the new feature, but there is no space in the
913 		 * buffer.
914 		 */
915 		ret = -ENOSPC;
916 		goto unlock;
917 	}
918 
919 	if (cpu_nr_enabled)
920 		nt->sysdata_fields |= SYSDATA_CPU_NR;
921 	else
922 		/* This is special because extradata_complete might have
923 		 * remaining data from previous sysdata, and it needs to be
924 		 * cleaned.
925 		 */
926 		disable_sysdata_feature(nt, SYSDATA_CPU_NR);
927 
928 unlock_ok:
929 	ret = strnlen(buf, count);
930 unlock:
931 	mutex_unlock(&dynamic_netconsole_mutex);
932 	return ret;
933 }
934 
935 CONFIGFS_ATTR(userdatum_, value);
936 CONFIGFS_ATTR(sysdata_, cpu_nr_enabled);
937 CONFIGFS_ATTR(sysdata_, taskname_enabled);
938 
939 static struct configfs_attribute *userdatum_attrs[] = {
940 	&userdatum_attr_value,
941 	NULL,
942 };
943 
944 static void userdatum_release(struct config_item *item)
945 {
946 	kfree(to_userdatum(item));
947 }
948 
949 static struct configfs_item_operations userdatum_ops = {
950 	.release = userdatum_release,
951 };
952 
953 static const struct config_item_type userdatum_type = {
954 	.ct_item_ops	= &userdatum_ops,
955 	.ct_attrs	= userdatum_attrs,
956 	.ct_owner	= THIS_MODULE,
957 };
958 
959 static struct config_item *userdatum_make_item(struct config_group *group,
960 					       const char *name)
961 {
962 	struct netconsole_target *nt;
963 	struct userdatum *udm;
964 	struct userdata *ud;
965 
966 	if (strlen(name) > MAX_EXTRADATA_NAME_LEN)
967 		return ERR_PTR(-ENAMETOOLONG);
968 
969 	ud = to_userdata(&group->cg_item);
970 	nt = userdata_to_target(ud);
971 	if (count_extradata_entries(nt) >= MAX_EXTRADATA_ITEMS)
972 		return ERR_PTR(-ENOSPC);
973 
974 	udm = kzalloc(sizeof(*udm), GFP_KERNEL);
975 	if (!udm)
976 		return ERR_PTR(-ENOMEM);
977 
978 	config_item_init_type_name(&udm->item, name, &userdatum_type);
979 	return &udm->item;
980 }
981 
982 static void userdatum_drop(struct config_group *group, struct config_item *item)
983 {
984 	struct netconsole_target *nt;
985 	struct userdata *ud;
986 
987 	ud = to_userdata(&group->cg_item);
988 	nt = userdata_to_target(ud);
989 
990 	mutex_lock(&dynamic_netconsole_mutex);
991 	update_userdata(nt);
992 	config_item_put(item);
993 	mutex_unlock(&dynamic_netconsole_mutex);
994 }
995 
996 static struct configfs_attribute *userdata_attrs[] = {
997 	&sysdata_attr_cpu_nr_enabled,
998 	&sysdata_attr_taskname_enabled,
999 	NULL,
1000 };
1001 
1002 static struct configfs_group_operations userdata_ops = {
1003 	.make_item		= userdatum_make_item,
1004 	.drop_item		= userdatum_drop,
1005 };
1006 
1007 static const struct config_item_type userdata_type = {
1008 	.ct_item_ops	= &userdatum_ops,
1009 	.ct_group_ops	= &userdata_ops,
1010 	.ct_attrs	= userdata_attrs,
1011 	.ct_owner	= THIS_MODULE,
1012 };
1013 
1014 CONFIGFS_ATTR(, enabled);
1015 CONFIGFS_ATTR(, extended);
1016 CONFIGFS_ATTR(, dev_name);
1017 CONFIGFS_ATTR(, local_port);
1018 CONFIGFS_ATTR(, remote_port);
1019 CONFIGFS_ATTR(, local_ip);
1020 CONFIGFS_ATTR(, remote_ip);
1021 CONFIGFS_ATTR_RO(, local_mac);
1022 CONFIGFS_ATTR(, remote_mac);
1023 CONFIGFS_ATTR(, release);
1024 CONFIGFS_ATTR_RO(, transmit_errors);
1025 
1026 static struct configfs_attribute *netconsole_target_attrs[] = {
1027 	&attr_enabled,
1028 	&attr_extended,
1029 	&attr_release,
1030 	&attr_dev_name,
1031 	&attr_local_port,
1032 	&attr_remote_port,
1033 	&attr_local_ip,
1034 	&attr_remote_ip,
1035 	&attr_local_mac,
1036 	&attr_remote_mac,
1037 	&attr_transmit_errors,
1038 	NULL,
1039 };
1040 
1041 /*
1042  * Item operations and type for netconsole_target.
1043  */
1044 
1045 static void netconsole_target_release(struct config_item *item)
1046 {
1047 	kfree(to_target(item));
1048 }
1049 
1050 static struct configfs_item_operations netconsole_target_item_ops = {
1051 	.release		= netconsole_target_release,
1052 };
1053 
1054 static const struct config_item_type netconsole_target_type = {
1055 	.ct_attrs		= netconsole_target_attrs,
1056 	.ct_item_ops		= &netconsole_target_item_ops,
1057 	.ct_owner		= THIS_MODULE,
1058 };
1059 
1060 static void init_target_config_group(struct netconsole_target *nt,
1061 				     const char *name)
1062 {
1063 	config_group_init_type_name(&nt->group, name, &netconsole_target_type);
1064 	config_group_init_type_name(&nt->userdata_group, "userdata",
1065 				    &userdata_type);
1066 	configfs_add_default_group(&nt->userdata_group, &nt->group);
1067 }
1068 
1069 static struct netconsole_target *find_cmdline_target(const char *name)
1070 {
1071 	struct netconsole_target *nt, *ret = NULL;
1072 	unsigned long flags;
1073 
1074 	spin_lock_irqsave(&target_list_lock, flags);
1075 	list_for_each_entry(nt, &target_list, list) {
1076 		if (!strcmp(nt->group.cg_item.ci_name, name)) {
1077 			ret = nt;
1078 			break;
1079 		}
1080 	}
1081 	spin_unlock_irqrestore(&target_list_lock, flags);
1082 
1083 	return ret;
1084 }
1085 
1086 /*
1087  * Group operations and type for netconsole_subsys.
1088  */
1089 
1090 static struct config_group *make_netconsole_target(struct config_group *group,
1091 						   const char *name)
1092 {
1093 	struct netconsole_target *nt;
1094 	unsigned long flags;
1095 
1096 	/* Checking if a target by this name was created at boot time.  If so,
1097 	 * attach a configfs entry to that target.  This enables dynamic
1098 	 * control.
1099 	 */
1100 	if (!strncmp(name, NETCONSOLE_PARAM_TARGET_PREFIX,
1101 		     strlen(NETCONSOLE_PARAM_TARGET_PREFIX))) {
1102 		nt = find_cmdline_target(name);
1103 		if (nt) {
1104 			init_target_config_group(nt, name);
1105 			return &nt->group;
1106 		}
1107 	}
1108 
1109 	nt = alloc_and_init();
1110 	if (!nt)
1111 		return ERR_PTR(-ENOMEM);
1112 
1113 	/* Initialize the config_group member */
1114 	init_target_config_group(nt, name);
1115 
1116 	/* Adding, but it is disabled */
1117 	spin_lock_irqsave(&target_list_lock, flags);
1118 	list_add(&nt->list, &target_list);
1119 	spin_unlock_irqrestore(&target_list_lock, flags);
1120 
1121 	return &nt->group;
1122 }
1123 
1124 static void drop_netconsole_target(struct config_group *group,
1125 				   struct config_item *item)
1126 {
1127 	unsigned long flags;
1128 	struct netconsole_target *nt = to_target(item);
1129 
1130 	spin_lock_irqsave(&target_list_lock, flags);
1131 	list_del(&nt->list);
1132 	spin_unlock_irqrestore(&target_list_lock, flags);
1133 
1134 	/*
1135 	 * The target may have never been enabled, or was manually disabled
1136 	 * before being removed so netpoll may have already been cleaned up.
1137 	 */
1138 	if (nt->enabled)
1139 		netpoll_cleanup(&nt->np);
1140 
1141 	config_item_put(&nt->group.cg_item);
1142 }
1143 
1144 static struct configfs_group_operations netconsole_subsys_group_ops = {
1145 	.make_group	= make_netconsole_target,
1146 	.drop_item	= drop_netconsole_target,
1147 };
1148 
1149 static const struct config_item_type netconsole_subsys_type = {
1150 	.ct_group_ops	= &netconsole_subsys_group_ops,
1151 	.ct_owner	= THIS_MODULE,
1152 };
1153 
1154 /* The netconsole configfs subsystem */
1155 static struct configfs_subsystem netconsole_subsys = {
1156 	.su_group	= {
1157 		.cg_item	= {
1158 			.ci_namebuf	= "netconsole",
1159 			.ci_type	= &netconsole_subsys_type,
1160 		},
1161 	},
1162 };
1163 
1164 static void populate_configfs_item(struct netconsole_target *nt,
1165 				   int cmdline_count)
1166 {
1167 	char target_name[16];
1168 
1169 	snprintf(target_name, sizeof(target_name), "%s%d",
1170 		 NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);
1171 	init_target_config_group(nt, target_name);
1172 }
1173 
1174 static int append_cpu_nr(struct netconsole_target *nt, int offset)
1175 {
1176 	/* Append cpu=%d at extradata_complete after userdata str */
1177 	return scnprintf(&nt->extradata_complete[offset],
1178 			 MAX_EXTRADATA_ENTRY_LEN, " cpu=%u\n",
1179 			 raw_smp_processor_id());
1180 }
1181 
1182 static int append_taskname(struct netconsole_target *nt, int offset)
1183 {
1184 	return scnprintf(&nt->extradata_complete[offset],
1185 			 MAX_EXTRADATA_ENTRY_LEN, " taskname=%s\n",
1186 			 current->comm);
1187 }
1188 /*
1189  * prepare_extradata - append sysdata at extradata_complete in runtime
1190  * @nt: target to send message to
1191  */
1192 static int prepare_extradata(struct netconsole_target *nt)
1193 {
1194 	u32 fields = SYSDATA_CPU_NR | SYSDATA_TASKNAME;
1195 	int extradata_len;
1196 
1197 	/* userdata was appended when configfs write helper was called
1198 	 * by update_userdata().
1199 	 */
1200 	extradata_len = nt->userdata_length;
1201 
1202 	if (!(nt->sysdata_fields & fields))
1203 		goto out;
1204 
1205 	if (nt->sysdata_fields & SYSDATA_CPU_NR)
1206 		extradata_len += append_cpu_nr(nt, extradata_len);
1207 	if (nt->sysdata_fields & SYSDATA_TASKNAME)
1208 		extradata_len += append_taskname(nt, extradata_len);
1209 
1210 	WARN_ON_ONCE(extradata_len >
1211 		     MAX_EXTRADATA_ENTRY_LEN * MAX_EXTRADATA_ITEMS);
1212 
1213 out:
1214 	return extradata_len;
1215 }
1216 #else /* CONFIG_NETCONSOLE_DYNAMIC not set */
1217 static int prepare_extradata(struct netconsole_target *nt)
1218 {
1219 	return 0;
1220 }
1221 #endif	/* CONFIG_NETCONSOLE_DYNAMIC */
1222 
1223 /* Handle network interface device notifications */
1224 static int netconsole_netdev_event(struct notifier_block *this,
1225 				   unsigned long event, void *ptr)
1226 {
1227 	unsigned long flags;
1228 	struct netconsole_target *nt, *tmp;
1229 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1230 	bool stopped = false;
1231 
1232 	if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER ||
1233 	      event == NETDEV_RELEASE || event == NETDEV_JOIN))
1234 		goto done;
1235 
1236 	mutex_lock(&target_cleanup_list_lock);
1237 	spin_lock_irqsave(&target_list_lock, flags);
1238 	list_for_each_entry_safe(nt, tmp, &target_list, list) {
1239 		netconsole_target_get(nt);
1240 		if (nt->np.dev == dev) {
1241 			switch (event) {
1242 			case NETDEV_CHANGENAME:
1243 				strscpy(nt->np.dev_name, dev->name, IFNAMSIZ);
1244 				break;
1245 			case NETDEV_RELEASE:
1246 			case NETDEV_JOIN:
1247 			case NETDEV_UNREGISTER:
1248 				nt->enabled = false;
1249 				list_move(&nt->list, &target_cleanup_list);
1250 				stopped = true;
1251 			}
1252 		}
1253 		netconsole_target_put(nt);
1254 	}
1255 	spin_unlock_irqrestore(&target_list_lock, flags);
1256 	mutex_unlock(&target_cleanup_list_lock);
1257 
1258 	if (stopped) {
1259 		const char *msg = "had an event";
1260 
1261 		switch (event) {
1262 		case NETDEV_UNREGISTER:
1263 			msg = "unregistered";
1264 			break;
1265 		case NETDEV_RELEASE:
1266 			msg = "released slaves";
1267 			break;
1268 		case NETDEV_JOIN:
1269 			msg = "is joining a master device";
1270 			break;
1271 		}
1272 		pr_info("network logging stopped on interface %s as it %s\n",
1273 			dev->name, msg);
1274 	}
1275 
1276 	/* Process target_cleanup_list entries. By the end, target_cleanup_list
1277 	 * should be empty
1278 	 */
1279 	netconsole_process_cleanups_core();
1280 
1281 done:
1282 	return NOTIFY_DONE;
1283 }
1284 
1285 static struct notifier_block netconsole_netdev_notifier = {
1286 	.notifier_call  = netconsole_netdev_event,
1287 };
1288 
1289 /**
1290  * send_udp - Wrapper for netpoll_send_udp that counts errors
1291  * @nt: target to send message to
1292  * @msg: message to send
1293  * @len: length of message
1294  *
1295  * Calls netpoll_send_udp and classifies the return value. If an error
1296  * occurred it increments statistics in nt->stats accordingly.
1297  * Only calls netpoll_send_udp if CONFIG_NETCONSOLE_DYNAMIC is disabled.
1298  */
1299 static void send_udp(struct netconsole_target *nt, const char *msg, int len)
1300 {
1301 	int result = netpoll_send_udp(&nt->np, msg, len);
1302 
1303 	if (IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC)) {
1304 		if (result == NET_XMIT_DROP) {
1305 			u64_stats_update_begin(&nt->stats.syncp);
1306 			u64_stats_inc(&nt->stats.xmit_drop_count);
1307 			u64_stats_update_end(&nt->stats.syncp);
1308 		} else if (result == -ENOMEM) {
1309 			u64_stats_update_begin(&nt->stats.syncp);
1310 			u64_stats_inc(&nt->stats.enomem_count);
1311 			u64_stats_update_end(&nt->stats.syncp);
1312 		}
1313 	}
1314 }
1315 
1316 static void send_msg_no_fragmentation(struct netconsole_target *nt,
1317 				      const char *msg,
1318 				      int msg_len,
1319 				      int release_len)
1320 {
1321 	const char *extradata = NULL;
1322 	const char *release;
1323 
1324 #ifdef CONFIG_NETCONSOLE_DYNAMIC
1325 	extradata = nt->extradata_complete;
1326 #endif
1327 
1328 	if (release_len) {
1329 		release = init_utsname()->release;
1330 
1331 		scnprintf(nt->buf, MAX_PRINT_CHUNK, "%s,%s", release, msg);
1332 		msg_len += release_len;
1333 	} else {
1334 		memcpy(nt->buf, msg, msg_len);
1335 	}
1336 
1337 	if (extradata)
1338 		msg_len += scnprintf(&nt->buf[msg_len],
1339 				     MAX_PRINT_CHUNK - msg_len,
1340 				     "%s", extradata);
1341 
1342 	send_udp(nt, nt->buf, msg_len);
1343 }
1344 
1345 static void append_release(char *buf)
1346 {
1347 	const char *release;
1348 
1349 	release = init_utsname()->release;
1350 	scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
1351 }
1352 
1353 static void send_fragmented_body(struct netconsole_target *nt,
1354 				 const char *msgbody, int header_len,
1355 				 int msgbody_len, int extradata_len)
1356 {
1357 	int sent_extradata, preceding_bytes;
1358 	const char *extradata = NULL;
1359 	int body_len, offset = 0;
1360 
1361 #ifdef CONFIG_NETCONSOLE_DYNAMIC
1362 	extradata = nt->extradata_complete;
1363 #endif
1364 
1365 	/* body_len represents the number of bytes that will be sent. This is
1366 	 * bigger than MAX_PRINT_CHUNK, thus, it will be split in multiple
1367 	 * packets
1368 	 */
1369 	body_len = msgbody_len + extradata_len;
1370 
1371 	/* In each iteration of the while loop below, we send a packet
1372 	 * containing the header and a portion of the body. The body is
1373 	 * composed of two parts: msgbody and extradata. We keep track of how
1374 	 * many bytes have been sent so far using the offset variable, which
1375 	 * ranges from 0 to the total length of the body.
1376 	 */
1377 	while (offset < body_len) {
1378 		int this_header = header_len;
1379 		bool msgbody_written = false;
1380 		int this_offset = 0;
1381 		int this_chunk = 0;
1382 
1383 		this_header += scnprintf(nt->buf + this_header,
1384 					 MAX_PRINT_CHUNK - this_header,
1385 					 ",ncfrag=%d/%d;", offset,
1386 					 body_len);
1387 
1388 		/* Not all msgbody data has been written yet */
1389 		if (offset < msgbody_len) {
1390 			this_chunk = min(msgbody_len - offset,
1391 					 MAX_PRINT_CHUNK - this_header);
1392 			if (WARN_ON_ONCE(this_chunk <= 0))
1393 				return;
1394 			memcpy(nt->buf + this_header, msgbody + offset,
1395 			       this_chunk);
1396 			this_offset += this_chunk;
1397 		}
1398 
1399 		/* msgbody was finally written, either in the previous
1400 		 * messages and/or in the current buf. Time to write
1401 		 * the extradata.
1402 		 */
1403 		msgbody_written |= offset + this_offset >= msgbody_len;
1404 
1405 		/* Msg body is fully written and there is pending extradata to
1406 		 * write, append extradata in this chunk
1407 		 */
1408 		if (msgbody_written && offset + this_offset < body_len) {
1409 			/* Track how much user data was already sent. First
1410 			 * time here, sent_userdata is zero
1411 			 */
1412 			sent_extradata = (offset + this_offset) - msgbody_len;
1413 			/* offset of bytes used in current buf */
1414 			preceding_bytes = this_chunk + this_header;
1415 
1416 			if (WARN_ON_ONCE(sent_extradata < 0))
1417 				return;
1418 
1419 			this_chunk = min(extradata_len - sent_extradata,
1420 					 MAX_PRINT_CHUNK - preceding_bytes);
1421 			if (WARN_ON_ONCE(this_chunk < 0))
1422 				/* this_chunk could be zero if all the previous
1423 				 * message used all the buffer. This is not a
1424 				 * problem, extradata will be sent in the next
1425 				 * iteration
1426 				 */
1427 				return;
1428 
1429 			memcpy(nt->buf + this_header + this_offset,
1430 			       extradata + sent_extradata,
1431 			       this_chunk);
1432 			this_offset += this_chunk;
1433 		}
1434 
1435 		send_udp(nt, nt->buf, this_header + this_offset);
1436 		offset += this_offset;
1437 	}
1438 }
1439 
1440 static void send_msg_fragmented(struct netconsole_target *nt,
1441 				const char *msg,
1442 				int msg_len,
1443 				int release_len,
1444 				int extradata_len)
1445 {
1446 	int header_len, msgbody_len;
1447 	const char *msgbody;
1448 
1449 	/* need to insert extra header fields, detect header and msgbody */
1450 	msgbody = memchr(msg, ';', msg_len);
1451 	if (WARN_ON_ONCE(!msgbody))
1452 		return;
1453 
1454 	header_len = msgbody - msg;
1455 	msgbody_len = msg_len - header_len - 1;
1456 	msgbody++;
1457 
1458 	/*
1459 	 * Transfer multiple chunks with the following extra header.
1460 	 * "ncfrag=<byte-offset>/<total-bytes>"
1461 	 */
1462 	if (release_len)
1463 		append_release(nt->buf);
1464 
1465 	/* Copy the header into the buffer */
1466 	memcpy(nt->buf + release_len, msg, header_len);
1467 	header_len += release_len;
1468 
1469 	/* for now on, the header will be persisted, and the msgbody
1470 	 * will be replaced
1471 	 */
1472 	send_fragmented_body(nt, msgbody, header_len, msgbody_len,
1473 			     extradata_len);
1474 }
1475 
1476 /**
1477  * send_ext_msg_udp - send extended log message to target
1478  * @nt: target to send message to
1479  * @msg: extended log message to send
1480  * @msg_len: length of message
1481  *
1482  * Transfer extended log @msg to @nt.  If @msg is longer than
1483  * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
1484  * ncfrag header field added to identify them.
1485  */
1486 static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
1487 			     int msg_len)
1488 {
1489 	int release_len = 0;
1490 	int extradata_len;
1491 
1492 	extradata_len = prepare_extradata(nt);
1493 
1494 	if (nt->release)
1495 		release_len = strlen(init_utsname()->release) + 1;
1496 
1497 	if (msg_len + release_len + extradata_len <= MAX_PRINT_CHUNK)
1498 		return send_msg_no_fragmentation(nt, msg, msg_len, release_len);
1499 
1500 	return send_msg_fragmented(nt, msg, msg_len, release_len,
1501 				   extradata_len);
1502 }
1503 
1504 static void write_ext_msg(struct console *con, const char *msg,
1505 			  unsigned int len)
1506 {
1507 	struct netconsole_target *nt;
1508 	unsigned long flags;
1509 
1510 	if ((oops_only && !oops_in_progress) || list_empty(&target_list))
1511 		return;
1512 
1513 	spin_lock_irqsave(&target_list_lock, flags);
1514 	list_for_each_entry(nt, &target_list, list)
1515 		if (nt->extended && nt->enabled && netif_running(nt->np.dev))
1516 			send_ext_msg_udp(nt, msg, len);
1517 	spin_unlock_irqrestore(&target_list_lock, flags);
1518 }
1519 
1520 static void write_msg(struct console *con, const char *msg, unsigned int len)
1521 {
1522 	int frag, left;
1523 	unsigned long flags;
1524 	struct netconsole_target *nt;
1525 	const char *tmp;
1526 
1527 	if (oops_only && !oops_in_progress)
1528 		return;
1529 	/* Avoid taking lock and disabling interrupts unnecessarily */
1530 	if (list_empty(&target_list))
1531 		return;
1532 
1533 	spin_lock_irqsave(&target_list_lock, flags);
1534 	list_for_each_entry(nt, &target_list, list) {
1535 		if (!nt->extended && nt->enabled && netif_running(nt->np.dev)) {
1536 			/*
1537 			 * We nest this inside the for-each-target loop above
1538 			 * so that we're able to get as much logging out to
1539 			 * at least one target if we die inside here, instead
1540 			 * of unnecessarily keeping all targets in lock-step.
1541 			 */
1542 			tmp = msg;
1543 			for (left = len; left;) {
1544 				frag = min(left, MAX_PRINT_CHUNK);
1545 				send_udp(nt, tmp, frag);
1546 				tmp += frag;
1547 				left -= frag;
1548 			}
1549 		}
1550 	}
1551 	spin_unlock_irqrestore(&target_list_lock, flags);
1552 }
1553 
1554 /* Allocate new target (from boot/module param) and setup netpoll for it */
1555 static struct netconsole_target *alloc_param_target(char *target_config,
1556 						    int cmdline_count)
1557 {
1558 	struct netconsole_target *nt;
1559 	int err;
1560 
1561 	nt = alloc_and_init();
1562 	if (!nt) {
1563 		err = -ENOMEM;
1564 		goto fail;
1565 	}
1566 
1567 	if (*target_config == '+') {
1568 		nt->extended = true;
1569 		target_config++;
1570 	}
1571 
1572 	if (*target_config == 'r') {
1573 		if (!nt->extended) {
1574 			pr_err("Netconsole configuration error. Release feature requires extended log message");
1575 			err = -EINVAL;
1576 			goto fail;
1577 		}
1578 		nt->release = true;
1579 		target_config++;
1580 	}
1581 
1582 	/* Parse parameters and setup netpoll */
1583 	err = netpoll_parse_options(&nt->np, target_config);
1584 	if (err)
1585 		goto fail;
1586 
1587 	err = netpoll_setup(&nt->np);
1588 	if (err) {
1589 		pr_err("Not enabling netconsole for %s%d. Netpoll setup failed\n",
1590 		       NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);
1591 		if (!IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC))
1592 			/* only fail if dynamic reconfiguration is set,
1593 			 * otherwise, keep the target in the list, but disabled.
1594 			 */
1595 			goto fail;
1596 	} else {
1597 		nt->enabled = true;
1598 	}
1599 	populate_configfs_item(nt, cmdline_count);
1600 
1601 	return nt;
1602 
1603 fail:
1604 	kfree(nt);
1605 	return ERR_PTR(err);
1606 }
1607 
1608 /* Cleanup netpoll for given target (from boot/module param) and free it */
1609 static void free_param_target(struct netconsole_target *nt)
1610 {
1611 	netpoll_cleanup(&nt->np);
1612 	kfree(nt);
1613 }
1614 
1615 static struct console netconsole_ext = {
1616 	.name	= "netcon_ext",
1617 	.flags	= CON_ENABLED | CON_EXTENDED,
1618 	.write	= write_ext_msg,
1619 };
1620 
1621 static struct console netconsole = {
1622 	.name	= "netcon",
1623 	.flags	= CON_ENABLED,
1624 	.write	= write_msg,
1625 };
1626 
1627 static int __init init_netconsole(void)
1628 {
1629 	int err;
1630 	struct netconsole_target *nt, *tmp;
1631 	unsigned int count = 0;
1632 	bool extended = false;
1633 	unsigned long flags;
1634 	char *target_config;
1635 	char *input = config;
1636 
1637 	if (strnlen(input, MAX_PARAM_LENGTH)) {
1638 		while ((target_config = strsep(&input, ";"))) {
1639 			nt = alloc_param_target(target_config, count);
1640 			if (IS_ERR(nt)) {
1641 				if (IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC))
1642 					continue;
1643 				err = PTR_ERR(nt);
1644 				goto fail;
1645 			}
1646 			/* Dump existing printks when we register */
1647 			if (nt->extended) {
1648 				extended = true;
1649 				netconsole_ext.flags |= CON_PRINTBUFFER;
1650 			} else {
1651 				netconsole.flags |= CON_PRINTBUFFER;
1652 			}
1653 
1654 			spin_lock_irqsave(&target_list_lock, flags);
1655 			list_add(&nt->list, &target_list);
1656 			spin_unlock_irqrestore(&target_list_lock, flags);
1657 			count++;
1658 		}
1659 	}
1660 
1661 	err = register_netdevice_notifier(&netconsole_netdev_notifier);
1662 	if (err)
1663 		goto fail;
1664 
1665 	err = dynamic_netconsole_init();
1666 	if (err)
1667 		goto undonotifier;
1668 
1669 	if (extended)
1670 		register_console(&netconsole_ext);
1671 	register_console(&netconsole);
1672 	pr_info("network logging started\n");
1673 
1674 	return err;
1675 
1676 undonotifier:
1677 	unregister_netdevice_notifier(&netconsole_netdev_notifier);
1678 
1679 fail:
1680 	pr_err("cleaning up\n");
1681 
1682 	/*
1683 	 * Remove all targets and destroy them (only targets created
1684 	 * from the boot/module option exist here). Skipping the list
1685 	 * lock is safe here, and netpoll_cleanup() will sleep.
1686 	 */
1687 	list_for_each_entry_safe(nt, tmp, &target_list, list) {
1688 		list_del(&nt->list);
1689 		free_param_target(nt);
1690 	}
1691 
1692 	return err;
1693 }
1694 
1695 static void __exit cleanup_netconsole(void)
1696 {
1697 	struct netconsole_target *nt, *tmp;
1698 
1699 	if (console_is_registered(&netconsole_ext))
1700 		unregister_console(&netconsole_ext);
1701 	unregister_console(&netconsole);
1702 	dynamic_netconsole_exit();
1703 	unregister_netdevice_notifier(&netconsole_netdev_notifier);
1704 
1705 	/*
1706 	 * Targets created via configfs pin references on our module
1707 	 * and would first be rmdir(2)'ed from userspace. We reach
1708 	 * here only when they are already destroyed, and only those
1709 	 * created from the boot/module option are left, so remove and
1710 	 * destroy them. Skipping the list lock is safe here, and
1711 	 * netpoll_cleanup() will sleep.
1712 	 */
1713 	list_for_each_entry_safe(nt, tmp, &target_list, list) {
1714 		list_del(&nt->list);
1715 		free_param_target(nt);
1716 	}
1717 }
1718 
1719 /*
1720  * Use late_initcall to ensure netconsole is
1721  * initialized after network device driver if built-in.
1722  *
1723  * late_initcall() and module_init() are identical if built as module.
1724  */
1725 late_initcall(init_netconsole);
1726 module_exit(cleanup_netconsole);
1727