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
12extern unsigned int vxlan_net_id;
13extern const u8 all_zeros_mac[ETH_ALEN + 2];
14extern 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 */
20struct 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 */
28struct 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 */
46static 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 */
52static 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 */
62static 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
69static 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)
77static inline
78bool 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
88static inline int vxlan_nla_get_addr(union vxlan_addr *ip,
89				     const struct nlattr *nla)
90{
91	if (nla_len(nla) >= sizeof(struct in6_addr)) {
92		ip->sin6.sin6_addr = nla_get_in6_addr(nla);
93		ip->sa.sa_family = AF_INET6;
94		return 0;
95	} else if (nla_len(nla) >= sizeof(__be32)) {
96		ip->sin.sin_addr.s_addr = nla_get_in_addr(nla);
97		ip->sa.sa_family = AF_INET;
98		return 0;
99	} else {
100		return -EAFNOSUPPORT;
101	}
102}
103
104static inline int vxlan_nla_put_addr(struct sk_buff *skb, int attr,
105				     const union vxlan_addr *ip)
106{
107	if (ip->sa.sa_family == AF_INET6)
108		return nla_put_in6_addr(skb, attr, &ip->sin6.sin6_addr);
109	else
110		return nla_put_in_addr(skb, attr, ip->sin.sin_addr.s_addr);
111}
112
113static inline bool vxlan_addr_is_multicast(const union vxlan_addr *ip)
114{
115	if (ip->sa.sa_family == AF_INET6)
116		return ipv6_addr_is_multicast(&ip->sin6.sin6_addr);
117	else
118		return ipv4_is_multicast(ip->sin.sin_addr.s_addr);
119}
120
121#else /* !CONFIG_IPV6 */
122
123static inline
124bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
125{
126	return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
127}
128
129static inline int vxlan_nla_get_addr(union vxlan_addr *ip,
130				     const struct nlattr *nla)
131{
132	if (nla_len(nla) >= sizeof(struct in6_addr)) {
133		return -EAFNOSUPPORT;
134	} else if (nla_len(nla) >= sizeof(__be32)) {
135		ip->sin.sin_addr.s_addr = nla_get_in_addr(nla);
136		ip->sa.sa_family = AF_INET;
137		return 0;
138	} else {
139		return -EAFNOSUPPORT;
140	}
141}
142
143static inline int vxlan_nla_put_addr(struct sk_buff *skb, int attr,
144				     const union vxlan_addr *ip)
145{
146	return nla_put_in_addr(skb, attr, ip->sin.sin_addr.s_addr);
147}
148
149static inline bool vxlan_addr_is_multicast(const union vxlan_addr *ip)
150{
151	return ipv4_is_multicast(ip->sin.sin_addr.s_addr);
152}
153
154#endif
155
156static inline size_t vxlan_addr_size(const union vxlan_addr *ip)
157{
158	if (ip->sa.sa_family == AF_INET6)
159		return sizeof(struct in6_addr);
160	else
161		return sizeof(__be32);
162}
163
164static inline struct vxlan_vni_node *
165vxlan_vnifilter_lookup(struct vxlan_dev *vxlan, __be32 vni)
166{
167	struct vxlan_vni_group *vg;
168
169	vg = rcu_dereference_rtnl(vxlan->vnigrp);
170	if (!vg)
171		return NULL;
172
173	return rhashtable_lookup_fast(&vg->vni_hash, &vni,
174				      vxlan_vni_rht_params);
175}
176
177/* vxlan_core.c */
178int vxlan_fdb_create(struct vxlan_dev *vxlan,
179		     const u8 *mac, union vxlan_addr *ip,
180		     __u16 state, __be16 port, __be32 src_vni,
181		     __be32 vni, __u32 ifindex, __u16 ndm_flags,
182		     u32 nhid, struct vxlan_fdb **fdb,
183		     struct netlink_ext_ack *extack);
184int __vxlan_fdb_delete(struct vxlan_dev *vxlan,
185		       const unsigned char *addr, union vxlan_addr ip,
186		       __be16 port, __be32 src_vni, __be32 vni,
187		       u32 ifindex, bool swdev_notify);
188u32 eth_vni_hash(const unsigned char *addr, __be32 vni);
189u32 fdb_head_index(struct vxlan_dev *vxlan, const u8 *mac, __be32 vni);
190int vxlan_fdb_update(struct vxlan_dev *vxlan,
191		     const u8 *mac, union vxlan_addr *ip,
192		     __u16 state, __u16 flags,
193		     __be16 port, __be32 src_vni, __be32 vni,
194		     __u32 ifindex, __u16 ndm_flags, u32 nhid,
195		     bool swdev_notify, struct netlink_ext_ack *extack);
196void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
197		    __be32 default_vni, struct vxlan_rdst *rdst, bool did_rsc);
198int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan,
199		     struct vxlan_config *conf, __be32 vni);
200
201/* vxlan_vnifilter.c */
202int vxlan_vnigroup_init(struct vxlan_dev *vxlan);
203void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan);
204
205void vxlan_vnifilter_init(void);
206void vxlan_vnifilter_uninit(void);
207void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni,
208			   struct vxlan_vni_node *vninode,
209			   int type, unsigned int len);
210
211void vxlan_vs_add_vnigrp(struct vxlan_dev *vxlan,
212			 struct vxlan_sock *vs,
213			 bool ipv6);
214void vxlan_vs_del_vnigrp(struct vxlan_dev *vxlan);
215int vxlan_vnilist_update_group(struct vxlan_dev *vxlan,
216			       union vxlan_addr *old_remote_ip,
217			       union vxlan_addr *new_remote_ip,
218			       struct netlink_ext_ack *extack);
219
220
221/* vxlan_multicast.c */
222int vxlan_multicast_join(struct vxlan_dev *vxlan);
223int vxlan_multicast_leave(struct vxlan_dev *vxlan);
224bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev,
225		      __be32 vni, union vxlan_addr *rip, int rifindex);
226int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
227		    int rifindex);
228int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
229		     int rifindex);
230
231/* vxlan_mdb.c */
232int vxlan_mdb_dump(struct net_device *dev, struct sk_buff *skb,
233		   struct netlink_callback *cb);
234int vxlan_mdb_add(struct net_device *dev, struct nlattr *tb[], u16 nlmsg_flags,
235		  struct netlink_ext_ack *extack);
236int vxlan_mdb_del(struct net_device *dev, struct nlattr *tb[],
237		  struct netlink_ext_ack *extack);
238int vxlan_mdb_del_bulk(struct net_device *dev, struct nlattr *tb[],
239		       struct netlink_ext_ack *extack);
240int vxlan_mdb_get(struct net_device *dev, struct nlattr *tb[], u32 portid,
241		  u32 seq, struct netlink_ext_ack *extack);
242struct vxlan_mdb_entry *vxlan_mdb_entry_skb_get(struct vxlan_dev *vxlan,
243						struct sk_buff *skb,
244						__be32 src_vni);
245netdev_tx_t vxlan_mdb_xmit(struct vxlan_dev *vxlan,
246			   const struct vxlan_mdb_entry *mdb_entry,
247			   struct sk_buff *skb);
248int vxlan_mdb_init(struct vxlan_dev *vxlan);
249void vxlan_mdb_fini(struct vxlan_dev *vxlan);
250#endif
251