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