linux/drivers/net/netconsole.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  linux/drivers/net/netconsole.c
 *
 *  Copyright (C) 2001  Ingo Molnar <[email protected]>
 *
 *  This file contains the implementation of an IRQ-safe, crash-safe
 *  kernel console implementation that outputs kernel messages to the
 *  network.
 *
 * Modification history:
 *
 * 2001-09-17    started by Ingo Molnar.
 * 2003-08-11    2.6 port by Matt Mackall
 *               simplified options
 *               generic card hooks
 *               works non-modular
 * 2003-09-07    rewritten with netpoll api
 */

/****************************************************************
 *
 ****************************************************************/

#define pr_fmt(fmt)

#include <linux/mm.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/console.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/netpoll.h>
#include <linux/inet.h>
#include <linux/configfs.h>
#include <linux/etherdevice.h>
#include <linux/utsname.h>

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

#define MAX_PARAM_LENGTH
#define MAX_USERDATA_ENTRY_LENGTH
#define MAX_USERDATA_VALUE_LENGTH
/* The number 3 comes from userdata entry format characters (' ', '=', '\n') */
#define MAX_USERDATA_NAME_LENGTH
#define MAX_USERDATA_ITEMS
#define MAX_PRINT_CHUNK

static char config[MAX_PARAM_LENGTH];
module_param_string();
MODULE_PARM_DESC();

static bool oops_only;
module_param(oops_only, bool, 0600);
MODULE_PARM_DESC();

#define NETCONSOLE_PARAM_TARGET_PREFIX

#ifndef	MODULE
static int __init option_setup(char *opt)
{}
__setup();
#endif	/* MODULE */

/* Linked list of all configured targets */
static LIST_HEAD(target_list);

/* This needs to be a spinlock because write_msg() cannot sleep */
static DEFINE_SPINLOCK(target_list_lock);

/*
 * Console driver for extended netconsoles.  Registered on the first use to
 * avoid unnecessarily enabling ext message formatting.
 */
static struct console netconsole_ext;

/**
 * struct netconsole_target - Represents a configured netconsole target.
 * @list:	Links this target into the target_list.
 * @group:	Links us into the configfs subsystem hierarchy.
 * @userdata_group:	Links to the userdata configfs hierarchy
 * @userdata_complete:	Cached, formatted string of append
 * @userdata_length:	String length of userdata_complete
 * @enabled:	On / off knob to enable / disable target.
 *		Visible from userspace (read-write).
 *		We maintain a strict 1:1 correspondence between this and
 *		whether the corresponding netpoll is active or inactive.
 *		Also, other parameters of a target may be modified at
 *		runtime only when it is disabled (enabled == 0).
 * @extended:	Denotes whether console is extended or not.
 * @release:	Denotes whether kernel release version should be prepended
 *		to the message. Depends on extended console.
 * @np:		The netpoll structure for this target.
 *		Contains the other userspace visible parameters:
 *		dev_name	(read-write)
 *		local_port	(read-write)
 *		remote_port	(read-write)
 *		local_ip	(read-write)
 *		remote_ip	(read-write)
 *		local_mac	(read-only)
 *		remote_mac	(read-write)
 */
struct netconsole_target {};

#ifdef	CONFIG_NETCONSOLE_DYNAMIC

static struct configfs_subsystem netconsole_subsys;
static DEFINE_MUTEX(dynamic_netconsole_mutex);

static int __init dynamic_netconsole_init(void)
{}

static void __exit dynamic_netconsole_exit(void)
{}

/*
 * Targets that were created by parsing the boot/module option string
 * do not exist in the configfs hierarchy (and have NULL names) and will
 * never go away, so make these a no-op for them.
 */
static void netconsole_target_get(struct netconsole_target *nt)
{}

static void netconsole_target_put(struct netconsole_target *nt)
{}

#else	/* !CONFIG_NETCONSOLE_DYNAMIC */

static int __init dynamic_netconsole_init(void)
{
	return 0;
}

static void __exit dynamic_netconsole_exit(void)
{
}

/*
 * No danger of targets going away from under us when dynamic
 * reconfigurability is off.
 */
static void netconsole_target_get(struct netconsole_target *nt)
{
}

static void netconsole_target_put(struct netconsole_target *nt)
{
}

static void populate_configfs_item(struct netconsole_target *nt,
				   int cmdline_count)
{
}
#endif	/* CONFIG_NETCONSOLE_DYNAMIC */

/* Allocate and initialize with defaults.
 * Note that these targets get their config_item fields zeroed-out.
 */
static struct netconsole_target *alloc_and_init(void)
{}

#ifdef	CONFIG_NETCONSOLE_DYNAMIC

/*
 * Our subsystem hierarchy is:
 *
 * /sys/kernel/config/netconsole/
 *				|
 *				<target>/
 *				|	enabled
 *				|	release
 *				|	dev_name
 *				|	local_port
 *				|	remote_port
 *				|	local_ip
 *				|	remote_ip
 *				|	local_mac
 *				|	remote_mac
 *				|	userdata/
 *				|		<key>/
 *				|			value
 *				|		...
 *				|
 *				<target>/...
 */

static struct netconsole_target *to_target(struct config_item *item)
{}

/* Get rid of possible trailing newline, returning the new length */
static void trim_newline(char *s, size_t maxlen)
{}

/*
 * Attribute operations for netconsole_target.
 */

static ssize_t enabled_show(struct config_item *item, char *buf)
{}

static ssize_t extended_show(struct config_item *item, char *buf)
{}

