#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 …
#define TUN_FASYNC …
#define TUN_VNET_LE …
#define TUN_VNET_BE …
#define TUN_FEATURES …
#define GOODCOPY_LEN …
#define FLT_EXACT_COUNT …
struct tap_filter { … };
#define MAX_TAP_QUEUES …
#define MAX_TAP_FLOWS …
#define TUN_FLOW_EXPIRE …
struct tun_file { … };
struct tun_page { … };
struct tun_flow_entry { … };
#define TUN_NUM_FLOW_ENTRIES …
#define TUN_MASK_FLOW_ENTRIES …
struct tun_prog { … };
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
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)
{ … }
static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash)
{ … }
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)
{ … }
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)
{ … }
static int run_filter(struct tap_filter *filter, const struct sk_buff *skb)
{ … }
static int check_filter(struct tap_filter *filter, const struct sk_buff *skb)
{ … }
static const struct ethtool_ops tun_ethtool_ops;
static int tun_net_init(struct net_device *dev)
{ … }
static void tun_net_uninit(struct net_device *dev)
{ … }
static int tun_net_open(struct net_device *dev)
{ … }
static int tun_net_close(struct net_device *dev)
{ … }
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)
{ … }
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 …
static void tun_net_initialize(struct net_device *dev)
{ … }
static bool tun_sock_writeable(struct tun_struct *tun, struct tun_file *tfile)
{ … }
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)
{ … }
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)
{ … }
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)
{ … }
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)
{ … }
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)
{ … }
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)
{ … }
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)
{ … }
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
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 = …;
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)
{ … }
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(…) …;