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 561da177e4SLinus Torvalds static struct netpoll np = { 571da177e4SLinus Torvalds .name = "netconsole", 581da177e4SLinus Torvalds .dev_name = "eth0", 591da177e4SLinus Torvalds .local_port = 6665, 601da177e4SLinus Torvalds .remote_port = 6666, 611da177e4SLinus Torvalds .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 621da177e4SLinus Torvalds }; 63d39badf0SSatyam Sharma static int configured; 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds static void write_msg(struct console *con, const char *msg, unsigned int len) 661da177e4SLinus Torvalds { 671da177e4SLinus Torvalds int frag, left; 681da177e4SLinus Torvalds unsigned long flags; 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds if (!np.dev) 711da177e4SLinus Torvalds return; 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds local_irq_save(flags); 741da177e4SLinus Torvalds 751da177e4SLinus Torvalds for (left = len; left;) { 761da177e4SLinus Torvalds frag = min(left, MAX_PRINT_CHUNK); 771da177e4SLinus Torvalds netpoll_send_udp(&np, msg, frag); 781da177e4SLinus Torvalds msg += frag; 791da177e4SLinus Torvalds left -= frag; 801da177e4SLinus Torvalds } 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds local_irq_restore(flags); 831da177e4SLinus Torvalds } 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds static struct console netconsole = { 86d938ab44SRandy Dunlap .name = "netcon", 871da177e4SLinus Torvalds .flags = CON_ENABLED | CON_PRINTBUFFER, 88d39badf0SSatyam Sharma .write = write_msg, 891da177e4SLinus Torvalds }; 901da177e4SLinus Torvalds 91d39badf0SSatyam Sharma static int __init option_setup(char *opt) 921da177e4SLinus Torvalds { 931da177e4SLinus Torvalds configured = !netpoll_parse_options(&np, opt); 949b41046cSOGAWA Hirofumi return 1; 951da177e4SLinus Torvalds } 961da177e4SLinus Torvalds 971da177e4SLinus Torvalds __setup("netconsole=", option_setup); 981da177e4SLinus Torvalds 99d39badf0SSatyam Sharma static int __init init_netconsole(void) 1001da177e4SLinus Torvalds { 101d39badf0SSatyam Sharma int err = 0; 102b41848b6SStephen Hemminger 103d39badf0SSatyam Sharma if (strnlen(config, MAX_PARAM_LENGTH)) 1041da177e4SLinus Torvalds option_setup(config); 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds if (!configured) { 107d39badf0SSatyam Sharma printk(KERN_INFO "netconsole: not configured, aborting\n"); 108d39badf0SSatyam Sharma goto out; 1091da177e4SLinus Torvalds } 1101da177e4SLinus Torvalds 111b41848b6SStephen Hemminger err = netpoll_setup(&np); 112b41848b6SStephen Hemminger if (err) 113d39badf0SSatyam Sharma goto out; 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds register_console(&netconsole); 1161da177e4SLinus Torvalds printk(KERN_INFO "netconsole: network logging started\n"); 117d39badf0SSatyam Sharma 118d39badf0SSatyam Sharma out: 119d39badf0SSatyam Sharma return err; 1201da177e4SLinus Torvalds } 1211da177e4SLinus Torvalds 122d39badf0SSatyam Sharma static void __exit cleanup_netconsole(void) 1231da177e4SLinus Torvalds { 1241da177e4SLinus Torvalds unregister_console(&netconsole); 1251da177e4SLinus Torvalds netpoll_cleanup(&np); 1261da177e4SLinus Torvalds } 1271da177e4SLinus Torvalds 1281da177e4SLinus Torvalds module_init(init_netconsole); 1291da177e4SLinus Torvalds module_exit(cleanup_netconsole); 130