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