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, GFP_KERNEL);
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 (s[len - 1] == '\n')
501 s[len - 1] = '\0';
502 }
503
504 /*
505 * Attribute operations for netconsole_target.
506 */
507
enabled_show(struct config_item * item,char * buf)508 static ssize_t enabled_show(struct config_item *item, char *buf)
509 {
510 return sysfs_emit(buf, "%d\n", to_target(item)->state == STATE_ENABLED);
511 }
512
extended_show(struct config_item * item,char * buf)513 static ssize_t extended_show(struct config_item *item, char *buf)
514 {
515 return sysfs_emit(buf, "%d\n", to_target(item)->extended);
516 }
517
release_show(struct config_item * item,char * buf)518 static ssize_t release_show(struct config_item *item, char *buf)
519 {
520 return sysfs_emit(buf, "%d\n", to_target(item)->release);
521 }
522
dev_name_show(struct config_item * item,char * buf)523 static ssize_t dev_name_show(struct config_item *item, char *buf)
524 {
525 return sysfs_emit(buf, "%s\n", to_target(item)->np.dev_name);
526 }
527
local_port_show(struct config_item * item,char * buf)528 static ssize_t local_port_show(struct config_item *item, char *buf)
529 {
530 return sysfs_emit(buf, "%d\n", to_target(item)->np.local_port);
531 }
532
remote_port_show(struct config_item * item,char * buf)533 static ssize_t remote_port_show(struct config_item *item, char *buf)
534 {
535 return sysfs_emit(buf, "%d\n", to_target(item)->np.remote_port);
536 }
537
local_ip_show(struct config_item * item,char * buf)538 static ssize_t local_ip_show(struct config_item *item, char *buf)
539 {
540 struct netconsole_target *nt = to_target(item);
541
542 if (nt->np.ipv6)
543 return sysfs_emit(buf, "%pI6c\n", &nt->np.local_ip.in6);
544 else
545 return sysfs_emit(buf, "%pI4\n", &nt->np.local_ip);
546 }
547
remote_ip_show(struct config_item * item,char * buf)548 static ssize_t remote_ip_show(struct config_item *item, char *buf)
549 {
550 struct netconsole_target *nt = to_target(item);
551
552 if (nt->np.ipv6)
553 return sysfs_emit(buf, "%pI6c\n", &nt->np.remote_ip.in6);
554 else
555 return sysfs_emit(buf, "%pI4\n", &nt->np.remote_ip);
556 }
557
local_mac_show(struct config_item * item,char * buf)558 static ssize_t local_mac_show(struct config_item *item, char *buf)
559 {
560 struct net_device *dev = to_target(item)->np.dev;
561 static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
562
563 return sysfs_emit(buf, "%pM\n", dev ? dev->dev_addr : bcast);
564 }
565
remote_mac_show(struct config_item * item,char * buf)566 static ssize_t remote_mac_show(struct config_item *item, char *buf)
567 {
568 return sysfs_emit(buf, "%pM\n", to_target(item)->np.remote_mac);
569 }
570
transmit_errors_show(struct config_item * item,char * buf)571 static ssize_t transmit_errors_show(struct config_item *item, char *buf)
572 {
573 struct netconsole_target *nt = to_target(item);
574 u64 xmit_drop_count, enomem_count;
575 unsigned int start;
576
577 do {
578 start = u64_stats_fetch_begin(&nt->stats.syncp);
579 xmit_drop_count = u64_stats_read(&nt->stats.xmit_drop_count);
580 enomem_count = u64_stats_read(&nt->stats.enomem_count);
581 } while (u64_stats_fetch_retry(&nt->stats.syncp, start));
582
583 return sysfs_emit(buf, "%llu\n", xmit_drop_count + enomem_count);
584 }
585
586 /* configfs helper to display if cpu_nr sysdata feature is enabled */
sysdata_cpu_nr_enabled_show(struct config_item * item,char * buf)587 static ssize_t sysdata_cpu_nr_enabled_show(struct config_item *item, char *buf)
588 {
589 struct netconsole_target *nt = to_target(item->ci_parent);
590 bool cpu_nr_enabled;
591
592 dynamic_netconsole_mutex_lock();
593 cpu_nr_enabled = !!(nt->sysdata_fields & SYSDATA_CPU_NR);
594 dynamic_netconsole_mutex_unlock();
595
596 return sysfs_emit(buf, "%d\n", cpu_nr_enabled);
597 }
598
599 /* configfs helper to display if taskname sysdata feature is enabled */
sysdata_taskname_enabled_show(struct config_item * item,char * buf)600 static ssize_t sysdata_taskname_enabled_show(struct config_item *item,
601 char *buf)
602 {
603 struct netconsole_target *nt = to_target(item->ci_parent);
604 bool taskname_enabled;
605
606 dynamic_netconsole_mutex_lock();
607 taskname_enabled = !!(nt->sysdata_fields & SYSDATA_TASKNAME);
608 dynamic_netconsole_mutex_unlock();
609
610 return sysfs_emit(buf, "%d\n", taskname_enabled);
611 }
612
sysdata_release_enabled_show(struct config_item * item,char * buf)613 static ssize_t sysdata_release_enabled_show(struct config_item *item,
614 char *buf)
615 {
616 struct netconsole_target *nt = to_target(item->ci_parent);
617 bool release_enabled;
618
619 dynamic_netconsole_mutex_lock();
620 release_enabled = !!(nt->sysdata_fields & SYSDATA_TASKNAME);
621 dynamic_netconsole_mutex_unlock();
622
623 return sysfs_emit(buf, "%d\n", release_enabled);
624 }
625
626 /* Iterate in the list of target, and make sure we don't have any console
627 * register without targets of the same type
628 */
unregister_netcons_consoles(void)629 static void unregister_netcons_consoles(void)
630 {
631 struct netconsole_target *nt;
632 u32 console_type_needed = 0;
633 unsigned long flags;
634
635 spin_lock_irqsave(&target_list_lock, flags);
636 list_for_each_entry(nt, &target_list, list) {
637 if (nt->extended)
638 console_type_needed |= CONS_EXTENDED;
639 else
640 console_type_needed |= CONS_BASIC;
641 }
642 spin_unlock_irqrestore(&target_list_lock, flags);
643
644 if (!(console_type_needed & CONS_EXTENDED) &&
645 console_is_registered(&netconsole_ext))
646 unregister_console(&netconsole_ext);
647
648 if (!(console_type_needed & CONS_BASIC) &&
649 console_is_registered(&netconsole))
650 unregister_console(&netconsole);
651 }
652
sysdata_msgid_enabled_show(struct config_item * item,char * buf)653 static ssize_t sysdata_msgid_enabled_show(struct config_item *item,
654 char *buf)
655 {
656 struct netconsole_target *nt = to_target(item->ci_parent);
657 bool msgid_enabled;
658
659 dynamic_netconsole_mutex_lock();
660 msgid_enabled = !!(nt->sysdata_fields & SYSDATA_MSGID);
661 dynamic_netconsole_mutex_unlock();
662
663 return sysfs_emit(buf, "%d\n", msgid_enabled);
664 }
665
666 /*
667 * This one is special -- targets created through the configfs interface
668 * are not enabled (and the corresponding netpoll activated) by default.
669 * The user is expected to set the desired parameters first (which
670 * would enable him to dynamically add new netpoll targets for new
671 * network interfaces as and when they come up).
672 */
enabled_store(struct config_item * item,const char * buf,size_t count)673 static ssize_t enabled_store(struct config_item *item,
674 const char *buf, size_t count)
675 {
676 struct netconsole_target *nt = to_target(item);
677 bool enabled, current_enabled;
678 unsigned long flags;
679 ssize_t ret;
680
681 dynamic_netconsole_mutex_lock();
682 ret = kstrtobool(buf, &enabled);
683 if (ret)
684 goto out_unlock;
685
686 /* When the user explicitly enables or disables a target that is
687 * currently deactivated, reset its state to disabled. The DEACTIVATED
688 * state only tracks interface-driven deactivation and should _not_
689 * persist when the user manually changes the target's enabled state.
690 */
691 if (nt->state == STATE_DEACTIVATED)
692 nt->state = STATE_DISABLED;
693
694 ret = -EINVAL;
695 current_enabled = nt->state == STATE_ENABLED;
696 if (enabled == current_enabled) {
697 pr_info("network logging has already %s\n",
698 current_enabled ? "started" : "stopped");
699 goto out_unlock;
700 }
701
702 if (enabled) { /* true */
703 if (nt->release && !nt->extended) {
704 pr_err("Not enabling netconsole. Release feature requires extended log message");
705 goto out_unlock;
706 }
707
708 if (nt->extended && !console_is_registered(&netconsole_ext)) {
709 netconsole_ext.flags |= CON_ENABLED;
710 register_console(&netconsole_ext);
711 }
712
713 /* User might be enabling the basic format target for the very
714 * first time, make sure the console is registered.
715 */
716 if (!nt->extended && !console_is_registered(&netconsole)) {
717 netconsole.flags |= CON_ENABLED;
718 register_console(&netconsole);
719 }
720
721 /*
722 * Skip netconsole_parser_cmdline() -- all the attributes are
723 * already configured via configfs. Just print them out.
724 */
725 netconsole_print_banner(&nt->np);
726
727 ret = netpoll_setup(&nt->np);
728 if (ret)
729 goto out_unlock;
730
731 nt->state = STATE_ENABLED;
732 pr_info("network logging started\n");
733 } else { /* false */
734 /* We need to disable the netconsole before cleaning it up
735 * otherwise we might end up in write_msg() with
736 * nt->np.dev == NULL and nt->state == STATE_ENABLED
737 */
738 mutex_lock(&target_cleanup_list_lock);
739 spin_lock_irqsave(&target_list_lock, flags);
740 nt->state = STATE_DISABLED;
741 /* Remove the target from the list, while holding
742 * target_list_lock
743 */
744 list_move(&nt->list, &target_cleanup_list);
745 spin_unlock_irqrestore(&target_list_lock, flags);
746 mutex_unlock(&target_cleanup_list_lock);
747 /* Unregister consoles, whose the last target of that type got
748 * disabled.
749 */
750 unregister_netcons_consoles();
751 }
752
753 ret = strnlen(buf, count);
754 /* Deferred cleanup */
755 netconsole_process_cleanups();
756 out_unlock:
757 dynamic_netconsole_mutex_unlock();
758 return ret;
759 }
760
release_store(struct config_item * item,const char * buf,size_t count)761 static ssize_t release_store(struct config_item *item, const char *buf,
762 size_t count)
763 {
764 struct netconsole_target *nt = to_target(item);
765 bool release;
766 ssize_t ret;
767
768 dynamic_netconsole_mutex_lock();
769 if (nt->state == STATE_ENABLED) {
770 pr_err("target (%s) is enabled, disable to update parameters\n",
771 config_item_name(&nt->group.cg_item));
772 ret = -EINVAL;
773 goto out_unlock;
774 }
775
776 ret = kstrtobool(buf, &release);
777 if (ret)
778 goto out_unlock;
779
780 nt->release = release;
781
782 ret = strnlen(buf, count);
783 out_unlock:
784 dynamic_netconsole_mutex_unlock();
785 return ret;
786 }
787
extended_store(struct config_item * item,const char * buf,size_t count)788 static ssize_t extended_store(struct config_item *item, const char *buf,
789 size_t count)
790 {
791 struct netconsole_target *nt = to_target(item);
792 bool extended;
793 ssize_t ret;
794
795 dynamic_netconsole_mutex_lock();
796 if (nt->state == STATE_ENABLED) {
797 pr_err("target (%s) is enabled, disable to update parameters\n",
798 config_item_name(&nt->group.cg_item));
799 ret = -EINVAL;
800 goto out_unlock;
801 }
802
803 ret = kstrtobool(buf, &extended);
804 if (ret)
805 goto out_unlock;
806
807 nt->extended = extended;
808 ret = strnlen(buf, count);
809 out_unlock:
810 dynamic_netconsole_mutex_unlock();
811 return ret;
812 }
813
dev_name_store(struct config_item * item,const char * buf,size_t count)814 static ssize_t dev_name_store(struct config_item *item, const char *buf,
815 size_t count)
816 {
817 struct netconsole_target *nt = to_target(item);
818
819 dynamic_netconsole_mutex_lock();
820 if (nt->state == STATE_ENABLED) {
821 pr_err("target (%s) is enabled, disable to update parameters\n",
822 config_item_name(&nt->group.cg_item));
823 dynamic_netconsole_mutex_unlock();
824 return -EINVAL;
825 }
826
827 strscpy(nt->np.dev_name, buf, IFNAMSIZ);
828 trim_newline(nt->np.dev_name, IFNAMSIZ);
829
830 dynamic_netconsole_mutex_unlock();
831 return strnlen(buf, count);
832 }
833
local_port_store(struct config_item * item,const char * buf,size_t count)834 static ssize_t local_port_store(struct config_item *item, const char *buf,
835 size_t count)
836 {
837 struct netconsole_target *nt = to_target(item);
838 ssize_t ret = -EINVAL;
839
840 dynamic_netconsole_mutex_lock();
841 if (nt->state == STATE_ENABLED) {
842 pr_err("target (%s) is enabled, disable to update parameters\n",
843 config_item_name(&nt->group.cg_item));
844 goto out_unlock;
845 }
846
847 ret = kstrtou16(buf, 10, &nt->np.local_port);
848 if (ret < 0)
849 goto out_unlock;
850 ret = strnlen(buf, count);
851 out_unlock:
852 dynamic_netconsole_mutex_unlock();
853 return ret;
854 }
855
remote_port_store(struct config_item * item,const char * buf,size_t count)856 static ssize_t remote_port_store(struct config_item *item,
857 const char *buf, size_t count)
858 {
859 struct netconsole_target *nt = to_target(item);
860 ssize_t ret = -EINVAL;
861
862 dynamic_netconsole_mutex_lock();
863 if (nt->state == STATE_ENABLED) {
864 pr_err("target (%s) is enabled, disable to update parameters\n",
865 config_item_name(&nt->group.cg_item));
866 goto out_unlock;
867 }
868
869 ret = kstrtou16(buf, 10, &nt->np.remote_port);
870 if (ret < 0)
871 goto out_unlock;
872 ret = strnlen(buf, count);
873 out_unlock:
874 dynamic_netconsole_mutex_unlock();
875 return ret;
876 }
877
local_ip_store(struct config_item * item,const char * buf,size_t count)878 static ssize_t local_ip_store(struct config_item *item, const char *buf,
879 size_t count)
880 {
881 struct netconsole_target *nt = to_target(item);
882 ssize_t ret = -EINVAL;
883 int ipv6;
884
885 dynamic_netconsole_mutex_lock();
886 if (nt->state == STATE_ENABLED) {
887 pr_err("target (%s) is enabled, disable to update parameters\n",
888 config_item_name(&nt->group.cg_item));
889 goto out_unlock;
890 }
891
892 ipv6 = netpoll_parse_ip_addr(buf, &nt->np.local_ip);
893 if (ipv6 == -1)
894 goto out_unlock;
895 nt->np.ipv6 = !!ipv6;
896
897 ret = strnlen(buf, count);
898 out_unlock:
899 dynamic_netconsole_mutex_unlock();
900 return ret;
901 }
902
remote_ip_store(struct config_item * item,const char * buf,size_t count)903 static ssize_t remote_ip_store(struct config_item *item, const char *buf,
904 size_t count)
905 {
906 struct netconsole_target *nt = to_target(item);
907 ssize_t ret = -EINVAL;
908 int ipv6;
909
910 dynamic_netconsole_mutex_lock();
911 if (nt->state == STATE_ENABLED) {
912 pr_err("target (%s) is enabled, disable to update parameters\n",
913 config_item_name(&nt->group.cg_item));
914 goto out_unlock;
915 }
916
917 ipv6 = netpoll_parse_ip_addr(buf, &nt->np.remote_ip);
918 if (ipv6 == -1)
919 goto out_unlock;
920 nt->np.ipv6 = !!ipv6;
921
922 ret = strnlen(buf, count);
923 out_unlock:
924 dynamic_netconsole_mutex_unlock();
925 return ret;
926 }
927
928 /* Count number of entries we have in userdata.
929 * This is important because userdata only supports MAX_USERDATA_ITEMS
930 * entries. Before enabling any new userdata feature, number of entries needs
931 * to checked for available space.
932 */
count_userdata_entries(struct netconsole_target * nt)933 static size_t count_userdata_entries(struct netconsole_target *nt)
934 {
935 return list_count_nodes(&nt->userdata_group.cg_children);
936 }
937
remote_mac_store(struct config_item * item,const char * buf,size_t count)938 static ssize_t remote_mac_store(struct config_item *item, const char *buf,
939 size_t count)
940 {
941 struct netconsole_target *nt = to_target(item);
942 u8 remote_mac[ETH_ALEN];
943 ssize_t ret = -EINVAL;
944
945 dynamic_netconsole_mutex_lock();
946 if (nt->state == STATE_ENABLED) {
947 pr_err("target (%s) is enabled, disable to update parameters\n",
948 config_item_name(&nt->group.cg_item));
949 goto out_unlock;
950 }
951
952 if (!mac_pton(buf, remote_mac))
953 goto out_unlock;
954 if (buf[MAC_ADDR_STR_LEN] && buf[MAC_ADDR_STR_LEN] != '\n')
955 goto out_unlock;
956 memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
957
958 ret = strnlen(buf, count);
959 out_unlock:
960 dynamic_netconsole_mutex_unlock();
961 return ret;
962 }
963
964 struct userdatum {
965 struct config_item item;
966 char value[MAX_EXTRADATA_VALUE_LEN];
967 };
968
to_userdatum(struct config_item * item)969 static struct userdatum *to_userdatum(struct config_item *item)
970 {
971 return container_of(item, struct userdatum, item);
972 }
973
974 struct userdata {
975 struct config_group group;
976 };
977
to_userdata(struct config_item * item)978 static struct userdata *to_userdata(struct config_item *item)
979 {
980 return container_of(to_config_group(item), struct userdata, group);
981 }
982
userdata_to_target(struct userdata * ud)983 static struct netconsole_target *userdata_to_target(struct userdata *ud)
984 {
985 struct config_group *netconsole_group;
986
987 netconsole_group = to_config_group(ud->group.cg_item.ci_parent);
988 return to_target(&netconsole_group->cg_item);
989 }
990
userdatum_value_show(struct config_item * item,char * buf)991 static ssize_t userdatum_value_show(struct config_item *item, char *buf)
992 {
993 return sysfs_emit(buf, "%s\n", &(to_userdatum(item)->value[0]));
994 }
995
996 /* Navigate configfs and calculate the lentgh of the formatted string
997 * representing userdata.
998 * Must be called holding netconsole_subsys.su_mutex
999 */
calc_userdata_len(struct netconsole_target * nt)1000 static int calc_userdata_len(struct netconsole_target *nt)
1001 {
1002 struct userdatum *udm_item;
1003 struct config_item *item;
1004 struct list_head *entry;
1005 int len = 0;
1006
1007 list_for_each(entry, &nt->userdata_group.cg_children) {
1008 item = container_of(entry, struct config_item, ci_entry);
1009 udm_item = to_userdatum(item);
1010 /* Skip userdata with no value set */
1011 if (udm_item->value[0]) {
1012 len += snprintf(NULL, 0, " %s=%s\n", item->ci_name,
1013 udm_item->value);
1014 }
1015 }
1016 return len;
1017 }
1018
update_userdata(struct netconsole_target * nt)1019 static int update_userdata(struct netconsole_target *nt)
1020 {
1021 struct userdatum *udm_item;
1022 struct config_item *item;
1023 struct list_head *entry;
1024 char *old_buf = NULL;
1025 char *new_buf = NULL;
1026 unsigned long flags;
1027 int offset = 0;
1028 int len;
1029
1030 /* Calculate required buffer size */
1031 len = calc_userdata_len(nt);
1032
1033 if (WARN_ON_ONCE(len > MAX_EXTRADATA_ENTRY_LEN * MAX_USERDATA_ITEMS))
1034 return -ENOSPC;
1035
1036 /* Allocate new buffer */
1037 if (len) {
1038 new_buf = kmalloc(len + 1, GFP_KERNEL);
1039 if (!new_buf)
1040 return -ENOMEM;
1041 }
1042
1043 /* Write userdata to new buffer */
1044 list_for_each(entry, &nt->userdata_group.cg_children) {
1045 item = container_of(entry, struct config_item, ci_entry);
1046 udm_item = to_userdatum(item);
1047 /* Skip userdata with no value set */
1048 if (udm_item->value[0]) {
1049 offset += scnprintf(&new_buf[offset], len + 1 - offset,
1050 " %s=%s\n", item->ci_name,
1051 udm_item->value);
1052 }
1053 }
1054
1055 WARN_ON_ONCE(offset != len);
1056
1057 /* Switch to new buffer and free old buffer */
1058 spin_lock_irqsave(&target_list_lock, flags);
1059 old_buf = nt->userdata;
1060 nt->userdata = new_buf;
1061 nt->userdata_length = offset;
1062 spin_unlock_irqrestore(&target_list_lock, flags);
1063
1064 kfree(old_buf);
1065
1066 return 0;
1067 }
1068
userdatum_value_store(struct config_item * item,const char * buf,size_t count)1069 static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
1070 size_t count)
1071 {
1072 struct userdatum *udm = to_userdatum(item);
1073 struct netconsole_target *nt;
1074 struct userdata *ud;
1075 ssize_t ret;
1076
1077 if (count > MAX_EXTRADATA_VALUE_LEN)
1078 return -EMSGSIZE;
1079
1080 mutex_lock(&netconsole_subsys.su_mutex);
1081 dynamic_netconsole_mutex_lock();
1082
1083 ret = strscpy(udm->value, buf, sizeof(udm->value));
1084 if (ret < 0)
1085 goto out_unlock;
1086 trim_newline(udm->value, sizeof(udm->value));
1087
1088 ud = to_userdata(item->ci_parent);
1089 nt = userdata_to_target(ud);
1090 ret = update_userdata(nt);
1091 if (ret < 0)
1092 goto out_unlock;
1093 ret = count;
1094 out_unlock:
1095 dynamic_netconsole_mutex_unlock();
1096 mutex_unlock(&netconsole_subsys.su_mutex);
1097 return ret;
1098 }
1099
1100 /* disable_sysdata_feature - Disable sysdata feature and clean sysdata
1101 * @nt: target that is disabling the feature
1102 * @feature: feature being disabled
1103 */
disable_sysdata_feature(struct netconsole_target * nt,enum sysdata_feature feature)1104 static void disable_sysdata_feature(struct netconsole_target *nt,
1105 enum sysdata_feature feature)
1106 {
1107 nt->sysdata_fields &= ~feature;
1108 nt->sysdata[0] = 0;
1109 }
1110
sysdata_msgid_enabled_store(struct config_item * item,const char * buf,size_t count)1111 static ssize_t sysdata_msgid_enabled_store(struct config_item *item,
1112 const char *buf, size_t count)
1113 {
1114 struct netconsole_target *nt = to_target(item->ci_parent);
1115 bool msgid_enabled, curr;
1116 ssize_t ret;
1117
1118 ret = kstrtobool(buf, &msgid_enabled);
1119 if (ret)
1120 return ret;
1121
1122 mutex_lock(&netconsole_subsys.su_mutex);
1123 dynamic_netconsole_mutex_lock();
1124 curr = !!(nt->sysdata_fields & SYSDATA_MSGID);
1125 if (msgid_enabled == curr)
1126 goto unlock_ok;
1127
1128 if (msgid_enabled)
1129 nt->sysdata_fields |= SYSDATA_MSGID;
1130 else
1131 disable_sysdata_feature(nt, SYSDATA_MSGID);
1132
1133 unlock_ok:
1134 ret = strnlen(buf, count);
1135 dynamic_netconsole_mutex_unlock();
1136 mutex_unlock(&netconsole_subsys.su_mutex);
1137 return ret;
1138 }
1139
sysdata_release_enabled_store(struct config_item * item,const char * buf,size_t count)1140 static ssize_t sysdata_release_enabled_store(struct config_item *item,
1141 const char *buf, size_t count)
1142 {
1143 struct netconsole_target *nt = to_target(item->ci_parent);
1144 bool release_enabled, curr;
1145 ssize_t ret;
1146
1147 ret = kstrtobool(buf, &release_enabled);
1148 if (ret)
1149 return ret;
1150
1151 mutex_lock(&netconsole_subsys.su_mutex);
1152 dynamic_netconsole_mutex_lock();
1153 curr = !!(nt->sysdata_fields & SYSDATA_RELEASE);
1154 if (release_enabled == curr)
1155 goto unlock_ok;
1156
1157 if (release_enabled)
1158 nt->sysdata_fields |= SYSDATA_RELEASE;
1159 else
1160 disable_sysdata_feature(nt, SYSDATA_RELEASE);
1161
1162 unlock_ok:
1163 ret = strnlen(buf, count);
1164 dynamic_netconsole_mutex_unlock();
1165 mutex_unlock(&netconsole_subsys.su_mutex);
1166 return ret;
1167 }
1168
sysdata_taskname_enabled_store(struct config_item * item,const char * buf,size_t count)1169 static ssize_t sysdata_taskname_enabled_store(struct config_item *item,
1170 const char *buf, size_t count)
1171 {
1172 struct netconsole_target *nt = to_target(item->ci_parent);
1173 bool taskname_enabled, curr;
1174 ssize_t ret;
1175
1176 ret = kstrtobool(buf, &taskname_enabled);
1177 if (ret)
1178 return ret;
1179
1180 mutex_lock(&netconsole_subsys.su_mutex);
1181 dynamic_netconsole_mutex_lock();
1182 curr = !!(nt->sysdata_fields & SYSDATA_TASKNAME);
1183 if (taskname_enabled == curr)
1184 goto unlock_ok;
1185
1186 if (taskname_enabled)
1187 nt->sysdata_fields |= SYSDATA_TASKNAME;
1188 else
1189 disable_sysdata_feature(nt, SYSDATA_TASKNAME);
1190
1191 unlock_ok:
1192 ret = strnlen(buf, count);
1193 dynamic_netconsole_mutex_unlock();
1194 mutex_unlock(&netconsole_subsys.su_mutex);
1195 return ret;
1196 }
1197
1198 /* configfs helper to sysdata cpu_nr feature */
sysdata_cpu_nr_enabled_store(struct config_item * item,const char * buf,size_t count)1199 static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item,
1200 const char *buf, size_t count)
1201 {
1202 struct netconsole_target *nt = to_target(item->ci_parent);
1203 bool cpu_nr_enabled, curr;
1204 ssize_t ret;
1205
1206 ret = kstrtobool(buf, &cpu_nr_enabled);
1207 if (ret)
1208 return ret;
1209
1210 mutex_lock(&netconsole_subsys.su_mutex);
1211 dynamic_netconsole_mutex_lock();
1212 curr = !!(nt->sysdata_fields & SYSDATA_CPU_NR);
1213 if (cpu_nr_enabled == curr)
1214 /* no change requested */
1215 goto unlock_ok;
1216
1217 if (cpu_nr_enabled)
1218 nt->sysdata_fields |= SYSDATA_CPU_NR;
1219 else
1220 /* This is special because sysdata might have remaining data
1221 * from previous sysdata, and it needs to be cleaned.
1222 */
1223 disable_sysdata_feature(nt, SYSDATA_CPU_NR);
1224
1225 unlock_ok:
1226 ret = strnlen(buf, count);
1227 dynamic_netconsole_mutex_unlock();
1228 mutex_unlock(&netconsole_subsys.su_mutex);
1229 return ret;
1230 }
1231
1232 CONFIGFS_ATTR(userdatum_, value);
1233 CONFIGFS_ATTR(sysdata_, cpu_nr_enabled);
1234 CONFIGFS_ATTR(sysdata_, taskname_enabled);
1235 CONFIGFS_ATTR(sysdata_, release_enabled);
1236 CONFIGFS_ATTR(sysdata_, msgid_enabled);
1237
1238 static struct configfs_attribute *userdatum_attrs[] = {
1239 &userdatum_attr_value,
1240 NULL,
1241 };
1242
userdatum_release(struct config_item * item)1243 static void userdatum_release(struct config_item *item)
1244 {
1245 kfree(to_userdatum(item));
1246 }
1247
1248 static struct configfs_item_operations userdatum_ops = {
1249 .release = userdatum_release,
1250 };
1251
1252 static const struct config_item_type userdatum_type = {
1253 .ct_item_ops = &userdatum_ops,
1254 .ct_attrs = userdatum_attrs,
1255 .ct_owner = THIS_MODULE,
1256 };
1257
userdatum_make_item(struct config_group * group,const char * name)1258 static struct config_item *userdatum_make_item(struct config_group *group,
1259 const char *name)
1260 {
1261 struct netconsole_target *nt;
1262 struct userdatum *udm;
1263 struct userdata *ud;
1264
1265 if (strlen(name) > MAX_EXTRADATA_NAME_LEN)
1266 return ERR_PTR(-ENAMETOOLONG);
1267
1268 ud = to_userdata(&group->cg_item);
1269 nt = userdata_to_target(ud);
1270 if (count_userdata_entries(nt) >= MAX_USERDATA_ITEMS)
1271 return ERR_PTR(-ENOSPC);
1272
1273 udm = kzalloc_obj(*udm, GFP_KERNEL);
1274 if (!udm)
1275 return ERR_PTR(-ENOMEM);
1276
1277 config_item_init_type_name(&udm->item, name, &userdatum_type);
1278 return &udm->item;
1279 }
1280
userdatum_drop(struct config_group * group,struct config_item * item)1281 static void userdatum_drop(struct config_group *group, struct config_item *item)
1282 {
1283 struct netconsole_target *nt;
1284 struct userdata *ud;
1285
1286 ud = to_userdata(&group->cg_item);
1287 nt = userdata_to_target(ud);
1288
1289 dynamic_netconsole_mutex_lock();
1290 update_userdata(nt);
1291 config_item_put(item);
1292 dynamic_netconsole_mutex_unlock();
1293 }
1294
1295 static struct configfs_attribute *userdata_attrs[] = {
1296 &sysdata_attr_cpu_nr_enabled,
1297 &sysdata_attr_taskname_enabled,
1298 &sysdata_attr_release_enabled,
1299 &sysdata_attr_msgid_enabled,
1300 NULL,
1301 };
1302
1303 static struct configfs_group_operations userdata_ops = {
1304 .make_item = userdatum_make_item,
1305 .drop_item = userdatum_drop,
1306 };
1307
1308 static const struct config_item_type userdata_type = {
1309 .ct_item_ops = &userdatum_ops,
1310 .ct_group_ops = &userdata_ops,
1311 .ct_attrs = userdata_attrs,
1312 .ct_owner = THIS_MODULE,
1313 };
1314
1315 CONFIGFS_ATTR(, enabled);
1316 CONFIGFS_ATTR(, extended);
1317 CONFIGFS_ATTR(, dev_name);
1318 CONFIGFS_ATTR(, local_port);
1319 CONFIGFS_ATTR(, remote_port);
1320 CONFIGFS_ATTR(, local_ip);
1321 CONFIGFS_ATTR(, remote_ip);
1322 CONFIGFS_ATTR_RO(, local_mac);
1323 CONFIGFS_ATTR(, remote_mac);
1324 CONFIGFS_ATTR(, release);
1325 CONFIGFS_ATTR_RO(, transmit_errors);
1326
1327 static struct configfs_attribute *netconsole_target_attrs[] = {
1328 &attr_enabled,
1329 &attr_extended,
1330 &attr_release,
1331 &attr_dev_name,
1332 &attr_local_port,
1333 &attr_remote_port,
1334 &attr_local_ip,
1335 &attr_remote_ip,
1336 &attr_local_mac,
1337 &attr_remote_mac,
1338 &attr_transmit_errors,
1339 NULL,
1340 };
1341
1342 /*
1343 * Item operations and type for netconsole_target.
1344 */
1345
netconsole_target_release(struct config_item * item)1346 static void netconsole_target_release(struct config_item *item)
1347 {
1348 struct netconsole_target *nt = to_target(item);
1349
1350 kfree(nt->userdata);
1351 kfree(nt);
1352 }
1353
1354 static struct configfs_item_operations netconsole_target_item_ops = {
1355 .release = netconsole_target_release,
1356 };
1357
1358 static const struct config_item_type netconsole_target_type = {
1359 .ct_attrs = netconsole_target_attrs,
1360 .ct_item_ops = &netconsole_target_item_ops,
1361 .ct_owner = THIS_MODULE,
1362 };
1363
init_target_config_group(struct netconsole_target * nt,const char * name)1364 static void init_target_config_group(struct netconsole_target *nt,
1365 const char *name)
1366 {
1367 config_group_init_type_name(&nt->group, name, &netconsole_target_type);
1368 config_group_init_type_name(&nt->userdata_group, "userdata",
1369 &userdata_type);
1370 configfs_add_default_group(&nt->userdata_group, &nt->group);
1371 }
1372
find_cmdline_target(const char * name)1373 static struct netconsole_target *find_cmdline_target(const char *name)
1374 {
1375 struct netconsole_target *nt, *ret = NULL;
1376 unsigned long flags;
1377
1378 spin_lock_irqsave(&target_list_lock, flags);
1379 list_for_each_entry(nt, &target_list, list) {
1380 if (!strcmp(nt->group.cg_item.ci_name, name)) {
1381 ret = nt;
1382 break;
1383 }
1384 }
1385 spin_unlock_irqrestore(&target_list_lock, flags);
1386
1387 return ret;
1388 }
1389
1390 /*
1391 * Group operations and type for netconsole_subsys.
1392 */
1393
make_netconsole_target(struct config_group * group,const char * name)1394 static struct config_group *make_netconsole_target(struct config_group *group,
1395 const char *name)
1396 {
1397 struct netconsole_target *nt;
1398 unsigned long flags;
1399
1400 /* Checking if a target by this name was created at boot time. If so,
1401 * attach a configfs entry to that target. This enables dynamic
1402 * control.
1403 */
1404 if (!strncmp(name, NETCONSOLE_PARAM_TARGET_PREFIX,
1405 strlen(NETCONSOLE_PARAM_TARGET_PREFIX))) {
1406 nt = find_cmdline_target(name);
1407 if (nt) {
1408 init_target_config_group(nt, name);
1409 return &nt->group;
1410 }
1411 }
1412
1413 nt = alloc_and_init();
1414 if (!nt)
1415 return ERR_PTR(-ENOMEM);
1416
1417 /* Initialize the config_group member */
1418 init_target_config_group(nt, name);
1419
1420 /* Adding, but it is disabled */
1421 spin_lock_irqsave(&target_list_lock, flags);
1422 list_add(&nt->list, &target_list);
1423 spin_unlock_irqrestore(&target_list_lock, flags);
1424
1425 return &nt->group;
1426 }
1427
drop_netconsole_target(struct config_group * group,struct config_item * item)1428 static void drop_netconsole_target(struct config_group *group,
1429 struct config_item *item)
1430 {
1431 struct netconsole_target *nt = to_target(item);
1432 unsigned long flags;
1433
1434 dynamic_netconsole_mutex_lock();
1435
1436 spin_lock_irqsave(&target_list_lock, flags);
1437 /* Disable deactivated target to prevent races between resume attempt
1438 * and target removal.
1439 */
1440 if (nt->state == STATE_DEACTIVATED)
1441 nt->state = STATE_DISABLED;
1442 list_del(&nt->list);
1443 spin_unlock_irqrestore(&target_list_lock, flags);
1444
1445 dynamic_netconsole_mutex_unlock();
1446
1447 /* Now that the target has been marked disabled no further work
1448 * can be scheduled. Existing work will skip as targets are not
1449 * deactivated anymore. Cancel any scheduled resume and wait for
1450 * completion.
1451 */
1452 cancel_work_sync(&nt->resume_wq);
1453
1454 /*
1455 * The target may have never been enabled, or was manually disabled
1456 * before being removed so netpoll may have already been cleaned up.
1457 */
1458 if (nt->state == STATE_ENABLED)
1459 netpoll_cleanup(&nt->np);
1460
1461 config_item_put(&nt->group.cg_item);
1462 }
1463
1464 static struct configfs_group_operations netconsole_subsys_group_ops = {
1465 .make_group = make_netconsole_target,
1466 .drop_item = drop_netconsole_target,
1467 };
1468
1469 static const struct config_item_type netconsole_subsys_type = {
1470 .ct_group_ops = &netconsole_subsys_group_ops,
1471 .ct_owner = THIS_MODULE,
1472 };
1473
1474 /* The netconsole configfs subsystem */
1475 static struct configfs_subsystem netconsole_subsys = {
1476 .su_group = {
1477 .cg_item = {
1478 .ci_namebuf = "netconsole",
1479 .ci_type = &netconsole_subsys_type,
1480 },
1481 },
1482 };
1483
populate_configfs_item(struct netconsole_target * nt,int cmdline_count)1484 static void populate_configfs_item(struct netconsole_target *nt,
1485 int cmdline_count)
1486 {
1487 char target_name[16];
1488
1489 snprintf(target_name, sizeof(target_name), "%s%d",
1490 NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);
1491 init_target_config_group(nt, target_name);
1492 }
1493
sysdata_append_cpu_nr(struct netconsole_target * nt,int offset,struct nbcon_write_context * wctxt)1494 static int sysdata_append_cpu_nr(struct netconsole_target *nt, int offset,
1495 struct nbcon_write_context *wctxt)
1496 {
1497 return scnprintf(&nt->sysdata[offset],
1498 MAX_EXTRADATA_ENTRY_LEN, " cpu=%u\n",
1499 wctxt->cpu);
1500 }
1501
sysdata_append_taskname(struct netconsole_target * nt,int offset,struct nbcon_write_context * wctxt)1502 static int sysdata_append_taskname(struct netconsole_target *nt, int offset,
1503 struct nbcon_write_context *wctxt)
1504 {
1505 return scnprintf(&nt->sysdata[offset],
1506 MAX_EXTRADATA_ENTRY_LEN, " taskname=%s\n",
1507 wctxt->comm);
1508 }
1509
sysdata_append_release(struct netconsole_target * nt,int offset)1510 static int sysdata_append_release(struct netconsole_target *nt, int offset)
1511 {
1512 return scnprintf(&nt->sysdata[offset],
1513 MAX_EXTRADATA_ENTRY_LEN, " release=%s\n",
1514 init_utsname()->release);
1515 }
1516
sysdata_append_msgid(struct netconsole_target * nt,int offset)1517 static int sysdata_append_msgid(struct netconsole_target *nt, int offset)
1518 {
1519 wrapping_assign_add(nt->msgcounter, 1);
1520 return scnprintf(&nt->sysdata[offset],
1521 MAX_EXTRADATA_ENTRY_LEN, " msgid=%u\n",
1522 nt->msgcounter);
1523 }
1524
1525 /*
1526 * prepare_sysdata - append sysdata in runtime
1527 * @nt: target to send message to
1528 * @wctxt: nbcon write context containing message metadata
1529 */
prepare_sysdata(struct netconsole_target * nt,struct nbcon_write_context * wctxt)1530 static int prepare_sysdata(struct netconsole_target *nt,
1531 struct nbcon_write_context *wctxt)
1532 {
1533 int sysdata_len = 0;
1534
1535 if (!nt->sysdata_fields)
1536 goto out;
1537
1538 if (nt->sysdata_fields & SYSDATA_CPU_NR)
1539 sysdata_len += sysdata_append_cpu_nr(nt, sysdata_len, wctxt);
1540 if (nt->sysdata_fields & SYSDATA_TASKNAME)
1541 sysdata_len += sysdata_append_taskname(nt, sysdata_len, wctxt);
1542 if (nt->sysdata_fields & SYSDATA_RELEASE)
1543 sysdata_len += sysdata_append_release(nt, sysdata_len);
1544 if (nt->sysdata_fields & SYSDATA_MSGID)
1545 sysdata_len += sysdata_append_msgid(nt, sysdata_len);
1546
1547 WARN_ON_ONCE(sysdata_len >
1548 MAX_EXTRADATA_ENTRY_LEN * MAX_SYSDATA_ITEMS);
1549
1550 out:
1551 return sysdata_len;
1552 }
1553 #endif /* CONFIG_NETCONSOLE_DYNAMIC */
1554
1555 /* Handle network interface device notifications */
netconsole_netdev_event(struct notifier_block * this,unsigned long event,void * ptr)1556 static int netconsole_netdev_event(struct notifier_block *this,
1557 unsigned long event, void *ptr)
1558 {
1559 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1560 struct netconsole_target *nt, *tmp;
1561 bool stopped = false;
1562 unsigned long flags;
1563
1564 if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER ||
1565 event == NETDEV_RELEASE || event == NETDEV_JOIN ||
1566 event == NETDEV_REGISTER))
1567 goto done;
1568
1569 mutex_lock(&target_cleanup_list_lock);
1570 spin_lock_irqsave(&target_list_lock, flags);
1571 list_for_each_entry_safe(nt, tmp, &target_list, list) {
1572 netconsole_target_get(nt);
1573 if (nt->np.dev == dev) {
1574 switch (event) {
1575 case NETDEV_CHANGENAME:
1576 strscpy(nt->np.dev_name, dev->name, IFNAMSIZ);
1577 break;
1578 case NETDEV_RELEASE:
1579 case NETDEV_JOIN:
1580 /* transition target to DISABLED instead of
1581 * DEACTIVATED when (de)enslaving devices as
1582 * their targets should not be automatically
1583 * resumed when the interface is brought up.
1584 */
1585 nt->state = STATE_DISABLED;
1586 list_move(&nt->list, &target_cleanup_list);
1587 stopped = true;
1588 break;
1589 case NETDEV_UNREGISTER:
1590 nt->state = STATE_DEACTIVATED;
1591 list_move(&nt->list, &target_cleanup_list);
1592 stopped = true;
1593 }
1594 }
1595 if ((event == NETDEV_REGISTER || event == NETDEV_CHANGENAME) &&
1596 deactivated_target_match(nt, dev))
1597 /* Schedule resume on a workqueue as it will attempt
1598 * to UP the device, which can't be done as part of this
1599 * notifier.
1600 */
1601 queue_work(netconsole_wq, &nt->resume_wq);
1602 netconsole_target_put(nt);
1603 }
1604 spin_unlock_irqrestore(&target_list_lock, flags);
1605 mutex_unlock(&target_cleanup_list_lock);
1606
1607 if (stopped) {
1608 const char *msg = "had an event";
1609
1610 switch (event) {
1611 case NETDEV_UNREGISTER:
1612 msg = "unregistered";
1613 break;
1614 case NETDEV_RELEASE:
1615 msg = "released slaves";
1616 break;
1617 case NETDEV_JOIN:
1618 msg = "is joining a master device";
1619 break;
1620 }
1621 pr_info("network logging stopped on interface %s as it %s\n",
1622 dev->name, msg);
1623 }
1624
1625 /* Process target_cleanup_list entries. By the end, target_cleanup_list
1626 * should be empty
1627 */
1628 netconsole_process_cleanups_core();
1629
1630 done:
1631 return NOTIFY_DONE;
1632 }
1633
1634 static struct notifier_block netconsole_netdev_notifier = {
1635 .notifier_call = netconsole_netdev_event,
1636 };
1637
1638 /**
1639 * send_udp - Wrapper for netpoll_send_udp that counts errors
1640 * @nt: target to send message to
1641 * @msg: message to send
1642 * @len: length of message
1643 *
1644 * Calls netpoll_send_udp and classifies the return value. If an error
1645 * occurred it increments statistics in nt->stats accordingly.
1646 * Only calls netpoll_send_udp if CONFIG_NETCONSOLE_DYNAMIC is disabled.
1647 */
send_udp(struct netconsole_target * nt,const char * msg,int len)1648 static void send_udp(struct netconsole_target *nt, const char *msg, int len)
1649 {
1650 int result = netpoll_send_udp(&nt->np, msg, len);
1651
1652 if (IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC)) {
1653 if (result == NET_XMIT_DROP) {
1654 u64_stats_update_begin(&nt->stats.syncp);
1655 u64_stats_inc(&nt->stats.xmit_drop_count);
1656 u64_stats_update_end(&nt->stats.syncp);
1657 } else if (result == -ENOMEM) {
1658 u64_stats_update_begin(&nt->stats.syncp);
1659 u64_stats_inc(&nt->stats.enomem_count);
1660 u64_stats_update_end(&nt->stats.syncp);
1661 }
1662 }
1663 }
1664
send_msg_no_fragmentation(struct netconsole_target * nt,const char * msg,int msg_len,int release_len)1665 static void send_msg_no_fragmentation(struct netconsole_target *nt,
1666 const char *msg,
1667 int msg_len,
1668 int release_len)
1669 {
1670 const char *userdata = NULL;
1671 const char *sysdata = NULL;
1672 const char *release;
1673
1674 #ifdef CONFIG_NETCONSOLE_DYNAMIC
1675 userdata = nt->userdata;
1676 sysdata = nt->sysdata;
1677 #endif
1678
1679 if (release_len) {
1680 release = init_utsname()->release;
1681
1682 scnprintf(nt->buf, MAX_PRINT_CHUNK, "%s,%s", release, msg);
1683 msg_len += release_len;
1684 } else {
1685 memcpy(nt->buf, msg, msg_len);
1686 }
1687
1688 if (userdata)
1689 msg_len += scnprintf(&nt->buf[msg_len],
1690 MAX_PRINT_CHUNK - msg_len, "%s",
1691 userdata);
1692
1693 if (sysdata)
1694 msg_len += scnprintf(&nt->buf[msg_len],
1695 MAX_PRINT_CHUNK - msg_len, "%s",
1696 sysdata);
1697
1698 send_udp(nt, nt->buf, msg_len);
1699 }
1700
append_release(char * buf)1701 static void append_release(char *buf)
1702 {
1703 const char *release;
1704
1705 release = init_utsname()->release;
1706 scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
1707 }
1708
send_fragmented_body(struct netconsole_target * nt,const char * msgbody_ptr,int header_len,int msgbody_len,int sysdata_len)1709 static void send_fragmented_body(struct netconsole_target *nt,
1710 const char *msgbody_ptr, int header_len,
1711 int msgbody_len, int sysdata_len)
1712 {
1713 const char *userdata_ptr = NULL;
1714 const char *sysdata_ptr = NULL;
1715 int data_len, data_sent = 0;
1716 int userdata_offset = 0;
1717 int sysdata_offset = 0;
1718 int msgbody_offset = 0;
1719 int userdata_len = 0;
1720
1721 #ifdef CONFIG_NETCONSOLE_DYNAMIC
1722 userdata_ptr = nt->userdata;
1723 sysdata_ptr = nt->sysdata;
1724 userdata_len = nt->userdata_length;
1725 #endif
1726 if (WARN_ON_ONCE(!userdata_ptr && userdata_len != 0))
1727 return;
1728
1729 if (WARN_ON_ONCE(!sysdata_ptr && sysdata_len != 0))
1730 return;
1731
1732 /* data_len represents the number of bytes that will be sent. This is
1733 * bigger than MAX_PRINT_CHUNK, thus, it will be split in multiple
1734 * packets
1735 */
1736 data_len = msgbody_len + userdata_len + sysdata_len;
1737
1738 /* In each iteration of the while loop below, we send a packet
1739 * containing the header and a portion of the data. The data is
1740 * composed of three parts: msgbody, userdata, and sysdata.
1741 * We keep track of how many bytes have been sent from each part using
1742 * the *_offset variables.
1743 * We keep track of how many bytes have been sent overall using the
1744 * data_sent variable, which ranges from 0 to the total bytes to be
1745 * sent.
1746 */
1747 while (data_sent < data_len) {
1748 int userdata_left = userdata_len - userdata_offset;
1749 int sysdata_left = sysdata_len - sysdata_offset;
1750 int msgbody_left = msgbody_len - msgbody_offset;
1751 int buf_offset = 0;
1752 int this_chunk = 0;
1753
1754 /* header is already populated in nt->buf, just append to it */
1755 buf_offset = header_len;
1756
1757 buf_offset += scnprintf(nt->buf + buf_offset,
1758 MAX_PRINT_CHUNK - buf_offset,
1759 ",ncfrag=%d/%d;", data_sent,
1760 data_len);
1761
1762 /* append msgbody first */
1763 this_chunk = min(msgbody_left, MAX_PRINT_CHUNK - buf_offset);
1764 memcpy(nt->buf + buf_offset, msgbody_ptr + msgbody_offset,
1765 this_chunk);
1766 msgbody_offset += this_chunk;
1767 buf_offset += this_chunk;
1768 data_sent += this_chunk;
1769
1770 /* after msgbody, append userdata */
1771 if (userdata_ptr && userdata_left) {
1772 this_chunk = min(userdata_left,
1773 MAX_PRINT_CHUNK - buf_offset);
1774 memcpy(nt->buf + buf_offset,
1775 userdata_ptr + userdata_offset, this_chunk);
1776 userdata_offset += this_chunk;
1777 buf_offset += this_chunk;
1778 data_sent += this_chunk;
1779 }
1780
1781 /* after userdata, append sysdata */
1782 if (sysdata_ptr && sysdata_left) {
1783 this_chunk = min(sysdata_left,
1784 MAX_PRINT_CHUNK - buf_offset);
1785 memcpy(nt->buf + buf_offset,
1786 sysdata_ptr + sysdata_offset, this_chunk);
1787 sysdata_offset += this_chunk;
1788 buf_offset += this_chunk;
1789 data_sent += this_chunk;
1790 }
1791
1792 /* if all is good, send the packet out */
1793 if (WARN_ON_ONCE(data_sent > data_len))
1794 return;
1795
1796 send_udp(nt, nt->buf, buf_offset);
1797 }
1798 }
1799
send_msg_fragmented(struct netconsole_target * nt,const char * msg,int msg_len,int release_len,int sysdata_len)1800 static void send_msg_fragmented(struct netconsole_target *nt,
1801 const char *msg,
1802 int msg_len,
1803 int release_len,
1804 int sysdata_len)
1805 {
1806 int header_len, msgbody_len;
1807 const char *msgbody;
1808
1809 /* need to insert extra header fields, detect header and msgbody */
1810 msgbody = memchr(msg, ';', msg_len);
1811 if (WARN_ON_ONCE(!msgbody))
1812 return;
1813
1814 header_len = msgbody - msg;
1815 msgbody_len = msg_len - header_len - 1;
1816 msgbody++;
1817
1818 /*
1819 * Transfer multiple chunks with the following extra header.
1820 * "ncfrag=<byte-offset>/<total-bytes>"
1821 */
1822 if (release_len)
1823 append_release(nt->buf);
1824
1825 /* Copy the header into the buffer */
1826 memcpy(nt->buf + release_len, msg, header_len);
1827 header_len += release_len;
1828
1829 /* for now on, the header will be persisted, and the msgbody
1830 * will be replaced
1831 */
1832 send_fragmented_body(nt, msgbody, header_len, msgbody_len,
1833 sysdata_len);
1834 }
1835
1836 /**
1837 * send_ext_msg_udp - send extended log message to target
1838 * @nt: target to send message to
1839 * @wctxt: nbcon write context containing message and metadata
1840 *
1841 * Transfer extended log message to @nt. If message is longer than
1842 * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
1843 * ncfrag header field added to identify them.
1844 */
send_ext_msg_udp(struct netconsole_target * nt,struct nbcon_write_context * wctxt)1845 static void send_ext_msg_udp(struct netconsole_target *nt,
1846 struct nbcon_write_context *wctxt)
1847 {
1848 int userdata_len = 0;
1849 int release_len = 0;
1850 int sysdata_len = 0;
1851 int len;
1852
1853 #ifdef CONFIG_NETCONSOLE_DYNAMIC
1854 sysdata_len = prepare_sysdata(nt, wctxt);
1855 userdata_len = nt->userdata_length;
1856 #endif
1857 if (nt->release)
1858 release_len = strlen(init_utsname()->release) + 1;
1859
1860 len = wctxt->len + release_len + sysdata_len + userdata_len;
1861 if (len <= MAX_PRINT_CHUNK)
1862 return send_msg_no_fragmentation(nt, wctxt->outbuf,
1863 wctxt->len, release_len);
1864
1865 return send_msg_fragmented(nt, wctxt->outbuf, wctxt->len, release_len,
1866 sysdata_len);
1867 }
1868
send_msg_udp(struct netconsole_target * nt,const char * msg,unsigned int len)1869 static void send_msg_udp(struct netconsole_target *nt, const char *msg,
1870 unsigned int len)
1871 {
1872 const char *tmp = msg;
1873 int frag, left = len;
1874
1875 while (left > 0) {
1876 frag = min(left, MAX_PRINT_CHUNK);
1877 send_udp(nt, tmp, frag);
1878 tmp += frag;
1879 left -= frag;
1880 }
1881 }
1882
1883 /**
1884 * netconsole_write - Generic function to send a msg to all targets
1885 * @wctxt: nbcon write context
1886 * @extended: "true" for extended console mode
1887 *
1888 * Given an nbcon write context, send the message to the netconsole targets
1889 */
netconsole_write(struct nbcon_write_context * wctxt,bool extended)1890 static void netconsole_write(struct nbcon_write_context *wctxt, bool extended)
1891 {
1892 struct netconsole_target *nt;
1893
1894 if (oops_only && !oops_in_progress)
1895 return;
1896
1897 list_for_each_entry(nt, &target_list, list) {
1898 if (nt->extended != extended || nt->state != STATE_ENABLED ||
1899 !netif_running(nt->np.dev))
1900 continue;
1901
1902 /* If nbcon_enter_unsafe() fails, just return given netconsole
1903 * lost the ownership, and iterating over the targets will not
1904 * be able to re-acquire.
1905 */
1906 if (!nbcon_enter_unsafe(wctxt))
1907 return;
1908
1909 if (extended)
1910 send_ext_msg_udp(nt, wctxt);
1911 else
1912 send_msg_udp(nt, wctxt->outbuf, wctxt->len);
1913
1914 nbcon_exit_unsafe(wctxt);
1915 }
1916 }
1917
netconsole_write_ext(struct console * con __always_unused,struct nbcon_write_context * wctxt)1918 static void netconsole_write_ext(struct console *con __always_unused,
1919 struct nbcon_write_context *wctxt)
1920 {
1921 netconsole_write(wctxt, true);
1922 }
1923
netconsole_write_basic(struct console * con __always_unused,struct nbcon_write_context * wctxt)1924 static void netconsole_write_basic(struct console *con __always_unused,
1925 struct nbcon_write_context *wctxt)
1926 {
1927 netconsole_write(wctxt, false);
1928 }
1929
netconsole_device_lock(struct console * con __always_unused,unsigned long * flags)1930 static void netconsole_device_lock(struct console *con __always_unused,
1931 unsigned long *flags)
1932 __acquires(&target_list_lock)
1933 {
1934 spin_lock_irqsave(&target_list_lock, *flags);
1935 }
1936
netconsole_device_unlock(struct console * con __always_unused,unsigned long flags)1937 static void netconsole_device_unlock(struct console *con __always_unused,
1938 unsigned long flags)
1939 __releases(&target_list_lock)
1940 {
1941 spin_unlock_irqrestore(&target_list_lock, flags);
1942 }
1943
netconsole_parser_cmdline(struct netpoll * np,char * opt)1944 static int netconsole_parser_cmdline(struct netpoll *np, char *opt)
1945 {
1946 bool ipversion_set = false;
1947 char *cur = opt;
1948 char *delim;
1949 int ipv6;
1950
1951 if (*cur != '@') {
1952 delim = strchr(cur, '@');
1953 if (!delim)
1954 goto parse_failed;
1955 *delim = 0;
1956 if (kstrtou16(cur, 10, &np->local_port))
1957 goto parse_failed;
1958 cur = delim;
1959 }
1960 cur++;
1961
1962 if (*cur != '/') {
1963 ipversion_set = true;
1964 delim = strchr(cur, '/');
1965 if (!delim)
1966 goto parse_failed;
1967 *delim = 0;
1968 ipv6 = netpoll_parse_ip_addr(cur, &np->local_ip);
1969 if (ipv6 < 0)
1970 goto parse_failed;
1971 else
1972 np->ipv6 = (bool)ipv6;
1973 cur = delim;
1974 }
1975 cur++;
1976
1977 if (*cur != ',') {
1978 /* parse out dev_name or dev_mac */
1979 delim = strchr(cur, ',');
1980 if (!delim)
1981 goto parse_failed;
1982 *delim = 0;
1983
1984 np->dev_name[0] = '\0';
1985 eth_broadcast_addr(np->dev_mac);
1986 if (!strchr(cur, ':'))
1987 strscpy(np->dev_name, cur, sizeof(np->dev_name));
1988 else if (!mac_pton(cur, np->dev_mac))
1989 goto parse_failed;
1990
1991 cur = delim;
1992 }
1993 cur++;
1994
1995 if (*cur != '@') {
1996 /* dst port */
1997 delim = strchr(cur, '@');
1998 if (!delim)
1999 goto parse_failed;
2000 *delim = 0;
2001 if (*cur == ' ' || *cur == '\t')
2002 np_info(np, "warning: whitespace is not allowed\n");
2003 if (kstrtou16(cur, 10, &np->remote_port))
2004 goto parse_failed;
2005 cur = delim;
2006 }
2007 cur++;
2008
2009 /* dst ip */
2010 delim = strchr(cur, '/');
2011 if (!delim)
2012 goto parse_failed;
2013 *delim = 0;
2014 ipv6 = netpoll_parse_ip_addr(cur, &np->remote_ip);
2015 if (ipv6 < 0)
2016 goto parse_failed;
2017 else if (ipversion_set && np->ipv6 != (bool)ipv6)
2018 goto parse_failed;
2019 else
2020 np->ipv6 = (bool)ipv6;
2021 cur = delim + 1;
2022
2023 if (*cur != 0) {
2024 /* MAC address */
2025 if (!mac_pton(cur, np->remote_mac))
2026 goto parse_failed;
2027 }
2028
2029 netconsole_print_banner(np);
2030
2031 return 0;
2032
2033 parse_failed:
2034 np_info(np, "couldn't parse config at '%s'!\n", cur);
2035 return -1;
2036 }
2037
2038 /* Allocate new target (from boot/module param) and setup netpoll for it */
alloc_param_target(char * target_config,int cmdline_count)2039 static struct netconsole_target *alloc_param_target(char *target_config,
2040 int cmdline_count)
2041 {
2042 struct netconsole_target *nt;
2043 int err;
2044
2045 nt = alloc_and_init();
2046 if (!nt) {
2047 err = -ENOMEM;
2048 goto fail;
2049 }
2050
2051 if (*target_config == '+') {
2052 nt->extended = true;
2053 target_config++;
2054 }
2055
2056 if (*target_config == 'r') {
2057 if (!nt->extended) {
2058 pr_err("Netconsole configuration error. Release feature requires extended log message");
2059 err = -EINVAL;
2060 goto fail;
2061 }
2062 nt->release = true;
2063 target_config++;
2064 }
2065
2066 /* Parse parameters and setup netpoll */
2067 err = netconsole_parser_cmdline(&nt->np, target_config);
2068 if (err)
2069 goto fail;
2070
2071 err = netpoll_setup(&nt->np);
2072 if (err) {
2073 pr_err("Not enabling netconsole for %s%d. Netpoll setup failed\n",
2074 NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);
2075 if (!IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC))
2076 /* only fail if dynamic reconfiguration is set,
2077 * otherwise, keep the target in the list, but disabled.
2078 */
2079 goto fail;
2080 } else {
2081 nt->state = STATE_ENABLED;
2082 }
2083 populate_configfs_item(nt, cmdline_count);
2084
2085 return nt;
2086
2087 fail:
2088 kfree(nt);
2089 return ERR_PTR(err);
2090 }
2091
2092 /* Cleanup netpoll for given target (from boot/module param) and free it */
free_param_target(struct netconsole_target * nt)2093 static void free_param_target(struct netconsole_target *nt)
2094 {
2095 cancel_work_sync(&nt->resume_wq);
2096 netpoll_cleanup(&nt->np);
2097 #ifdef CONFIG_NETCONSOLE_DYNAMIC
2098 kfree(nt->userdata);
2099 #endif
2100 kfree(nt);
2101 }
2102
2103 static struct console netconsole_ext = {
2104 .name = "netcon_ext",
2105 .flags = CON_ENABLED | CON_EXTENDED | CON_NBCON | CON_NBCON_ATOMIC_UNSAFE,
2106 .write_thread = netconsole_write_ext,
2107 .write_atomic = netconsole_write_ext,
2108 .device_lock = netconsole_device_lock,
2109 .device_unlock = netconsole_device_unlock,
2110 };
2111
2112 static struct console netconsole = {
2113 .name = "netcon",
2114 .flags = CON_ENABLED | CON_NBCON | CON_NBCON_ATOMIC_UNSAFE,
2115 .write_thread = netconsole_write_basic,
2116 .write_atomic = netconsole_write_basic,
2117 .device_lock = netconsole_device_lock,
2118 .device_unlock = netconsole_device_unlock,
2119 };
2120
init_netconsole(void)2121 static int __init init_netconsole(void)
2122 {
2123 int err;
2124 struct netconsole_target *nt, *tmp;
2125 u32 console_type_needed = 0;
2126 unsigned int count = 0;
2127 unsigned long flags;
2128 char *target_config;
2129 char *input = config;
2130
2131 if (strnlen(input, MAX_PARAM_LENGTH)) {
2132 while ((target_config = strsep(&input, ";"))) {
2133 nt = alloc_param_target(target_config, count);
2134 if (IS_ERR(nt)) {
2135 if (IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC))
2136 continue;
2137 err = PTR_ERR(nt);
2138 goto fail;
2139 }
2140 /* Dump existing printks when we register */
2141 if (nt->extended) {
2142 console_type_needed |= CONS_EXTENDED;
2143 netconsole_ext.flags |= CON_PRINTBUFFER;
2144 } else {
2145 console_type_needed |= CONS_BASIC;
2146 netconsole.flags |= CON_PRINTBUFFER;
2147 }
2148
2149 spin_lock_irqsave(&target_list_lock, flags);
2150 list_add(&nt->list, &target_list);
2151 spin_unlock_irqrestore(&target_list_lock, flags);
2152 count++;
2153 }
2154 }
2155
2156 netconsole_wq = alloc_workqueue("netconsole", WQ_UNBOUND, 0);
2157 if (!netconsole_wq) {
2158 err = -ENOMEM;
2159 goto fail;
2160 }
2161
2162 err = register_netdevice_notifier(&netconsole_netdev_notifier);
2163 if (err)
2164 goto fail;
2165
2166 err = dynamic_netconsole_init();
2167 if (err)
2168 goto undonotifier;
2169
2170 if (console_type_needed & CONS_EXTENDED)
2171 register_console(&netconsole_ext);
2172 if (console_type_needed & CONS_BASIC)
2173 register_console(&netconsole);
2174 pr_info("network logging started\n");
2175
2176 return err;
2177
2178 undonotifier:
2179 unregister_netdevice_notifier(&netconsole_netdev_notifier);
2180
2181 fail:
2182 pr_err("cleaning up\n");
2183
2184 if (netconsole_wq)
2185 flush_workqueue(netconsole_wq);
2186 /*
2187 * Remove all targets and destroy them (only targets created
2188 * from the boot/module option exist here). Skipping the list
2189 * lock is safe here, and netpoll_cleanup() will sleep.
2190 */
2191 list_for_each_entry_safe(nt, tmp, &target_list, list) {
2192 list_del(&nt->list);
2193 free_param_target(nt);
2194 }
2195
2196 if (netconsole_wq)
2197 destroy_workqueue(netconsole_wq);
2198
2199 return err;
2200 }
2201
cleanup_netconsole(void)2202 static void __exit cleanup_netconsole(void)
2203 {
2204 struct netconsole_target *nt, *tmp;
2205
2206 if (console_is_registered(&netconsole_ext))
2207 unregister_console(&netconsole_ext);
2208 if (console_is_registered(&netconsole))
2209 unregister_console(&netconsole);
2210 dynamic_netconsole_exit();
2211 unregister_netdevice_notifier(&netconsole_netdev_notifier);
2212 flush_workqueue(netconsole_wq);
2213
2214 /*
2215 * Targets created via configfs pin references on our module
2216 * and would first be rmdir(2)'ed from userspace. We reach
2217 * here only when they are already destroyed, and only those
2218 * created from the boot/module option are left, so remove and
2219 * destroy them. Skipping the list lock is safe here, and
2220 * netpoll_cleanup() will sleep.
2221 */
2222 list_for_each_entry_safe(nt, tmp, &target_list, list) {
2223 list_del(&nt->list);
2224 free_param_target(nt);
2225 }
2226
2227 destroy_workqueue(netconsole_wq);
2228 }
2229
2230 /*
2231 * Use late_initcall to ensure netconsole is
2232 * initialized after network device driver if built-in.
2233 *
2234 * late_initcall() and module_init() are identical if built as module.
2235 */
2236 late_initcall(init_netconsole);
2237 module_exit(cleanup_netconsole);
2238