linux/drivers/net/tun.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  TUN - Universal TUN/TAP device driver.
 *  Copyright (C) 1999-2002 Maxim Krasnyansky <[email protected]>
 *
 *  $Id: tun.c,v 1.15 2002/03/01 02:44:24 maxk Exp $
 */

/*
 *  Changes:
 *
 *  Mike Kershaw <[email protected]> 2005/08/14
 *    Add TUNSETLINK ioctl to set the link encapsulation
 *
 *  Mark Smith <[email protected]>
 *    Use eth_random_addr() for tap MAC address.
 *
 *  Harald Roelle <[email protected]>  2004/04/20
 *    Fixes in packet dropping, queue length setting and queue wakeup.
 *    Increased default tx queue length.
 *    Added ethtool API.
 *    Minor cleanups
 *
 *  Daniel Podlejski <[email protected]>
 *    Modifications for 2.3.99-pre5 kernel.
 */

#define pr_fmt(fmt)

#define DRV_NAME
#define DRV_VERSION
#define DRV_DESCRIPTION
#define DRV_COPYRIGHT

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched/signal.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/miscdevice.h>
#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
#include <linux/compat.h>
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_tun.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
#include <linux/math.h>
#include <linux/nsproxy.h>
#include <linux/virtio_net.h>
#include <linux/rcupdate.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
#include <net/sock.h>
#include <net/xdp.h>
#include <net/ip_tunnels.h>
#include <linux/seq_file.h>
#include <linux/uio.h>
#include <linux/skb_array.h>
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
#include <linux/mutex.h>
#include <linux/ieee802154.h>
#include <linux/if_ltalk.h>
#include <uapi/linux/if_fddi.h>
#include <uapi/linux/if_hippi.h>
#include <uapi/linux/if_fc.h>
#include <net/ax25.h>
#include <net/rose.h>
#include <net/6lowpan.h>
#include <net/rps.h>

#include <linux/uaccess.h>
#include <linux/proc_fs.h>

static void tun_default_link_ksettings(struct net_device *dev,
				       struct ethtool_link_ksettings *cmd);

#define TUN_RX_PAD

/* TUN device flags */

/* IFF_ATTACH_QUEUE is never stored in device flags,
 * overload it to mean fasync when stored there.
 */
#define TUN_FASYNC
/* High bits in flags field are unused. */
#define TUN_VNET_LE
#define TUN_VNET_BE

#define TUN_FEATURES

#define GOODCOPY_LEN

#define FLT_EXACT_COUNT
struct tap_filter {};

/* MAX_TAP_QUEUES 256 is chosen to allow rx/tx queues to be equal
 * to max number of VCPUs in guest. */
#define MAX_TAP_QUEUES
#define MAX_TAP_FLOWS

#define TUN_FLOW_EXPIRE

/* A tun_file connects an open character device to a tuntap netdevice. It
 * also contains all socket related structures (except sock_fprog and tap_filter)
 * to serve as one transmit queue for tuntap device. The sock_fprog and
 * tap_filter were kept in tun_struct since they were used for filtering for the
 * netdevice not for a specific queue (at least I didn't see the requirement for
 * this).
 *
 * RCU usage:
 * The tun_file and tun_struct are loosely coupled, the pointer from one to the
 * other can only be read while rcu_read_lock or rtnl_lock is held.
 */
struct tun_file {};

struct tun_page {};

struct tun_flow_entry {};

#define TUN_NUM_FLOW_ENTRIES
#define TUN_MASK_FLOW_ENTRIES

struct tun_prog {};

/* Since the socket were moved to tun_file, to preserve the behavior of persist
 * device, socket filter, sndbuf and vnet header size were restore when the
 * file were attached to a persist device.
 */
struct tun_struct {};

struct veth {};

static void tun_flow_init(struct tun_struct *tun);
static void tun_flow_uninit(struct tun_struct *tun);

static int tun_napi_receive(struct napi_struct *napi, int budget)
{}

static int tun_napi_poll(struct napi_struct *napi, int budget)
{}

static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile,
			  bool napi_en, bool napi_frags)
{}

static void tun_napi_enable(struct tun_file *tfile)
{}

static void tun_napi_disable(struct tun_file *tfile)
{}

static void tun_napi_del(struct tun_file *tfile)
{}

