11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/drivers/net/netconsole.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 2001 Ingo Molnar <mingo@redhat.com> 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * This file contains the implementation of an IRQ-safe, crash-safe 71da177e4SLinus Torvalds * kernel console implementation that outputs kernel messages to the 81da177e4SLinus Torvalds * network. 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * Modification history: 111da177e4SLinus Torvalds * 121da177e4SLinus Torvalds * 2001-09-17 started by Ingo Molnar. 131da177e4SLinus Torvalds * 2003-08-11 2.6 port by Matt Mackall 141da177e4SLinus Torvalds * simplified options 151da177e4SLinus Torvalds * generic card hooks 161da177e4SLinus Torvalds * works non-modular 171da177e4SLinus Torvalds * 2003-09-07 rewritten with netpoll api 181da177e4SLinus Torvalds */ 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds /**************************************************************** 211da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 221da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 231da177e4SLinus Torvalds * the Free Software Foundation; either version 2, or (at your option) 241da177e4SLinus Torvalds * any later version. 251da177e4SLinus Torvalds * 261da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, 271da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 281da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 291da177e4SLinus Torvalds * GNU General Public License for more details. 301da177e4SLinus Torvalds * 311da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 321da177e4SLinus Torvalds * along with this program; if not, write to the Free Software 331da177e4SLinus Torvalds * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 341da177e4SLinus Torvalds * 351da177e4SLinus Torvalds ****************************************************************/ 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds #include <linux/mm.h> 381da177e4SLinus Torvalds #include <linux/init.h> 391da177e4SLinus Torvalds #include <linux/module.h> 401da177e4SLinus Torvalds #include <linux/console.h> 411da177e4SLinus Torvalds #include <linux/moduleparam.h> 421da177e4SLinus Torvalds #include <linux/string.h> 431da177e4SLinus Torvalds #include <linux/netpoll.h> 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds MODULE_AUTHOR("Maintainer: Matt Mackall <mpm@selenic.com>"); 461da177e4SLinus Torvalds MODULE_DESCRIPTION("Console driver for network interfaces"); 471da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 481da177e4SLinus Torvalds 49d39badf0SSatyam Sharma #define MAX_PARAM_LENGTH 256 50d39badf0SSatyam Sharma #define MAX_PRINT_CHUNK 1000 51d39badf0SSatyam Sharma 52d39badf0SSatyam Sharma static char config[MAX_PARAM_LENGTH]; 53d39badf0SSatyam Sharma module_param_string(netconsole, config, MAX_PARAM_LENGTH, 0); 541da177e4SLinus Torvalds MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n"); 551da177e4SLinus Torvalds 56d2b60881SSatyam Sharma #ifndef MODULE 57d2b60881SSatyam Sharma static int __init option_setup(char *opt) 58d2b60881SSatyam Sharma { 59d2b60881SSatyam Sharma strlcpy(config, opt, MAX_PARAM_LENGTH); 60d2b60881SSatyam Sharma return 1; 61d2b60881SSatyam Sharma } 62d2b60881SSatyam Sharma __setup("netconsole=", option_setup); 63d2b60881SSatyam Sharma #endif /* MODULE */ 64d2b60881SSatyam Sharma 651da177e4SLinus Torvalds static struct netpoll np = { 661da177e4SLinus Torvalds .name = "netconsole", 671da177e4SLinus Torvalds .dev_name = "eth0", 681da177e4SLinus Torvalds .local_port = 6665, 691da177e4SLinus Torvalds .remote_port = 6666, 701da177e4SLinus Torvalds .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 711da177e4SLinus Torvalds }; 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds static void write_msg(struct console *con, const char *msg, unsigned int len) 741da177e4SLinus Torvalds { 751da177e4SLinus Torvalds int frag, left; 761da177e4SLinus Torvalds unsigned long flags; 771da177e4SLinus Torvalds 780cc120beSSatyam Sharma if (netif_running(np.dev)) { 791da177e4SLinus Torvalds local_irq_save(flags); 801da177e4SLinus Torvalds for (left = len; left;) { 811da177e4SLinus Torvalds frag = min(left, MAX_PRINT_CHUNK); 821da177e4SLinus Torvalds netpoll_send_udp(&np, msg, frag); 831da177e4SLinus Torvalds msg += frag; 841da177e4SLinus Torvalds left -= frag; 851da177e4SLinus Torvalds } 861da177e4SLinus Torvalds local_irq_restore(flags); 871da177e4SLinus Torvalds } 880cc120beSSatyam Sharma } 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds static struct console netconsole = { 91d938ab44SRandy Dunlap .name = "netcon", 921da177e4SLinus Torvalds .flags = CON_ENABLED | CON_PRINTBUFFER, 93d39badf0SSatyam Sharma .write = write_msg, 941da177e4SLinus Torvalds }; 951da177e4SLinus Torvalds 96d39badf0SSatyam Sharma static int __init init_netconsole(void) 971da177e4SLinus Torvalds { 98d39badf0SSatyam Sharma int err = 0; 99b41848b6SStephen Hemminger 100d2b60881SSatyam Sharma if (!strnlen(config, MAX_PARAM_LENGTH)) { 101d39badf0SSatyam Sharma printk(KERN_INFO "netconsole: not configured, aborting\n"); 102d39badf0SSatyam Sharma goto out; 1031da177e4SLinus Torvalds } 1041da177e4SLinus Torvalds 105d2b60881SSatyam Sharma err = netpoll_parse_options(&np, config); 106d2b60881SSatyam Sharma if (err) 107d2b60881SSatyam Sharma goto out; 108d2b60881SSatyam Sharma 109b41848b6SStephen Hemminger err = netpoll_setup(&np); 110b41848b6SStephen Hemminger if (err) 111d39badf0SSatyam Sharma goto out; 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds register_console(&netconsole); 1141da177e4SLinus Torvalds printk(KERN_INFO "netconsole: network logging started\n"); 115d39badf0SSatyam Sharma 116d39badf0SSatyam Sharma out: 117d39badf0SSatyam Sharma return err; 1181da177e4SLinus Torvalds } 1191da177e4SLinus Torvalds 120d39badf0SSatyam Sharma static void __exit cleanup_netconsole(void) 1211da177e4SLinus Torvalds { 1221da177e4SLinus Torvalds unregister_console(&netconsole); 1231da177e4SLinus Torvalds netpoll_cleanup(&np); 1241da177e4SLinus Torvalds } 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds module_init(init_netconsole); 1271da177e4SLinus Torvalds module_exit(cleanup_netconsole); 128