linux/drivers/net/ppp/ppp_generic.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Generic PPP layer for Linux.
 *
 * Copyright 1999-2002 Paul Mackerras.
 *
 * The generic PPP layer handles the PPP network interfaces, the
 * /dev/ppp device, packet and VJ compression, and multilink.
 * It talks to PPP `channels' via the interface defined in
 * include/linux/ppp_channel.h.  Channels provide the basic means for
 * sending and receiving PPP frames on some kind of communications
 * channel.
 *
 * Part of the code in this driver was inspired by the old async-only
 * PPP driver, written by Michael Callahan and Al Longyear, and
 * subsequently hacked by Paul Mackerras.
 *
 * ==FILEVERSION 20041108==
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched/signal.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/idr.h>
#include <linux/netdevice.h>
#include <linux/poll.h>
#include <linux/ppp_defs.h>
#include <linux/filter.h>
#include <linux/ppp-ioctl.h>
#include <linux/ppp_channel.h>
#include <linux/ppp-comp.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/if_arp.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <linux/stddef.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/unaligned.h>
#include <net/slhc_vj.h>
#include <linux/atomic.h>
#include <linux/refcount.h>

#include <linux/nsproxy.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>

#define PPP_VERSION

/*
 * Network protocols we support.
 */
#define NP_IP
#define NP_IPV6
#define NP_IPX
#define NP_AT
#define NP_MPLS_UC
#define NP_MPLS_MC
#define NUM_NP

#define MPHDRLEN
#define MPHDRLEN_SSN

#define PPP_PROTO_LEN
#define PPP_LCP_HDRLEN

/*
 * An instance of /dev/ppp can be associated with either a ppp
 * interface unit or a ppp channel.  In both cases, file->private_data
 * points to one of these.
 */
struct ppp_file {};

#define PF_TO_X(pf, X)

#define PF_TO_PPP(pf)
#define PF_TO_CHANNEL(pf)

/*
 * Data structure to hold primary network stats for which
 * we want to use 64 bit storage.  Other network stats
 * are stored in dev->stats of the ppp strucute.
 */
struct ppp_link_stats {};

/*
 * Data structure describing one ppp unit.
 * A ppp unit corresponds to a ppp network interface device
 * and represents a multilink bundle.
 * It can have 0 or more ppp channels connected to it.
 */
struct ppp {};

/*
 * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC,
 * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP,
 * SC_MUST_COMP
 * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR.
 * Bits in xstate: SC_COMP_RUN
 */
#define SC_FLAG_BITS

/*
 * Private data structure for each channel.
 * This includes the data structure used for multilink.
 */
struct channel {};

struct ppp_config {};

/*
 * SMP locking issues:
 * Both the ppp.rlock and ppp.wlock locks protect the ppp.channels
 * list and the ppp.n_channels field, you need to take both locks
 * before you modify them.
 * The lock ordering is: channel.upl -> ppp.wlock -> ppp.rlock ->
 * channel.downl.
 */

static DEFINE_MUTEX(ppp_mutex);
static atomic_t ppp_unit_count =;
static atomic_t channel_count =;

/* per-net private data for this module */
static unsigned int ppp_net_id __read_mostly;
struct ppp_net {};

/* Get the PPP protocol number from a skb */
#define PPP_PROTO(skb)

/* We limit the length of ppp->file.rq to this (arbitrary) value */
#define PPP_MAX_RQLEN

/*
 * Maximum number of multilink fragments queued up.
 * This has to be large enough to cope with the maximum latency of
 * the slowest channel relative to the others.  Strictly it should
 * depend on the number of channels and their characteristics.
 */
#define PPP_MP_MAX_QLEN

/* Multilink header bits. */
#define B
#define E

/* Compare multilink sequence numbers (assumed to be 32 bits wide) */
#define seq_before(a, b)
#define seq_after(a, b)

/* Prototypes. */
static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
			struct file *file, unsigned int cmd, unsigned long arg);
static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb);
static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
static void ppp_push(struct ppp *ppp);
static void ppp_channel_push(struct channel *pch);
static void ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb,
			      struct channel *pch);
static void ppp_receive_error(struct ppp *ppp);
static void ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb);
static struct sk_buff *ppp_decompress_frame(struct ppp *ppp,
					    struct sk_buff *skb);
#ifdef CONFIG_PPP_MULTILINK
static void ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb,
				struct channel *pch);
static void ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb);
static struct sk_buff *ppp_mp_reconstruct(struct ppp *ppp);
static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb);
#endif /* CONFIG_PPP_MULTILINK */
static int ppp_set_compress(struct ppp *ppp, struct ppp_option_data *data);
static void ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound);
static void ppp_ccp_closed(struct ppp *ppp);
static struct compressor *find_compressor(int type);
static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st);
static int ppp_create_interface(struct net *net, struct file *file, int *unit);
static void init_ppp_file(struct ppp_file *pf, int kind);
static void ppp_destroy_interface(struct ppp *ppp);
static struct ppp *ppp_find_unit(struct ppp_net *pn, int unit);
static struct channel *ppp_find_channel(struct ppp_net *pn, int unit);
static int ppp_connect_channel(struct channel *pch, int unit);
static int ppp_disconnect_channel(struct channel *pch);
static void ppp_destroy_channel(struct channel *pch);
static int unit_get(struct idr *p, void *ptr, int min);
static int unit_set(struct idr *p, void *ptr, int n);
static void unit_put(struct idr *p, int n);
static void *unit_find(struct idr *p, int n);
static void ppp_setup(struct net_device *dev);

static const struct net_device_ops ppp_netdev_ops;

static const struct class ppp_class =;

/* per net-namespace data */
static inline struct ppp_net *ppp_pernet(struct net *net)
{}

/* Translates a PPP protocol number to a NP index (NP == network protocol) */
static inline int proto_to_npindex(int proto)
{}

/* Translates an NP index into a PPP protocol number */
static const int npindex_to_proto[NUM_NP] =;

/* Translates an ethertype into an NP index */
static inline int ethertype_to_npindex(int ethertype)
{}

/* Translates an NP index into an ethertype */
static const int npindex_to_ethertype[NUM_NP] =;

/*
 * Locking shorthand.
 */
#define ppp_xmit_lock(ppp)
#define ppp_xmit_unlock(ppp)
#define ppp_recv_lock(ppp)
#define ppp_recv_unlock(ppp)
#define ppp_lock(ppp)
#define ppp_unlock(ppp)

/*
 * /dev/ppp device routines.
 * The /dev/ppp device is used by pppd to control the ppp unit.
 * It supports the read, write, ioctl and poll functions.
 * Open instances of /dev/ppp can be in one of three states:
 * unattached, attached to a ppp unit, or attached to a ppp channel.
 */
static int ppp_open(struct inode *inode, struct file *file)
{}

static int ppp_release(struct inode *unused, struct file *file)
{}

static ssize_t ppp_read(struct file *file, char __user *buf,
			size_t count, loff_t *ppos)
{}

static bool ppp_check_packet(struct sk_buff *skb, size_t count)
{}

static ssize_t ppp_write(struct file *file, const char __user *buf,
			 size_t count, loff_t *ppos)
{}

/* No kernel lock - fine */
static __poll_t ppp_poll(struct file *file, poll_table *wait)
{}

#ifdef CONFIG_PPP_FILTER
static struct bpf_prog *get_filter(struct sock_fprog *uprog)
{}

static struct bpf_prog *ppp_get_filter(struct sock_fprog __user *p)
{}

#ifdef CONFIG_COMPAT
struct sock_fprog32 {};

#define PPPIOCSPASS32
#define PPPIOCSACTIVE32

static struct bpf_prog *compat_ppp_get_filter(struct sock_fprog32 __user *p)
{}
#endif
#endif

/* Bridge one PPP channel to another.
 * When two channels are bridged, ppp_input on one channel is redirected to
 * the other's ops->start_xmit handler.
 * In order to safely bridge channels we must reject channels which are already
 * part of a bridge instance, or which form part of an existing unit.
 * Once successfully bridged, each channel holds a reference on the other
 * to prevent it being freed while the bridge is extant.
 */
static int ppp_bridge_channels(struct channel *pch, struct channel *pchb)
{}

static int ppp_unbridge_channels(struct channel *pch)
{}

static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{}

#ifdef CONFIG_COMPAT
struct ppp_option_data32 {};
#define PPPIOCSCOMPRESS32

static long ppp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{}
#endif

static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
			struct file *file, unsigned int cmd, unsigned long arg)
{}

static const struct file_operations ppp_device_fops =;

static __net_init int ppp_init_net(struct net *net)
{}

static __net_exit void ppp_exit_net(struct net *net)
{}

static struct pernet_operations ppp_net_ops =;

static int ppp_unit_register(struct ppp *ppp, int unit, bool ifname_is_set)
{}

static int ppp_dev_configure(struct net *src_net, struct net_device *dev,
			     const struct ppp_config *conf)
{}

static const struct nla_policy ppp_nl_policy[IFLA_PPP_MAX + 1] =;

static int ppp_nl_validate(struct nlattr *tb[], struct nlattr *data[],
			   struct netlink_ext_ack *extack)
{}

static int ppp_nl_newlink(struct net *src_net, struct net_device *dev,
			  struct nlattr *tb[], struct nlattr *data[],
			  struct netlink_ext_ack *extack)
{}

static void ppp_nl_dellink(struct net_device *dev, struct list_head *head)
{}

static size_t ppp_nl_get_size(const struct net_device *dev)
{}

static int ppp_nl_fill_info(struct sk_buff *skb, const struct net_device *dev)
{}

static struct net *ppp_nl_get_link_net(const struct net_device *dev)
{}

static struct rtnl_link_ops ppp_link_ops __read_mostly =;

#define PPP_MAJOR

/* Called at boot time if ppp is compiled into the kernel,
   or at module load time (from init_module) if compiled as a module. */
static int __init ppp_init(void)
{}

/*
 * Network interface unit routines.
 */
static netdev_tx_t
ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static int
ppp_net_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
		       void __user *addr, int cmd)
{}

static void
ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64)
{}

static int ppp_dev_init(struct net_device *dev)
{}

static void ppp_dev_uninit(struct net_device *dev)
{}

static void ppp_dev_priv_destructor(struct net_device *dev)
{}

static int ppp_fill_forward_path(struct net_device_path_ctx *ctx,
				 struct net_device_path *path)
{}

static const struct net_device_ops ppp_netdev_ops =;

static const struct device_type ppp_type =;

static void ppp_setup(struct net_device *dev)
{}

/*
 * Transmit-side routines.
 */

/* Called to do any work queued up on the transmit side that can now be done */
static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
{}

static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
{}

static inline struct sk_buff *
pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
{}

/*
 * Compress and send a frame.
 * The caller should have locked the xmit path,
 * and xmit_pending should be 0.
 */
static void
ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
{}

/*
 * Try to send the frame in xmit_pending.
 * The caller should have the xmit path locked.
 */
static void
ppp_push(struct ppp *ppp)
{}

#ifdef CONFIG_PPP_MULTILINK
static bool mp_protocol_compress __read_mostly =;
module_param(mp_protocol_compress, bool, 0644);
MODULE_PARM_DESC();

/*
 * Divide a packet to be transmitted into fragments and
 * send them out the individual links.
 */
static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
{}
#endif /* CONFIG_PPP_MULTILINK */

/* Try to send data out on a channel */
static void __ppp_channel_push(struct channel *pch)
{}

static void ppp_channel_push(struct channel *pch)
{}

/*
 * Receive-side routines.
 */

struct ppp_mp_skb_parm {};
#define PPP_MP_CB(skb)

static inline void
ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
{}

/**
 * __ppp_decompress_proto - Decompress protocol field, slim version.
 * @skb: Socket buffer where protocol field should be decompressed. It must have
 *	 at least 1 byte of head room and 1 byte of linear data. First byte of
 *	 data must be a protocol field byte.
 *
 * Decompress protocol field in PPP header if it's compressed, e.g. when
 * Protocol-Field-Compression (PFC) was negotiated. No checks w.r.t. skb data
 * length are done in this function.
 */
static void __ppp_decompress_proto(struct sk_buff *skb)
{}

/**
 * ppp_decompress_proto - Check skb data room and decompress protocol field.
 * @skb: Socket buffer where protocol field should be decompressed. First byte
 *	 of data must be a protocol field byte.
 *
 * Decompress protocol field in PPP header if it's compressed, e.g. when
 * Protocol-Field-Compression (PFC) was negotiated. This function also makes
 * sure that skb data room is sufficient for Protocol field, before and after
 * decompression.
 *
 * Return: true - decompressed successfully, false - not enough room in skb.
 */
static bool ppp_decompress_proto(struct sk_buff *skb)
{}

/* Attempt to handle a frame via. a bridged channel, if one exists.
 * If the channel is bridged, the frame is consumed by the bridge.
 * If not, the caller must handle the frame by normal recv mechanisms.
 * Returns true if the frame is consumed, false otherwise.
 */
static bool ppp_channel_bridge_input(struct channel *pch, struct sk_buff *skb)
{}

void
ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
{}

/* Put a 0-length skb in the receive queue as an error indication */
void
ppp_input_error(struct ppp_channel *chan, int code)
{}

/*
 * We come in here to process a received frame.
 * The receive side of the ppp unit is locked.
 */
static void
ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
{}

static void
ppp_receive_error(struct ppp *ppp)
{}

static void
ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
{}

static struct sk_buff *
ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb)
{}

#ifdef CONFIG_PPP_MULTILINK
/*
 * Receive a multilink frame.
 * We put it on the reconstruction queue and then pull off
 * as many completed frames as we can.
 */
static void
ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
{}

/*
 * Insert a fragment on the MP reconstruction queue.
 * The queue is ordered by increasing sequence number.
 */
static void
ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb)
{}

/*
 * Reconstruct a packet from the MP fragment queue.
 * We go through increasing sequence numbers until we find a
 * complete packet, or we get to the sequence number for a fragment
 * which hasn't arrived but might still do so.
 */
static struct sk_buff *
ppp_mp_reconstruct(struct ppp *ppp)
{}
#endif /* CONFIG_PPP_MULTILINK */

/*
 * Channel interface.
 */

/* Create a new, unattached ppp channel. */
int ppp_register_channel(struct ppp_channel *chan)
{}

/* Create a new, unattached ppp channel for specified net. */
int ppp_register_net_channel(struct net *net, struct ppp_channel *chan)
{}

/*
 * Return the index of a channel.
 */
int ppp_channel_index(struct ppp_channel *chan)
{}

/*
 * Return the PPP unit number to which a channel is connected.
 */
int ppp_unit_number(struct ppp_channel *chan)
{}

/*
 * Return the PPP device interface name of a channel.
 */
char *ppp_dev_name(struct ppp_channel *chan)
{}


/*
 * Disconnect a channel from the generic layer.
 * This must be called in process context.
 */
void
ppp_unregister_channel(struct ppp_channel *chan)
{}

/*
 * Callback from a channel when it can accept more to transmit.
 * This should be called at BH/softirq level, not interrupt level.
 */
void
ppp_output_wakeup(struct ppp_channel *chan)
{}

/*
 * Compression control.
 */

/* Process the PPPIOCSCOMPRESS ioctl. */
static int
ppp_set_compress(struct ppp *ppp, struct ppp_option_data *data)
{}

/*
 * Look at a CCP packet and update our state accordingly.
 * We assume the caller has the xmit or recv path locked.
 */
static void
ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound)
{}

/* Free up compression resources. */
static void
ppp_ccp_closed(struct ppp *ppp)
{}

/* List of compressors. */
static LIST_HEAD(compressor_list);
static DEFINE_SPINLOCK(compressor_list_lock);

struct compressor_entry {};

static struct compressor_entry *
find_comp_entry(int proto)
{}

/* Register a compressor */
int
ppp_register_compressor(struct compressor *cp)
{}

/* Unregister a compressor */
void
ppp_unregister_compressor(struct compressor *cp)
{}

/* Find a compressor. */
static struct compressor *
find_compressor(int type)
{}

/*
 * Miscelleneous stuff.
 */

static void
ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
{}

/*
 * Stuff for handling the lists of ppp units and channels
 * and for initialization.
 */

/*
 * Create a new ppp interface unit.  Fails if it can't allocate memory
 * or if there is already a unit with the requested number.
 * unit == -1 means allocate a new number.
 */
static int ppp_create_interface(struct net *net, struct file *file, int *unit)
{}

/*
 * Initialize a ppp_file structure.
 */
static void
init_ppp_file(struct ppp_file *pf, int kind)
{}

/*
 * Free the memory used by a ppp unit.  This is only called once
 * there are no channels connected to the unit and no file structs
 * that reference the unit.
 */
static void ppp_destroy_interface(struct ppp *ppp)
{}

/*
 * Locate an existing ppp unit.
 * The caller should have locked the all_ppp_mutex.
 */
static struct ppp *
ppp_find_unit(struct ppp_net *pn, int unit)
{}

/*
 * Locate an existing ppp channel.
 * The caller should have locked the all_channels_lock.
 * First we look in the new_channels list, then in the
 * all_channels list.  If found in the new_channels list,
 * we move it to the all_channels list.  This is for speed
 * when we have a lot of channels in use.
 */
static struct channel *
ppp_find_channel(struct ppp_net *pn, int unit)
{}

/*
 * Connect a PPP channel to a PPP interface unit.
 */
static int
ppp_connect_channel(struct channel *pch, int unit)
{}

/*
 * Disconnect a channel from its ppp unit.
 */
static int
ppp_disconnect_channel(struct channel *pch)
{}

/*
 * Free up the resources used by a ppp channel.
 */
static void ppp_destroy_channel(struct channel *pch)
{}

static void __exit ppp_cleanup(void)
{}

/*
 * Units handling. Caller must protect concurrent access
 * by holding all_ppp_mutex
 */

/* associate pointer with specified number */
static int unit_set(struct idr *p, void *ptr, int n)
{}

/* get new free unit number and associate pointer with it */
static int unit_get(struct idr *p, void *ptr, int min)
{}

/* put unit number back to a pool */
static void unit_put(struct idr *p, int n)
{}

/* get pointer associated with the number */
static void *unit_find(struct idr *p, int n)
{}

/* Module/initialization stuff */

module_init();
module_exit(ppp_cleanup);

EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_ALIAS_CHARDEV();
MODULE_ALIAS_RTNL_LINK();
MODULE_ALIAS();