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