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