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