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