static ssize_t release_show(struct config_item *item, char *buf)
{}

static ssize_t dev_name_show(struct config_item *item, char *buf)
{}

static ssize_t local_port_show(struct config_item *item, char *buf)
{}

static ssize_t remote_port_show(struct config_item *item, char *buf)
{}

static ssize_t local_ip_show(struct config_item *item, char *buf)
{}

static ssize_t remote_ip_show(struct config_item *item, char *buf)
{}

static ssize_t local_mac_show(struct config_item *item, char *buf)
{}

static ssize_t remote_mac_show(struct config_item *item, char *buf)
{}

/*
 * This one is special -- targets created through the configfs interface
 * are not enabled (and the corresponding netpoll activated) by default.
 * The user is expected to set the desired parameters first (which
 * would enable him to dynamically add new netpoll targets for new
 * network interfaces as and when they come up).
 */
static ssize_t enabled_store(struct config_item *item,
		const char *buf, size_t count)
{}

static ssize_t release_store(struct config_item *item, const char *buf,
			     size_t count)
{}

static ssize_t extended_store(struct config_item *item, const char *buf,
		size_t count)
{}

static ssize_t dev_name_store(struct config_item *item, const char *buf,
		size_t count)
{}

static ssize_t local_port_store(struct config_item *item, const char *buf,
		size_t count)
{}

static ssize_t remote_port_store(struct config_item *item,
		const char *buf, size_t count)
{}

static ssize_t local_ip_store(struct config_item *item, const char *buf,
		size_t count)
{}

static ssize_t remote_ip_store(struct config_item *item, const char *buf,
	       size_t count)
{}

static ssize_t remote_mac_store(struct config_item *item, const char *buf,
		size_t count)
{}

struct userdatum {};

static struct userdatum *to_userdatum(struct config_item *item)
{}

struct userdata {};

static struct userdata *to_userdata(struct config_item *item)
{}

static struct netconsole_target *userdata_to_target(struct userdata *ud)
{}

static ssize_t userdatum_value_show(struct config_item *item, char *buf)
{}

static void update_userdata(struct netconsole_target *nt)
{}

static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
				     size_t count)
{}

CONFIGFS_ATTR();

static struct configfs_attribute *userdatum_attrs[] =;

static void userdatum_release(struct config_item *item)
{}

static struct configfs_item_operations userdatum_ops =;

static const struct config_item_type userdatum_type =;

static struct config_item *userdatum_make_item(struct config_group *group,
					       const char *name)
{}

static void userdatum_drop(struct config_group *group, struct config_item *item)
{}

static struct configfs_attribute *userdata_attrs[] =;

static struct configfs_group_operations userdata_ops =;

static struct config_item_type userdata_type =;

CONFIGFS_ATTR();
CONFIGFS_ATTR();
CONFIGFS_ATTR();
CONFIGFS_ATTR();
CONFIGFS_ATTR();
CONFIGFS_ATTR();
CONFIGFS_ATTR();
CONFIGFS_ATTR_RO();
CONFIGFS_ATTR();
CONFIGFS_ATTR();

static struct configfs_attribute *netconsole_target_attrs[] =;

/*
 * Item operations and type for netconsole_target.
 */

static void netconsole_target_release(struct config_item *item)
{}

static struct configfs_item_operations netconsole_target_item_ops =;

static const struct config_item_type netconsole_target_type =;

static void init_target_config_group(struct netconsole_target *nt,
				     const char *name)
{}

static struct netconsole_target *find_cmdline_target(const char *name)
{}

/*
 * Group operations and type for netconsole_subsys.
 */

static struct config_group *make_netconsole_target(struct config_group *group,
						   const char *name)
{}

static void drop_netconsole_target(struct config_group *group,
				   struct config_item *item)
{}

static struct configfs_group_operations netconsole_subsys_group_ops =;

static const struct config_item_type netconsole_subsys_type =;

/* The netconsole configfs subsystem */
static struct configfs_subsystem netconsole_subsys =;

static void populate_configfs_item(struct netconsole_target *nt,
				   int cmdline_count)
{}

#endif	/* CONFIG_NETCONSOLE_DYNAMIC */

/* Handle network interface device notifications */
static int netconsole_netdev_event(struct notifier_block *this,
				   unsigned long event, void *ptr)
{}

static struct notifier_block netconsole_netdev_notifier =;

/**
 * send_ext_msg_udp - send extended log message to target
 * @nt: target to send message to
 * @msg: extended log message to send
 * @msg_len: length of message
 *
 * Transfer extended log @msg to @nt.  If @msg is longer than
 * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
 * ncfrag header field added to identify them.
 */
static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
			     int msg_len)
{}

static void write_ext_msg(struct console *con, const char *msg,
			  unsigned int len)
{}

static void write_msg(struct console *con, const char *msg, unsigned int len)
{}

/* Allocate new target (from boot/module param) and setup netpoll for it */
static struct netconsole_target *alloc_param_target(char *target_config,
						    int cmdline_count)
{}

/* Cleanup netpoll for given target (from boot/module param) and free it */
static void free_param_target(struct netconsole_target *nt)
{}

static struct console netconsole_ext =;

static struct console netconsole =;

static int __init init_netconsole(void)
{}

static void __exit cleanup_netconsole(void)
{}

/*
 * Use late_initcall to ensure netconsole is
 * initialized after network device driver if built-in.
 *
 * late_initcall() and module_init() are identical if built as module.
 */
late_initcall(init_netconsole);
module_exit(cleanup_netconsole);