96 lines
2.4 KiB
C
96 lines
2.4 KiB
C
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||
|
/*
|
||
|
* Vxlan private header file
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifndef _VXLAN_PRIVATE_H
|
||
|
#define _VXLAN_PRIVATE_H
|
||
|
|
||
|
extern unsigned int vxlan_net_id;
|
||
|
extern const u8 all_zeros_mac[ETH_ALEN + 2];
|
||
|
|
||
|
#define PORT_HASH_BITS 8
|
||
|
#define PORT_HASH_SIZE (1 << PORT_HASH_BITS)
|
||
|
|
||
|
/* per-network namespace private data for this module */
|
||
|
struct vxlan_net {
|
||
|
struct list_head vxlan_list;
|
||
|
struct hlist_head sock_list[PORT_HASH_SIZE];
|
||
|
spinlock_t sock_lock;
|
||
|
struct notifier_block nexthop_notifier_block;
|
||
|
};
|
||
|
|
||
|
/* Forwarding table entry */
|
||
|
struct vxlan_fdb {
|
||
|
struct hlist_node hlist; /* linked list of entries */
|
||
|
struct rcu_head rcu;
|
||
|
unsigned long updated; /* jiffies */
|
||
|
unsigned long used;
|
||
|
struct list_head remotes;
|
||
|
u8 eth_addr[ETH_ALEN];
|
||
|
u16 state; /* see ndm_state */
|
||
|
__be32 vni;
|
||
|
u16 flags; /* see ndm_flags and below */
|
||
|
struct list_head nh_list;
|
||
|
struct nexthop __rcu *nh;
|
||
|
struct vxlan_dev __rcu *vdev;
|
||
|
};
|
||
|
|
||
|
#define NTF_VXLAN_ADDED_BY_USER 0x100
|
||
|
|
||
|
/* Virtual Network hash table head */
|
||
|
static inline struct hlist_head *vni_head(struct vxlan_sock *vs, __be32 vni)
|
||
|
{
|
||
|
return &vs->vni_list[hash_32((__force u32)vni, VNI_HASH_BITS)];
|
||
|
}
|
||
|
|
||
|
/* Socket hash table head */
|
||
|
static inline struct hlist_head *vs_head(struct net *net, __be16 port)
|
||
|
{
|
||
|
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
|
||
|
|
||
|
return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];
|
||
|
}
|
||
|
|
||
|
/* First remote destination for a forwarding entry.
|
||
|
* Guaranteed to be non-NULL because remotes are never deleted.
|
||
|
*/
|
||
|
static inline struct vxlan_rdst *first_remote_rcu(struct vxlan_fdb *fdb)
|
||
|
{
|
||
|
if (rcu_access_pointer(fdb->nh))
|
||
|
return NULL;
|
||
|
return list_entry_rcu(fdb->remotes.next, struct vxlan_rdst, list);
|
||
|
}
|
||
|
|
||
|
static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb)
|
||
|
{
|
||
|
if (rcu_access_pointer(fdb->nh))
|
||
|
return NULL;
|
||
|
return list_first_entry(&fdb->remotes, struct vxlan_rdst, list);
|
||
|
}
|
||
|
|
||
|
#if IS_ENABLED(CONFIG_IPV6)
|
||
|
static inline
|
||
|
bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
|
||
|
{
|
||
|
if (a->sa.sa_family != b->sa.sa_family)
|
||
|
return false;
|
||
|
if (a->sa.sa_family == AF_INET6)
|
||
|
return ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
|
||
|
else
|
||
|
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
|
||
|
}
|
||
|
|
||
|
#else /* !CONFIG_IPV6 */
|
||
|
|
||
|
static inline
|
||
|
bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
|
||
|
{
|
||
|
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|