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