xref: /linux/drivers/net/vxlan/vxlan_private.h (revision 0be3ff0c)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  *	Vxlan private header file
4  *
5  */
6 
7 #ifndef _VXLAN_PRIVATE_H
8 #define _VXLAN_PRIVATE_H
9 
10 #include <linux/rhashtable.h>
11 
12 extern unsigned int vxlan_net_id;
13 extern const u8 all_zeros_mac[ETH_ALEN + 2];
14 extern const struct rhashtable_params vxlan_vni_rht_params;
15 
16 #define PORT_HASH_BITS	8
17 #define PORT_HASH_SIZE  (1 << PORT_HASH_BITS)
18 
19 /* per-network namespace private data for this module */
20 struct vxlan_net {
21 	struct list_head  vxlan_list;
22 	struct hlist_head sock_list[PORT_HASH_SIZE];
23 	spinlock_t	  sock_lock;
24 	struct notifier_block nexthop_notifier_block;
25 };
26 
27 /* Forwarding table entry */
28 struct vxlan_fdb {
29 	struct hlist_node hlist;	/* linked list of entries */
30 	struct rcu_head	  rcu;
31 	unsigned long	  updated;	/* jiffies */
32 	unsigned long	  used;
33 	struct list_head  remotes;
34 	u8		  eth_addr[ETH_ALEN];
35 	u16		  state;	/* see ndm_state */
36 	__be32		  vni;
37 	u16		  flags;	/* see ndm_flags and below */
38 	struct list_head  nh_list;
39 	struct nexthop __rcu *nh;
40 	struct vxlan_dev  __rcu *vdev;
41 };
42 
43 #define NTF_VXLAN_ADDED_BY_USER 0x100
44 
45 /* Virtual Network hash table head */
46 static inline struct hlist_head *vni_head(struct vxlan_sock *vs, __be32 vni)
47 {
48 	return &vs->vni_list[hash_32((__force u32)vni, VNI_HASH_BITS)];
49 }
50 
51 /* Socket hash table head */
52 static inline struct hlist_head *vs_head(struct net *net, __be16 port)
53 {
54 	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
55 
56 	return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];
57 }
58 
59 /* First remote destination for a forwarding entry.
60  * Guaranteed to be non-NULL because remotes are never deleted.
61  */
62 static inline struct vxlan_rdst *first_remote_rcu(struct vxlan_fdb *fdb)
63 {
64 	if (rcu_access_pointer(fdb->nh))
65 		return NULL;
66 	return list_entry_rcu(fdb->remotes.next, struct vxlan_rdst, list);
67 }
68 
69 static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb)
70 {
71 	if (rcu_access_pointer(fdb->nh))
72 		return NULL;
73 	return list_first_entry(&fdb->remotes, struct vxlan_rdst, list);
74 }
75 
76 #if IS_ENABLED(CONFIG_IPV6)
77 static inline
78 bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
79 {
80 	if (a->sa.sa_family != b->sa.sa_family)
81 		return false;
82 	if (a->sa.sa_family == AF_INET6)
83 		return ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
84 	else
85 		return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
86 }
87 
88 #else /* !CONFIG_IPV6 */
89 
90 static inline
91 bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
92 {
93 	return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
94 }
95 
96 #endif
97 
98 static inline struct vxlan_vni_node *
99 vxlan_vnifilter_lookup(struct vxlan_dev *vxlan, __be32 vni)
100 {
101 	struct vxlan_vni_group *vg;
102 
103 	vg = rcu_dereference_rtnl(vxlan->vnigrp);
104 	if (!vg)
105 		return NULL;
106 
107 	return rhashtable_lookup_fast(&vg->vni_hash, &vni,
108 				      vxlan_vni_rht_params);
109 }
110 
111 /* vxlan_core.c */
112 int vxlan_fdb_create(struct vxlan_dev *vxlan,
113 		     const u8 *mac, union vxlan_addr *ip,
114 		     __u16 state, __be16 port, __be32 src_vni,
115 		     __be32 vni, __u32 ifindex, __u16 ndm_flags,
116 		     u32 nhid, struct vxlan_fdb **fdb,
117 		     struct netlink_ext_ack *extack);
118 int __vxlan_fdb_delete(struct vxlan_dev *vxlan,
119 		       const unsigned char *addr, union vxlan_addr ip,
120 		       __be16 port, __be32 src_vni, __be32 vni,
121 		       u32 ifindex, bool swdev_notify);
122 u32 eth_vni_hash(const unsigned char *addr, __be32 vni);
123 u32 fdb_head_index(struct vxlan_dev *vxlan, const u8 *mac, __be32 vni);
124 int vxlan_fdb_update(struct vxlan_dev *vxlan,
125 		     const u8 *mac, union vxlan_addr *ip,
126 		     __u16 state, __u16 flags,
127 		     __be16 port, __be32 src_vni, __be32 vni,
128 		     __u32 ifindex, __u16 ndm_flags, u32 nhid,
129 		     bool swdev_notify, struct netlink_ext_ack *extack);
130 int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan,
131 		     struct vxlan_config *conf, __be32 vni);
132 
133 /* vxlan_vnifilter.c */
134 int vxlan_vnigroup_init(struct vxlan_dev *vxlan);
135 void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan);
136 
137 void vxlan_vnifilter_init(void);
138 void vxlan_vnifilter_uninit(void);
139 void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni,
140 			   struct vxlan_vni_node *vninode,
141 			   int type, unsigned int len);
142 
143 void vxlan_vs_add_vnigrp(struct vxlan_dev *vxlan,
144 			 struct vxlan_sock *vs,
145 			 bool ipv6);
146 void vxlan_vs_del_vnigrp(struct vxlan_dev *vxlan);
147 int vxlan_vnilist_update_group(struct vxlan_dev *vxlan,
148 			       union vxlan_addr *old_remote_ip,
149 			       union vxlan_addr *new_remote_ip,
150 			       struct netlink_ext_ack *extack);
151 
152 
153 /* vxlan_multicast.c */
154 int vxlan_multicast_join(struct vxlan_dev *vxlan);
155 int vxlan_multicast_leave(struct vxlan_dev *vxlan);
156 bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev,
157 		      __be32 vni, union vxlan_addr *rip, int rifindex);
158 int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
159 		    int rifindex);
160 int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
161 		     int rifindex);
162 #endif
163