#define pr_fmt(fmt) …
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/udp.h>
#include <linux/igmp.h>
#include <linux/if_ether.h>
#include <linux/ethtool.h>
#include <net/arp.h>
#include <net/ndisc.h>
#include <net/gro.h>
#include <net/ipv6_stubs.h>
#include <net/ip.h>
#include <net/icmp.h>
#include <net/rtnetlink.h>
#include <net/inet_ecn.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/tun_proto.h>
#include <net/vxlan.h>
#include <net/nexthop.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ip6_tunnel.h>
#include <net/ip6_checksum.h>
#endif
#include "vxlan_private.h"
#define VXLAN_VERSION …
#define FDB_AGE_DEFAULT …
#define FDB_AGE_INTERVAL …
static unsigned short vxlan_port __read_mostly = …;
module_param_named(udp_port, vxlan_port, ushort, 0444);
MODULE_PARM_DESC(…) …;
static bool log_ecn_error = …;
module_param(log_ecn_error, bool, 0644);
MODULE_PARM_DESC(…) …;
unsigned int vxlan_net_id;
const u8 all_zeros_mac[ETH_ALEN + 2];
static struct rtnl_link_ops vxlan_link_ops;
static int vxlan_sock_add(struct vxlan_dev *vxlan);
static void vxlan_vs_del_dev(struct vxlan_dev *vxlan);
static u32 vxlan_salt __read_mostly;
static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
{ … }
static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
__be16 port, u32 flags, int ifindex)
{ … }
static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs,
int ifindex, __be32 vni,
struct vxlan_vni_node **vninode)
{ … }
static struct vxlan_dev *vxlan_find_vni(struct net *net, int ifindex,
__be32 vni, sa_family_t family,
__be16 port, u32 flags)
{ … }
static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
const struct vxlan_fdb *fdb,
u32 portid, u32 seq, int type, unsigned int flags,
const struct vxlan_rdst *rdst)
{ … }
static inline size_t vxlan_nlmsg_size(void)
{ … }
static void __vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
struct vxlan_rdst *rd, int type)
{ … }
static void vxlan_fdb_switchdev_notifier_info(const struct vxlan_dev *vxlan,
const struct vxlan_fdb *fdb,
const struct vxlan_rdst *rd,
struct netlink_ext_ack *extack,
struct switchdev_notifier_vxlan_fdb_info *fdb_info)
{ … }
static int vxlan_fdb_switchdev_call_notifiers(struct vxlan_dev *vxlan,
struct vxlan_fdb *fdb,
struct vxlan_rdst *rd,
bool adding,
struct netlink_ext_ack *extack)
{ … }
static int vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
struct vxlan_rdst *rd, int type, bool swdev_notify,
struct netlink_ext_ack *extack)
{ … }
static void vxlan_ip_miss(struct net_device *dev, union vxlan_addr *ipa)
{ … }
static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN])
{ … }
static u32 eth_hash(const unsigned char *addr)
{ … }
u32 eth_vni_hash(const unsigned char *addr, __be32 vni)
{ … }
u32 fdb_head_index(struct vxlan_dev *vxlan, const u8 *mac, __be32 vni)
{ … }
static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan,
const u8 *mac, __be32 vni)
{ … }
static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac, __be32 vni)
{ … }
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac, __be32 vni)
{ … }
static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f,
union vxlan_addr *ip, __be16 port,
__be32 vni, __u32 ifindex)
{ … }
int vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni,
struct switchdev_notifier_vxlan_fdb_info *fdb_info)
{ … }
EXPORT_SYMBOL_GPL(…);
static int vxlan_fdb_notify_one(struct notifier_block *nb,
const struct vxlan_dev *vxlan,
const struct vxlan_fdb *f,
const struct vxlan_rdst *rdst,
struct netlink_ext_ack *extack)
{ … }
int vxlan_fdb_replay(const struct net_device *dev, __be32 vni,
struct notifier_block *nb,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL_GPL(…);
void vxlan_fdb_clear_offload(const struct net_device *dev, __be32 vni)
{ … }
EXPORT_SYMBOL_GPL(…);
static int vxlan_fdb_replace(struct vxlan_fdb *f,
union vxlan_addr *ip, __be16 port, __be32 vni,
__u32 ifindex, struct vxlan_rdst *oldrd)
{ … }
static int vxlan_fdb_append(struct vxlan_fdb *f,
union vxlan_addr *ip, __be16 port, __be32 vni,
__u32 ifindex, struct vxlan_rdst **rdp)
{ … }
static bool vxlan_parse_gpe_proto(struct vxlanhdr *hdr, __be16 *protocol)
{ … }
static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb,
unsigned int off,
struct vxlanhdr *vh, size_t hdrlen,
__be32 vni_field,
struct gro_remcsum *grc,
bool nopartial)
{ … }
static struct vxlanhdr *vxlan_gro_prepare_receive(struct sock *sk,
struct list_head *head,
struct sk_buff *skb,
struct gro_remcsum *grc)
{ … }
static struct sk_buff *vxlan_gro_receive(struct sock *sk,
struct list_head *head,
struct sk_buff *skb)
{ … }
static struct sk_buff *vxlan_gpe_gro_receive(struct sock *sk,
struct list_head *head,
struct sk_buff *skb)
{ … }
static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
{ … }
static int vxlan_gpe_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
{ … }
static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, const u8 *mac,
__u16 state, __be32 src_vni,
__u16 ndm_flags)
{ … }
static void vxlan_fdb_insert(struct vxlan_dev *vxlan, const u8 *mac,
__be32 src_vni, struct vxlan_fdb *f)
{ … }
static int vxlan_fdb_nh_update(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
u32 nhid, struct netlink_ext_ack *extack)
{ … }
int vxlan_fdb_create(struct vxlan_dev *vxlan,
const u8 *mac, union vxlan_addr *ip,
__u16 state, __be16 port, __be32 src_vni,
__be32 vni, __u32 ifindex, __u16 ndm_flags,
u32 nhid, struct vxlan_fdb **fdb,
struct netlink_ext_ack *extack)
{ … }
static void __vxlan_fdb_free(struct vxlan_fdb *f)
{ … }
static void vxlan_fdb_free(struct rcu_head *head)
{ … }
static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f,
bool do_notify, bool swdev_notify)
{ … }
static void vxlan_dst_free(struct rcu_head *head)
{ … }
static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
union vxlan_addr *ip,
__u16 state, __u16 flags,
__be16 port, __be32 vni,
__u32 ifindex, __u16 ndm_flags,
struct vxlan_fdb *f, u32 nhid,
bool swdev_notify,
struct netlink_ext_ack *extack)
{ … }
static int vxlan_fdb_update_create(struct vxlan_dev *vxlan,
const u8 *mac, union vxlan_addr *ip,
__u16 state, __u16 flags,
__be16 port, __be32 src_vni, __be32 vni,
__u32 ifindex, __u16 ndm_flags, u32 nhid,
bool swdev_notify,
struct netlink_ext_ack *extack)
{ … }
int vxlan_fdb_update(struct vxlan_dev *vxlan,
const u8 *mac, union vxlan_addr *ip,
__u16 state, __u16 flags,
__be16 port, __be32 src_vni, __be32 vni,
__u32 ifindex, __u16 ndm_flags, u32 nhid,
bool swdev_notify,
struct netlink_ext_ack *extack)
{ … }
static void vxlan_fdb_dst_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f,
struct vxlan_rdst *rd, bool swdev_notify)
{ … }
static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
union vxlan_addr *ip, __be16 *port, __be32 *src_vni,
__be32 *vni, u32 *ifindex, u32 *nhid,
struct netlink_ext_ack *extack)
{ … }
static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr, u16 vid, u16 flags,
struct netlink_ext_ack *extack)
{ … }
int __vxlan_fdb_delete(struct vxlan_dev *vxlan,
const unsigned char *addr, union vxlan_addr ip,
__be16 port, __be32 src_vni, __be32 vni,
u32 ifindex, bool swdev_notify)
{ … }
static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr, u16 vid,
struct netlink_ext_ack *extack)
{ … }
static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
struct net_device *dev,
struct net_device *filter_dev, int *idx)
{ … }
static int vxlan_fdb_get(struct sk_buff *skb,
struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr,
u16 vid, u32 portid, u32 seq,
struct netlink_ext_ack *extack)
{ … }
static bool vxlan_snoop(struct net_device *dev,
union vxlan_addr *src_ip, const u8 *src_mac,
u32 src_ifindex, __be32 vni)
{ … }
static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
{ … }
static void vxlan_sock_release(struct vxlan_dev *vxlan)
{ … }
static bool vxlan_remcsum(struct vxlanhdr *unparsed,
struct sk_buff *skb, u32 vxflags)
{ … }
static void vxlan_parse_gbp_hdr(struct vxlanhdr *unparsed,
struct sk_buff *skb, u32 vxflags,
struct vxlan_metadata *md)
{ … }
static bool vxlan_set_mac(struct vxlan_dev *vxlan,
struct vxlan_sock *vs,
struct sk_buff *skb, __be32 vni)
{ … }
static bool vxlan_ecn_decapsulate(struct vxlan_sock *vs, void *oiph,
struct sk_buff *skb)
{ … }
static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
{ … }
static int vxlan_err_lookup(struct sock *sk, struct sk_buff *skb)
{ … }
static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static struct sk_buff *vxlan_na_create(struct sk_buff *request,
struct neighbour *n, bool isrouter)
{ … }
static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
{ … }
#endif
static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
{ … }
static int vxlan_build_gpe_hdr(struct vxlanhdr *vxh, __be16 protocol)
{ … }
static int vxlan_build_skb(struct sk_buff *skb, struct dst_entry *dst,
int iphdr_len, __be32 vni,
struct vxlan_metadata *md, u32 vxflags,
bool udp_sum)
{ … }
static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
struct vxlan_dev *dst_vxlan, __be32 vni,
bool snoop)
{ … }
static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev,
struct vxlan_dev *vxlan,
int addr_family,
__be16 dst_port, int dst_ifindex, __be32 vni,
struct dst_entry *dst,
u32 rt_flags)
{ … }
void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
__be32 default_vni, struct vxlan_rdst *rdst, bool did_rsc)
{ … }
static void vxlan_xmit_nh(struct sk_buff *skb, struct net_device *dev,
struct vxlan_fdb *f, __be32 vni, bool did_rsc)
{ … }
static netdev_tx_t vxlan_xmit_nhid(struct sk_buff *skb, struct net_device *dev,
u32 nhid, __be32 vni)
{ … }
static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
{ … }
static void vxlan_cleanup(struct timer_list *t)
{ … }
static void vxlan_vs_del_dev(struct vxlan_dev *vxlan)
{ … }
static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan,
struct vxlan_dev_node *node)
{ … }
static int vxlan_init(struct net_device *dev)
{ … }
static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan, __be32 vni)
{ … }
static void vxlan_uninit(struct net_device *dev)
{ … }
static int vxlan_open(struct net_device *dev)
{ … }
struct vxlan_fdb_flush_desc { … };
static bool vxlan_fdb_is_default_entry(const struct vxlan_fdb *f,
const struct vxlan_dev *vxlan)
{ … }
static bool vxlan_fdb_nhid_matches(const struct vxlan_fdb *f, u32 nhid)
{ … }
static bool vxlan_fdb_flush_matches(const struct vxlan_fdb *f,
const struct vxlan_dev *vxlan,
const struct vxlan_fdb_flush_desc *desc)
{ … }
static bool
vxlan_fdb_flush_should_match_remotes(const struct vxlan_fdb_flush_desc *desc)
{ … }
static bool
vxlan_fdb_flush_remote_matches(const struct vxlan_fdb_flush_desc *desc,
const struct vxlan_rdst *rd)
{ … }
static void
vxlan_fdb_flush_match_remotes(struct vxlan_fdb *f, struct vxlan_dev *vxlan,
const struct vxlan_fdb_flush_desc *desc,
bool *p_destroy_fdb)
{ … }
static void vxlan_flush(struct vxlan_dev *vxlan,
const struct vxlan_fdb_flush_desc *desc)
{ … }
static const struct nla_policy vxlan_del_bulk_policy[NDA_MAX + 1] = …;
#define VXLAN_FDB_FLUSH_IGNORED_NDM_FLAGS …
#define VXLAN_FDB_FLUSH_ALLOWED_NDM_STATES …
#define VXLAN_FDB_FLUSH_ALLOWED_NDM_FLAGS …
static int vxlan_fdb_delete_bulk(struct nlmsghdr *nlh, struct net_device *dev,
struct netlink_ext_ack *extack)
{ … }
static int vxlan_stop(struct net_device *dev)
{ … }
static void vxlan_set_multicast_list(struct net_device *dev)
{ … }
static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
{ … }
static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
{ … }
static const struct net_device_ops vxlan_netdev_ether_ops = …;
static const struct net_device_ops vxlan_netdev_raw_ops = …;
static const struct device_type vxlan_type = …;
static void vxlan_offload_rx_ports(struct net_device *dev, bool push)
{ … }
static void vxlan_setup(struct net_device *dev)
{ … }
static void vxlan_ether_setup(struct net_device *dev)
{ … }
static void vxlan_raw_setup(struct net_device *dev)
{ … }
static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = …;
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{ … }
static void vxlan_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{ … }
static int vxlan_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{ … }
static const struct ethtool_ops vxlan_ethtool_ops = …;
static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
__be16 port, u32 flags, int ifindex)
{ … }
static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
__be16 port, u32 flags,
int ifindex)
{ … }
static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6)
{ … }
static int vxlan_sock_add(struct vxlan_dev *vxlan)
{ … }
int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan,
struct vxlan_config *conf, __be32 vni)
{ … }
static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf,
struct net_device **lower,
struct vxlan_dev *old,
struct netlink_ext_ack *extack)
{ … }
static void vxlan_config_apply(struct net_device *dev,
struct vxlan_config *conf,
struct net_device *lowerdev,
struct net *src_net,
bool changelink)
{ … }
static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
struct vxlan_config *conf, bool changelink,
struct netlink_ext_ack *extack)
{ … }
static int __vxlan_dev_create(struct net *net, struct net_device *dev,
struct vxlan_config *conf,
struct netlink_ext_ack *extack)
{ … }
static int vxlan_nl2flag(struct vxlan_config *conf, struct nlattr *tb[],
int attrtype, unsigned long mask, bool changelink,
bool changelink_supported,
struct netlink_ext_ack *extack)
{ … }
static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
struct net_device *dev, struct vxlan_config *conf,
bool changelink, struct netlink_ext_ack *extack)
{ … }
static int vxlan_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{ … }
static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
{ … }
static void vxlan_dellink(struct net_device *dev, struct list_head *head)
{ … }
static size_t vxlan_get_size(const struct net_device *dev)
{ … }
static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
{ … }
static struct net *vxlan_get_link_net(const struct net_device *dev)
{ … }
static struct rtnl_link_ops vxlan_link_ops __read_mostly = …;
struct net_device *vxlan_dev_create(struct net *net, const char *name,
u8 name_assign_type,
struct vxlan_config *conf)
{ … }
EXPORT_SYMBOL_GPL(…);
static void vxlan_handle_lowerdev_unregister(struct vxlan_net *vn,
struct net_device *dev)
{ … }
static int vxlan_netdevice_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{ … }
static struct notifier_block vxlan_notifier_block __read_mostly = …;
static void
vxlan_fdb_offloaded_set(struct net_device *dev,
struct switchdev_notifier_vxlan_fdb_info *fdb_info)
{ … }
static int
vxlan_fdb_external_learn_add(struct net_device *dev,
struct switchdev_notifier_vxlan_fdb_info *fdb_info)
{ … }
static int
vxlan_fdb_external_learn_del(struct net_device *dev,
struct switchdev_notifier_vxlan_fdb_info *fdb_info)
{ … }
static int vxlan_switchdev_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{ … }
static struct notifier_block vxlan_switchdev_notifier_block __read_mostly = …;
static void vxlan_fdb_nh_flush(struct nexthop *nh)
{ … }
static int vxlan_nexthop_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{ … }
static __net_init int vxlan_init_net(struct net *net)
{ … }
static void __net_exit vxlan_destroy_tunnels(struct vxlan_net *vn,
struct list_head *dev_to_kill)
{ … }
static void __net_exit vxlan_exit_batch_rtnl(struct list_head *net_list,
struct list_head *dev_to_kill)
{ … }
static void __net_exit vxlan_exit_net(struct net *net)
{ … }
static struct pernet_operations vxlan_net_ops = …;
static int __init vxlan_init_module(void)
{ … }
late_initcall(vxlan_init_module);
static void __exit vxlan_cleanup_module(void)
{ … }
module_exit(vxlan_cleanup_module);
MODULE_LICENSE(…) …;
MODULE_VERSION(…);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_ALIAS_RTNL_LINK(…) …;