static bool tun_napi_frags_enabled(const struct tun_file *tfile)
{}

#ifdef CONFIG_TUN_VNET_CROSS_LE
static inline bool tun_legacy_is_little_endian(struct tun_struct *tun)
{}

static long tun_get_vnet_be(struct tun_struct *tun, int __user *argp)
{}

static long tun_set_vnet_be(struct tun_struct *tun, int __user *argp)
{}
#else
static inline bool tun_legacy_is_little_endian(struct tun_struct *tun)
{
	return virtio_legacy_is_little_endian();
}

static long tun_get_vnet_be(struct tun_struct *tun, int __user *argp)
{
	return -EINVAL;
}

static long tun_set_vnet_be(struct tun_struct *tun, int __user *argp)
{
	return -EINVAL;
}
#endif /* CONFIG_TUN_VNET_CROSS_LE */

static inline bool tun_is_little_endian(struct tun_struct *tun)
{}

static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
{}

static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val)
{}

static inline u32 tun_hashfn(u32 rxhash)
{}

static struct tun_flow_entry *tun_flow_find(struct hlist_head *head, u32 rxhash)
{}

static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun,
					      struct hlist_head *head,
					      u32 rxhash, u16 queue_index)
{}

static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e)
{}

static void tun_flow_flush(struct tun_struct *tun)
{}

static void tun_flow_delete_by_queue(struct tun_struct *tun, u16 queue_index)
{}

static void tun_flow_cleanup(struct timer_list *t)
{}

static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
			    struct tun_file *tfile)
{}

/* Save the hash received in the stack receive path and update the
 * flow_hash table accordingly.
 */
static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash)
{}

/* We try to identify a flow through its rxhash. The reason that
 * we do not check rxq no. is because some cards(e.g 82599), chooses
 * the rxq based on the txq where the last packet of the flow comes. As
 * the userspace application move between processors, we may get a
 * different rxq no. here.
 */
static u16 tun_automq_select_queue(struct tun_struct *tun, struct sk_buff *skb)
{}

static u16 tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *skb)
{}

static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb,
			    struct net_device *sb_dev)
{}

static inline bool tun_not_capable(struct tun_struct *tun)
{}

static void tun_set_real_num_queues(struct tun_struct *tun)
{}

static void tun_disable_queue(struct tun_struct *tun, struct tun_file *tfile)
{}

static struct tun_struct *tun_enable_queue(struct tun_file *tfile)
{}

void tun_ptr_free(void *ptr)
{}
EXPORT_SYMBOL_GPL();

static void tun_queue_purge(struct tun_file *tfile)
{}

static void __tun_detach(struct tun_file *tfile, bool clean)
{}

static void tun_detach(struct tun_file *tfile, bool clean)
{}

static void tun_detach_all(struct net_device *dev)
{}

static int tun_attach(struct tun_struct *tun, struct file *file,
		      bool skip_filter, bool napi, bool napi_frags,
		      bool publish_tun)
{}

static struct tun_struct *tun_get(struct tun_file *tfile)
{}

static void tun_put(struct tun_struct *tun)
{}

/* TAP filtering */
static void addr_hash_set(u32 *mask, const u8 *addr)
{}

static unsigned int addr_hash_test(const u32 *mask, const u8 *addr)
{}

static int update_filter(struct tap_filter *filter, void __user *arg)
{}

/* Returns: 0 - drop, !=0 - accept */
static int run_filter(struct tap_filter *filter, const struct sk_buff *skb)
{}

/*
 * Checks whether the packet is accepted or not.
 * Returns: 0 - drop, !=0 - accept
 */
static int check_filter(struct tap_filter *filter, const struct sk_buff *skb)
{}

/* Network device part of the driver */

static const struct ethtool_ops tun_ethtool_ops;

static int tun_net_init(struct net_device *dev)
{}

/* Net device detach from fd. */
static void tun_net_uninit(struct net_device *dev)
{}

/* Net device open. */
static int tun_net_open(struct net_device *dev)
{}

/* Net device close. */
static int tun_net_close(struct net_device *dev)
{}

/* Net device start xmit */
static void tun_automq_xmit(struct tun_struct *tun, struct sk_buff *skb)
{}

