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