#include <linux/module.h>
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/sockios.h>
#include <linux/icmp.h>
#include <linux/if.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/net.h>
#include <linux/in6.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/icmpv6.h>
#include <linux/init.h>
#include <linux/route.h>
#include <linux/rtnetlink.h>
#include <linux/netfilter_ipv6.h>
#include <linux/slab.h>
#include <linux/hash.h>
#include <linux/uaccess.h>
#include <linux/atomic.h>
#include <net/icmp.h>
#include <net/ip.h>
#include <net/ip_tunnels.h>
#include <net/ipv6.h>
#include <net/ip6_route.h>
#include <net/addrconf.h>
#include <net/ip6_tunnel.h>
#include <net/xfrm.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <linux/etherdevice.h>
#define IP6_VTI_HASH_SIZE_SHIFT …
#define IP6_VTI_HASH_SIZE …
static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2)
{ … }
static int vti6_dev_init(struct net_device *dev);
static void vti6_dev_setup(struct net_device *dev);
static struct rtnl_link_ops vti6_link_ops __read_mostly;
static unsigned int vti6_net_id __read_mostly;
struct vti6_net { … };
#define for_each_vti6_tunnel_rcu(start) …
static struct ip6_tnl *
vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
const struct in6_addr *local)
{ … }
static struct ip6_tnl __rcu **
vti6_tnl_bucket(struct vti6_net *ip6n, const struct __ip6_tnl_parm *p)
{ … }
static void
vti6_tnl_link(struct vti6_net *ip6n, struct ip6_tnl *t)
{ … }
static void
vti6_tnl_unlink(struct vti6_net *ip6n, struct ip6_tnl *t)
{ … }
static int vti6_tnl_create2(struct net_device *dev)
{ … }
static struct ip6_tnl *vti6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
{ … }
static struct ip6_tnl *vti6_locate(struct net *net, struct __ip6_tnl_parm *p,
int create)
{ … }
static void vti6_dev_uninit(struct net_device *dev)
{ … }
static int vti6_input_proto(struct sk_buff *skb, int nexthdr, __be32 spi,
int encap_type)
{ … }
static int vti6_rcv(struct sk_buff *skb)
{ … }
static int vti6_rcv_cb(struct sk_buff *skb, int err)
{ … }
static inline bool
vti6_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr)
{ … }
static bool vti6_state_check(const struct xfrm_state *x,
const struct in6_addr *dst,
const struct in6_addr *src)
{ … }
static int
vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
{ … }
static netdev_tx_t
vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
{ … }
static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{ … }
static void vti6_link_config(struct ip6_tnl *t, bool keep_mtu)
{ … }
static int
vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p,
bool keep_mtu)
{ … }
static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p,
bool keep_mtu)
{ … }
static void
vti6_parm_from_user(struct __ip6_tnl_parm *p, const struct ip6_tnl_parm2 *u)
{ … }
static void
vti6_parm_to_user(struct ip6_tnl_parm2 *u, const struct __ip6_tnl_parm *p)
{ … }
static int
vti6_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd)
{ … }
static const struct net_device_ops vti6_netdev_ops = …;
static void vti6_dev_setup(struct net_device *dev)
{ … }
static inline int vti6_dev_init_gen(struct net_device *dev)
{ … }
static int vti6_dev_init(struct net_device *dev)
{ … }
static int __net_init vti6_fb_tnl_dev_init(struct net_device *dev)
{ … }
static int vti6_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{ … }
static void vti6_netlink_parms(struct nlattr *data[],
struct __ip6_tnl_parm *parms)
{ … }
static int vti6_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{ … }
static void vti6_dellink(struct net_device *dev, struct list_head *head)
{ … }
static int vti6_changelink(struct net_device *dev, struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
{ … }
static size_t vti6_get_size(const struct net_device *dev)
{ … }
static int vti6_fill_info(struct sk_buff *skb, const struct net_device *dev)
{ … }
static const struct nla_policy vti6_policy[IFLA_VTI_MAX + 1] = …;
static struct rtnl_link_ops vti6_link_ops __read_mostly = …;
static void __net_exit vti6_destroy_tunnels(struct vti6_net *ip6n,
struct list_head *list)
{ … }
static int __net_init vti6_init_net(struct net *net)
{ … }
static void __net_exit vti6_exit_batch_rtnl(struct list_head *net_list,
struct list_head *dev_to_kill)
{ … }
static struct pernet_operations vti6_net_ops = …;
static struct xfrm6_protocol vti_esp6_protocol __read_mostly = …;
static struct xfrm6_protocol vti_ah6_protocol __read_mostly = …;
static struct xfrm6_protocol vti_ipcomp6_protocol __read_mostly = …;
#if IS_REACHABLE(CONFIG_INET6_XFRM_TUNNEL)
static int vti6_rcv_tunnel(struct sk_buff *skb)
{ … }
static struct xfrm6_tunnel vti_ipv6_handler __read_mostly = …;
static struct xfrm6_tunnel vti_ip6ip_handler __read_mostly = …;
#endif
static int __init vti6_tunnel_init(void)
{ … }
static void __exit vti6_tunnel_cleanup(void)
{ … }
module_init(…) …;
module_exit(vti6_tunnel_cleanup);
MODULE_LICENSE(…) …;
MODULE_ALIAS_RTNL_LINK(…) …;
MODULE_ALIAS_NETDEV(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;