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