static unsigned int run_ebpf_filter(struct tun_struct *tun,
				    struct sk_buff *skb,
				    int len)
{}

/* Net device start xmit */
static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static void tun_net_mclist(struct net_device *dev)
{}

static netdev_features_t tun_net_fix_features(struct net_device *dev,
	netdev_features_t features)
{}

static void tun_set_headroom(struct net_device *dev, int new_hr)
{}

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

static int tun_xdp_set(struct net_device *dev, struct bpf_prog *prog,
		       struct netlink_ext_ack *extack)
{}

static int tun_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{}

static int tun_net_change_carrier(struct net_device *dev, bool new_carrier)
{}

static const struct net_device_ops tun_netdev_ops =;

static void __tun_xdp_flush_tfile(struct tun_file *tfile)
{}

static int tun_xdp_xmit(struct net_device *dev, int n,
			struct xdp_frame **frames, u32 flags)
{}

static int tun_xdp_tx(struct net_device *dev, struct xdp_buff *xdp)
{}

static const struct net_device_ops tap_netdev_ops =;

static void tun_flow_init(struct tun_struct *tun)
{}

static void tun_flow_uninit(struct tun_struct *tun)
{}

#define MIN_MTU
#define MAX_MTU

/* Initialize net device. */
static void tun_net_initialize(struct net_device *dev)
{}

static bool tun_sock_writeable(struct tun_struct *tun, struct tun_file *tfile)
{}

/* Character device part */

/* Poll */
static __poll_t tun_chr_poll(struct file *file, poll_table *wait)
{}

static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile,
					    size_t len,
					    const struct iov_iter *it)
{}

/* prepad is the amount to reserve at front.  len is length after that.
 * linear is a hint as to how much to copy (usually headers). */
static struct sk_buff *tun_alloc_skb(struct tun_file *tfile,
				     size_t prepad, size_t len,
				     size_t linear, int noblock)
{}

static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile,
			   struct sk_buff *skb, int more)
{}

static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile,
			      int len, int noblock, bool zerocopy)
{}

static struct sk_buff *__tun_build_skb(struct tun_file *tfile,
				       struct page_frag *alloc_frag, char *buf,
				       int buflen, int len, int pad)
{}

static int tun_xdp_act(struct tun_struct *tun, struct bpf_prog *xdp_prog,
		       struct xdp_buff *xdp, u32 act)
{}

static struct sk_buff *tun_build_skb(struct tun_struct *tun,
				     struct tun_file *tfile,
				     struct iov_iter *from,
				     struct virtio_net_hdr *hdr,
				     int len, int *skb_xdp)
{}

/* Get packet from user space buffer */
static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
			    void *msg_control, struct iov_iter *from,
			    int noblock, bool more)
{}

static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from)
{}

static ssize_t tun_put_user_xdp(struct tun_struct *tun,
				struct tun_file *tfile,
				struct xdp_frame *xdp_frame,
				struct iov_iter *iter)
{}

/* Put packet to the user space buffer */
static ssize_t tun_put_user(struct tun_struct *tun,
			    struct tun_file *tfile,
			    struct sk_buff *skb,
			    struct iov_iter *iter)
{}

static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err)
{}

static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
			   struct iov_iter *to,
			   int noblock, void *ptr)
{}

static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to)
{}

static void tun_prog_free(struct rcu_head *rcu)
{}

static int __tun_set_ebpf(struct tun_struct *tun,
			  struct tun_prog __rcu **prog_p,
			  struct bpf_prog *prog)
{}

static void tun_free_netdev(struct net_device *dev)
{}

static void tun_setup(struct net_device *dev)
{}

/* Trivial set of netlink ops to allow deleting tun or tap
 * device with netlink.
 */
static int tun_validate(struct nlattr *tb[], struct nlattr *data[],
			struct netlink_ext_ack *extack)
{}

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

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

static struct rtnl_link_ops tun_link_ops __read_mostly =;

static void tun_sock_write_space(struct sock *sk)
{}

static void tun_put_page(struct tun_page *tpage)
{}

static int tun_xdp_one(struct tun_struct *tun,
		       struct tun_file *tfile,
		       struct xdp_buff *xdp, int *flush,
		       struct tun_page *tpage)
{}

static int tun_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
{}

static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len,
		       int flags)
{}

