linux/drivers/net/slip/slip.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * slip.c	This module implements the SLIP protocol for kernel-based
 *		devices like TTY.  It interfaces between a raw TTY, and the
 *		kernel's INET protocol layers.
 *
 * Version:	@(#)slip.c	0.8.3	12/24/94
 *
 * Authors:	Laurence Culhane, <[email protected]>
 *		Fred N. van Kempen, <[email protected]>
 *
 * Fixes:
 *		Alan Cox	: 	Sanity checks and avoid tx overruns.
 *					Has a new sl->mtu field.
 *		Alan Cox	: 	Found cause of overrun. ifconfig sl0
 *					mtu upwards. Driver now spots this
 *					and grows/shrinks its buffers(hack!).
 *					Memory leak if you run out of memory
 *					setting up a slip driver fixed.
 *		Matt Dillon	:	Printable slip (borrowed from NET2E)
 *	Pauline Middelink	:	Slip driver fixes.
 *		Alan Cox	:	Honours the old SL_COMPRESSED flag
 *		Alan Cox	:	KISS AX.25 and AXUI IP support
 *		Michael Riepe	:	Automatic CSLIP recognition added
 *		Charles Hedrick :	CSLIP header length problem fix.
 *		Alan Cox	:	Corrected non-IP cases of the above.
 *		Alan Cox	:	Now uses hardware type as per FvK.
 *		Alan Cox	:	Default to 192.168.0.0 (RFC 1597)
 *		A.N.Kuznetsov	:	dev_tint() recursion fix.
 *	Dmitry Gorodchanin	:	SLIP memory leaks
 *      Dmitry Gorodchanin      :       Code cleanup. Reduce tty driver
 *                                      buffering from 4096 to 256 bytes.
 *                                      Improving SLIP response time.
 *                                      CONFIG_SLIP_MODE_SLIP6.
 *                                      ifconfig sl? up & down now works
 *					correctly.
 *					Modularization.
 *              Alan Cox        :       Oops - fix AX.25 buffer lengths
 *      Dmitry Gorodchanin      :       Even more cleanups. Preserve CSLIP
 *                                      statistics. Include CSLIP code only
 *                                      if it really needed.
 *		Alan Cox	:	Free slhc buffers in the right place.
 *		Alan Cox	:	Allow for digipeated IP over AX.25
 *		Matti Aarnio	:	Dynamic SLIP devices, with ideas taken
 *					from Jim Freeman's <[email protected]>
 *					dynamic PPP devices.  We do NOT kfree()
 *					device entries, just reg./unreg. them
 *					as they are needed.  We kfree() them
 *					at module cleanup.
 *					With MODULE-loading ``insmod'', user
 *					can issue parameter:  slip_maxdev=1024
 *					(Or how much he/she wants.. Default
 *					is 256)
 *	Stanislav Voronyi	:	Slip line checking, with ideas taken
 *					from multislip BSDI driver which was
 *					written by Igor Chechik, RELCOM Corp.
 *					Only algorithms have been ported to
 *					Linux SLIP driver.
 *	Vitaly E. Lavrov	:	Sane behaviour on tty hangup.
 *	Alexey Kuznetsov	:	Cleanup interfaces to tty & netdevice
 *					modules.
 */

#define SL_CHECK_TRANSMIT
#include <linux/compat.h>
#include <linux/module.h>
#include <linux/moduleparam.h>

#include <linux/uaccess.h>
#include <linux/bitops.h>
#include <linux/sched/signal.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/if_arp.h>
#include <linux/if_slip.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "slip.h"
#ifdef CONFIG_INET
#include <linux/ip.h>
#include <linux/tcp.h>
#include <net/slhc_vj.h>
#endif

#define SLIP_VERSION

static struct net_device **slip_devs;

static int slip_maxdev =;
module_param(slip_maxdev, int, 0);
MODULE_PARM_DESC();

static int slip_esc(unsigned char *p, unsigned char *d, int len);
static void slip_unesc(struct slip *sl, unsigned char c);
#ifdef CONFIG_SLIP_MODE_SLIP6
static int slip_esc6(unsigned char *p, unsigned char *d, int len);
static void slip_unesc6(struct slip *sl, unsigned char c);
#endif
#ifdef CONFIG_SLIP_SMART
static void sl_keepalive(struct timer_list *t);
static void sl_outfill(struct timer_list *t);
static int sl_siocdevprivate(struct net_device *dev, struct ifreq *rq, void __user *data, int cmd);
#endif

/********************************
*  Buffer administration routines:
*	sl_alloc_bufs()
*	sl_free_bufs()
*	sl_realloc_bufs()
*
* NOTE: sl_realloc_bufs != sl_free_bufs + sl_alloc_bufs, because
*	sl_realloc_bufs provides strong atomicity and reallocation
*	on actively running device.
*********************************/

/*
   Allocate channel buffers.
 */

static int sl_alloc_bufs(struct slip *sl, int mtu)
{}

/* Free a SLIP channel buffers. */
static void sl_free_bufs(struct slip *sl)
{}

/*
   Reallocate slip channel buffers.
 */

static int sl_realloc_bufs(struct slip *sl, int mtu)
{}


/* Set the "sending" flag.  This must be atomic hence the set_bit. */
static inline void sl_lock(struct slip *sl)
{}


/* Clear the "sending" flag.  This must be atomic, hence the ASM. */
static inline void sl_unlock(struct slip *sl)
{}

/* Send one completely decapsulated IP datagram to the IP layer. */
static void sl_bump(struct slip *sl)
{}

/* Encapsulate one IP datagram and stuff into a TTY queue. */
static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
{}

/* Write out any remaining transmit buffer. Scheduled when tty is writable */
static void slip_transmit(struct work_struct *work)
{}

/*
 * Called by the driver when there's room for more data.
 * Schedule the transmit.
 */
static void slip_write_wakeup(struct tty_struct *tty)
{}

static void sl_tx_timeout(struct net_device *dev, unsigned int txqueue)
{}


/* Encapsulate an IP datagram and kick it into a TTY queue. */
static netdev_tx_t
sl_xmit(struct sk_buff *skb, struct net_device *dev)
{}


/******************************************
 *   Routines looking at netdevice side.
 ******************************************/

/* Netdevice UP -> DOWN routine */

static int
sl_close(struct net_device *dev)
{}

/* Netdevice DOWN -> UP routine */

static int sl_open(struct net_device *dev)
{}

/* Netdevice change MTU request */

static int sl_change_mtu(struct net_device *dev, int new_mtu)
{}

/* Netdevice get statistics request */

static void
sl_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{}

/* Netdevice register callback */

static int sl_init(struct net_device *dev)
{}


static void sl_uninit(struct net_device *dev)
{}

/* Hook the destructor so we can free slip devices at the right point in time */
static void sl_free_netdev(struct net_device *dev)
{}

static const struct net_device_ops sl_netdev_ops =;


static void sl_setup(struct net_device *dev)
{}

/******************************************
  Routines looking at TTY side.
 ******************************************/


/*
 * Handle the 'receiver data ready' interrupt.
 * This function is called by the 'tty_io' module in the kernel when
 * a block of SLIP data has been received, which can now be decapsulated
 * and sent on to some IP layer for further processing. This will not
 * be re-entered while running but other ldisc functions may be called
 * in parallel
 */

static void slip_receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp,
			     size_t count)
{}

