GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / net / vxlan / vxlan_private.h
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 static 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
104 static 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
113 static 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
123 static inline
124 bool 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
129 static 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
143 static 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
149 static 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
156 static 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
164 static inline struct vxlan_vni_node *
165 vxlan_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 */
178 int 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);
184 int __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);
188 u32 eth_vni_hash(const unsigned char *addr, __be32 vni);
189 u32 fdb_head_index(struct vxlan_dev *vxlan, const u8 *mac, __be32 vni);
190 int 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);
196 void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
197                     __be32 default_vni, struct vxlan_rdst *rdst, bool did_rsc);
198 int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan,
199                      struct vxlan_config *conf, __be32 vni);
200
201 /* vxlan_vnifilter.c */
202 int vxlan_vnigroup_init(struct vxlan_dev *vxlan);
203 void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan);
204
205 void vxlan_vnifilter_init(void);
206 void vxlan_vnifilter_uninit(void);
207 void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni,
208                            struct vxlan_vni_node *vninode,
209                            int type, unsigned int len);
210
211 void vxlan_vs_add_vnigrp(struct vxlan_dev *vxlan,
212                          struct vxlan_sock *vs,
213                          bool ipv6);
214 void vxlan_vs_del_vnigrp(struct vxlan_dev *vxlan);
215 int 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 */
222 int vxlan_multicast_join(struct vxlan_dev *vxlan);
223 int vxlan_multicast_leave(struct vxlan_dev *vxlan);
224 bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev,
225                       __be32 vni, union vxlan_addr *rip, int rifindex);
226 int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
227                     int rifindex);
228 int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
229                      int rifindex);
230
231 /* vxlan_mdb.c */
232 int vxlan_mdb_dump(struct net_device *dev, struct sk_buff *skb,
233                    struct netlink_callback *cb);
234 int vxlan_mdb_add(struct net_device *dev, struct nlattr *tb[], u16 nlmsg_flags,
235                   struct netlink_ext_ack *extack);
236 int vxlan_mdb_del(struct net_device *dev, struct nlattr *tb[],
237                   struct netlink_ext_ack *extack);
238 int vxlan_mdb_del_bulk(struct net_device *dev, struct nlattr *tb[],
239                        struct netlink_ext_ack *extack);
240 int vxlan_mdb_get(struct net_device *dev, struct nlattr *tb[], u32 portid,
241                   u32 seq, struct netlink_ext_ack *extack);
242 struct vxlan_mdb_entry *vxlan_mdb_entry_skb_get(struct vxlan_dev *vxlan,
243                                                 struct sk_buff *skb,
244                                                 __be32 src_vni);
245 netdev_tx_t vxlan_mdb_xmit(struct vxlan_dev *vxlan,
246                            const struct vxlan_mdb_entry *mdb_entry,
247                            struct sk_buff *skb);
248 int vxlan_mdb_init(struct vxlan_dev *vxlan);
249 void vxlan_mdb_fini(struct vxlan_dev *vxlan);
250 #endif