static int tun_ptr_peek_len(void *ptr)
{}

static int tun_peek_len(struct socket *sock)
{}

/* Ops structure to mimic raw sockets with tun */
static const struct proto_ops tun_socket_ops =;

static struct proto tun_proto =;

static int tun_flags(struct tun_struct *tun)
{}

static ssize_t tun_flags_show(struct device *dev, struct device_attribute *attr,
			      char *buf)
{}

static ssize_t owner_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{}

static ssize_t group_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{}

static DEVICE_ATTR_RO(tun_flags);
static DEVICE_ATTR_RO(owner);
static DEVICE_ATTR_RO(group);

static struct attribute *tun_dev_attrs[] =;

static const struct attribute_group tun_attr_group =;

static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
{}

static void tun_get_iff(struct tun_struct *tun, struct ifreq *ifr)
{}

/* This is like a cut-down ethtool ops, except done via tun fd so no
 * privs required. */
static int set_offload(struct tun_struct *tun, unsigned long arg)
{}

static void tun_detach_filter(struct tun_struct *tun, int n)
{}

static int tun_attach_filter(struct tun_struct *tun)
{}

static void tun_set_sndbuf(struct tun_struct *tun)
{}

static int tun_set_queue(struct file *file, struct ifreq *ifr)
{}

static int tun_set_ebpf(struct tun_struct *tun, struct tun_prog __rcu **prog_p,
			void __user *data)
{}

/* Return correct value for tun->dev->addr_len based on tun->dev->type. */
static unsigned char tun_get_addr_len(unsigned short type)
{}

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

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

#ifdef CONFIG_COMPAT
static long tun_chr_compat_ioctl(struct file *file,
			 unsigned int cmd, unsigned long arg)
{}
#endif /* CONFIG_COMPAT */

static int tun_chr_fasync(int fd, struct file *file, int on)
{}

static int tun_chr_open(struct inode *inode, struct file * file)
{}

static int tun_chr_close(struct inode *inode, struct file *file)
{}

#ifdef CONFIG_PROC_FS
static void tun_chr_show_fdinfo(struct seq_file *m, struct file *file)
{}
#endif

static const struct file_operations tun_fops =;

static struct miscdevice tun_miscdev =;

/* ethtool interface */

static void tun_default_link_ksettings(struct net_device *dev,
				       struct ethtool_link_ksettings *cmd)
{}

static int tun_get_link_ksettings(struct net_device *dev,
				  struct ethtool_link_ksettings *cmd)
{}

static int tun_set_link_ksettings(struct net_device *dev,
				  const struct ethtool_link_ksettings *cmd)
{}

static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{}

static u32 tun_get_msglevel(struct net_device *dev)
{}

static void tun_set_msglevel(struct net_device *dev, u32 value)
{}

static int tun_get_coalesce(struct net_device *dev,
			    struct ethtool_coalesce *ec,
			    struct kernel_ethtool_coalesce *kernel_coal,
			    struct netlink_ext_ack *extack)
{}

static int tun_set_coalesce(struct net_device *dev,
			    struct ethtool_coalesce *ec,
			    struct kernel_ethtool_coalesce *kernel_coal,
			    struct netlink_ext_ack *extack)
{}

static void tun_get_channels(struct net_device *dev,
			     struct ethtool_channels *channels)
{}

static const struct ethtool_ops tun_ethtool_ops =;

static int tun_queue_resize(struct tun_struct *tun)
{}

static int tun_device_event(struct notifier_block *unused,
			    unsigned long event, void *ptr)
{}

static struct notifier_block tun_notifier_block __read_mostly =;

static int __init tun_init(void)
{}

static void __exit tun_cleanup(void)
{}

/* Get an underlying socket object from tun file.  Returns error unless file is
 * attached to a device.  The returned object works like a packet socket, it
 * can be used for sock_sendmsg/sock_recvmsg.  The caller is responsible for
 * holding a reference to the file for as long as the socket is in use. */
struct socket *tun_get_socket(struct file *file)
{}
EXPORT_SYMBOL_GPL();

struct ptr_ring *tun_get_tx_ring(struct file *file)
{}
EXPORT_SYMBOL_GPL();

module_init();
module_exit(tun_cleanup);
MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_ALIAS_MISCDEV();
MODULE_ALIAS();