2 * linux/drivers/net/netconsole.c
4 * Copyright (C) 2001 Ingo Molnar <mingo@redhat.com>
6 * This file contains the implementation of an IRQ-safe, crash-safe
7 * kernel console implementation that outputs kernel messages to the
10 * Modification history:
12 * 2001-09-17 started by Ingo Molnar.
13 * 2003-08-11 2.6 port by Matt Mackall
17 * 2003-09-07 rewritten with netpoll api
20 /****************************************************************
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2, or (at your option)
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 ****************************************************************/
38 #include <linux/tty.h>
39 #include <linux/init.h>
40 #include <linux/module.h>
41 #include <linux/console.h>
42 #include <linux/tty_driver.h>
43 #include <linux/moduleparam.h>
44 #include <linux/string.h>
45 #include <linux/sysrq.h>
46 #include <linux/smp.h>
47 #include <linux/netpoll.h>
48 #include <asm/unaligned.h>
52 MODULE_AUTHOR("Maintainer: Matt Mackall <mpm@selenic.com>");
53 MODULE_DESCRIPTION("Console driver for network interfaces");
54 MODULE_LICENSE("GPL");
56 static char config[256];
57 module_param_string(netconsole, config, 256, 0);
58 MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n");
60 static struct netpoll np = {
65 .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
67 static int configured = 0;
69 static char netlog_config[256];
70 module_param_string(netlog, netlog_config, 256, 0);
71 MODULE_PARM_DESC(netlog, " netlog=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n");
72 static struct netpoll netlog_np = {
77 .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
79 static int netlog_configured = 0;
81 #define MAX_PRINT_CHUNK 1000
82 #define SYSLOG_HEADER_LEN 4
84 static int syslog_chars = SYSLOG_HEADER_LEN;
85 static unsigned char syslog_line [MAX_PRINT_CHUNK + 10] = {
90 [4 ... MAX_PRINT_CHUNK+5] = '\0',
92 static unsigned char netlog_line[MAX_PRINT_CHUNK + HEADER_LEN];
93 static unsigned int log_offset;
96 * We feed kernel messages char by char, and send the UDP packet
97 * one linefeed. We buffer all characters received.
99 static inline void feed_syslog_char(const unsigned char c)
101 if (syslog_chars == MAX_PRINT_CHUNK)
103 syslog_line[syslog_chars] = c;
106 netpoll_send_udp(&np, syslog_line, syslog_chars);
107 syslog_chars = SYSLOG_HEADER_LEN;
111 static void write_msg(struct console *con, const char *msg, unsigned int len)
116 char *netlog_buf = &netlog_line[HEADER_LEN];
118 if (!np.dev && !netlog_np.dev)
121 if (unlikely(netdump_mode))
124 local_irq_save(flags);
127 for (i = 0; i < len; i++)
128 feed_syslog_char(msg[i]);
133 if (left > MAX_PRINT_CHUNK)
134 len = MAX_PRINT_CHUNK;
137 netlog_line[0] = NETDUMP_VERSION;
140 reply.code = REPLY_LOG;
141 reply.info = log_offset;
143 put_unaligned(htonl(reply.nr),
144 (u32 *)(netlog_line + 1));
145 put_unaligned(htonl(reply.code),
146 (u32 *)(netlog_line + 5));
147 put_unaligned(htonl(reply.info),
148 (u32 *)(netlog_line + 9));
151 memcpy(netlog_buf, msg, len);
153 netpoll_send_udp(&netlog_np,
154 netlog_line, len + HEADER_LEN);
160 local_irq_restore(flags);
163 static struct console netconsole = {
164 .flags = CON_ENABLED | CON_PRINTBUFFER,
168 static int option_setup(char *opt)
170 configured = !netpoll_parse_options(&np, opt);
174 __setup("netconsole=", option_setup);
176 static int netlog_option_setup(char *opt)
178 netlog_configured = !netpoll_parse_options(&netlog_np, opt);
182 __setup("netlog=", netlog_option_setup);
184 static int init_netconsole(void)
187 option_setup(config);
189 if (strlen(netlog_config))
190 netlog_option_setup(netlog_config);
192 if (configured && netpoll_setup(&np))
193 printk("netconsole: failed to configure syslog service\n");
195 if (netlog_configured && netpoll_setup(&netlog_np))
196 printk("netconsole: failed to configured netlog service.\n");
198 if (!configured && !netlog_configured)
201 register_console(&netconsole);
202 printk(KERN_INFO "netconsole: network logging started\n");
206 static void cleanup_netconsole(void)
208 unregister_console(&netconsole);
211 netpoll_cleanup(&np);
213 if (netlog_configured)
214 netpoll_cleanup(&netlog_np);
217 module_init(init_netconsole);
218 module_exit(cleanup_netconsole);