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