/************************************
 *  slip_open helper routines.
 ************************************/

/* Collect hanged up channels */
static void sl_sync(void)
{}


/* Find a free SLIP channel, and link in this `tty' line. */
static struct slip *sl_alloc(void)
{}

/*
 * Open the high-level part of the SLIP channel.
 * This function is called by the TTY module when the
 * SLIP line discipline is called for.  Because we are
 * sure the tty line exists, we only have to link it to
 * a free SLIP channel...
 *
 * Called in process context serialized from other ldisc calls.
 */

static int slip_open(struct tty_struct *tty)
{}

/*
 * Close down a SLIP channel.
 * This means flushing out any pending queues, and then returning. This
 * call is serialized against other ldisc functions.
 *
 * We also use this method fo a hangup event
 */

static void slip_close(struct tty_struct *tty)
{}

static void slip_hangup(struct tty_struct *tty)
{}
 /************************************************************************
  *			STANDARD SLIP ENCAPSULATION		  	 *
  ************************************************************************/

static int slip_esc(unsigned char *s, unsigned char *d, int len)
{}

static void slip_unesc(struct slip *sl, unsigned char s)
{}


#ifdef CONFIG_SLIP_MODE_SLIP6
/************************************************************************
 *			 6 BIT SLIP ENCAPSULATION			*
 ************************************************************************/

static int slip_esc6(unsigned char *s, unsigned char *d, int len)
{}

static void slip_unesc6(struct slip *sl, unsigned char s)
{}
#endif /* CONFIG_SLIP_MODE_SLIP6 */

/* Perform I/O control on an active SLIP channel. */
static int slip_ioctl(struct tty_struct *tty, unsigned int cmd,
		unsigned long arg)
{}

/* VSV changes start here */
#ifdef CONFIG_SLIP_SMART
/* function sl_siocdevprivate called from net/core/dev.c
   to allow get/set outfill/keepalive parameter
   by ifconfig                                 */

static int sl_siocdevprivate(struct net_device *dev, struct ifreq *rq,
			     void __user *data, int cmd)
{}
#endif
/* VSV changes end */

static struct tty_ldisc_ops sl_ldisc =;

static int __init slip_init(void)
{}

static void __exit slip_exit(void)
{}

module_init();
module_exit(slip_exit);

#ifdef CONFIG_SLIP_SMART
/*
 * This is start of the code for multislip style line checking
 * added by Stanislav Voronyi. All changes before marked VSV
 */

static void sl_outfill(struct timer_list *t)
{}

static void sl_keepalive(struct timer_list *t)
{}

#endif
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_ALIAS_LDISC();