]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/if_vxlan.c
Implement pci_enable_msi() and pci_disable_msi() in the LinuxKPI.
[FreeBSD/FreeBSD.git] / sys / net / if_vxlan.c
1 /*-
2  * Copyright (c) 2014, Bryan Venteicher <bryanv@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice unmodified, this list of conditions, and the following
10  *    disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "opt_inet.h"
28 #include "opt_inet6.h"
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/eventhandler.h>
35 #include <sys/kernel.h>
36 #include <sys/lock.h>
37 #include <sys/hash.h>
38 #include <sys/malloc.h>
39 #include <sys/mbuf.h>
40 #include <sys/module.h>
41 #include <sys/refcount.h>
42 #include <sys/rmlock.h>
43 #include <sys/priv.h>
44 #include <sys/proc.h>
45 #include <sys/queue.h>
46 #include <sys/sbuf.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/sockio.h>
50 #include <sys/sysctl.h>
51 #include <sys/systm.h>
52
53 #include <net/bpf.h>
54 #include <net/ethernet.h>
55 #include <net/if.h>
56 #include <net/if_var.h>
57 #include <net/if_clone.h>
58 #include <net/if_dl.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
61 #include <net/if_vxlan.h>
62 #include <net/netisr.h>
63
64 #include <netinet/in.h>
65 #include <netinet/in_systm.h>
66 #include <netinet/in_var.h>
67 #include <netinet/in_pcb.h>
68 #include <netinet/ip.h>
69 #include <netinet/ip6.h>
70 #include <netinet/ip_var.h>
71 #include <netinet/udp.h>
72 #include <netinet/udp_var.h>
73
74 #include <netinet6/ip6_var.h>
75 #include <netinet6/scope6_var.h>
76
77 struct vxlan_softc;
78 LIST_HEAD(vxlan_softc_head, vxlan_softc);
79
80 struct vxlan_socket_mc_info {
81         union vxlan_sockaddr             vxlsomc_saddr;
82         union vxlan_sockaddr             vxlsomc_gaddr;
83         int                              vxlsomc_ifidx;
84         int                              vxlsomc_users;
85 };
86
87 /*
88  * The maximum MTU of encapsulated ethernet frame within IPv4/UDP packet.
89  */
90 #define VXLAN_MAX_MTU   (IP_MAXPACKET - \
91                 60 /* Maximum IPv4 header len */ - \
92                 sizeof(struct udphdr) - \
93                 sizeof(struct vxlan_header) - \
94                 ETHER_HDR_LEN - ETHER_CRC_LEN - ETHER_VLAN_ENCAP_LEN)
95
96 #define VXLAN_SO_MC_MAX_GROUPS          32
97
98 #define VXLAN_SO_VNI_HASH_SHIFT         6
99 #define VXLAN_SO_VNI_HASH_SIZE          (1 << VXLAN_SO_VNI_HASH_SHIFT)
100 #define VXLAN_SO_VNI_HASH(_vni)         ((_vni) % VXLAN_SO_VNI_HASH_SIZE)
101
102 struct vxlan_socket {
103         struct socket                   *vxlso_sock;
104         struct rmlock                    vxlso_lock;
105         u_int                            vxlso_refcnt;
106         union vxlan_sockaddr             vxlso_laddr;
107         LIST_ENTRY(vxlan_socket)         vxlso_entry;
108         struct vxlan_softc_head          vxlso_vni_hash[VXLAN_SO_VNI_HASH_SIZE];
109         struct vxlan_socket_mc_info      vxlso_mc[VXLAN_SO_MC_MAX_GROUPS];
110 };
111
112 #define VXLAN_SO_RLOCK(_vso, _p)        rm_rlock(&(_vso)->vxlso_lock, (_p))
113 #define VXLAN_SO_RUNLOCK(_vso, _p)      rm_runlock(&(_vso)->vxlso_lock, (_p))
114 #define VXLAN_SO_WLOCK(_vso)            rm_wlock(&(_vso)->vxlso_lock)
115 #define VXLAN_SO_WUNLOCK(_vso)          rm_wunlock(&(_vso)->vxlso_lock)
116 #define VXLAN_SO_LOCK_ASSERT(_vso) \
117     rm_assert(&(_vso)->vxlso_lock, RA_LOCKED)
118 #define VXLAN_SO_LOCK_WASSERT(_vso) \
119     rm_assert(&(_vso)->vxlso_lock, RA_WLOCKED)
120
121 #define VXLAN_SO_ACQUIRE(_vso)          refcount_acquire(&(_vso)->vxlso_refcnt)
122 #define VXLAN_SO_RELEASE(_vso)          refcount_release(&(_vso)->vxlso_refcnt)
123
124 struct vxlan_ftable_entry {
125         LIST_ENTRY(vxlan_ftable_entry)   vxlfe_hash;
126         uint16_t                         vxlfe_flags;
127         uint8_t                          vxlfe_mac[ETHER_ADDR_LEN];
128         union vxlan_sockaddr             vxlfe_raddr;
129         time_t                           vxlfe_expire;
130 };
131
132 #define VXLAN_FE_FLAG_DYNAMIC           0x01
133 #define VXLAN_FE_FLAG_STATIC            0x02
134
135 #define VXLAN_FE_IS_DYNAMIC(_fe) \
136     ((_fe)->vxlfe_flags & VXLAN_FE_FLAG_DYNAMIC)
137
138 #define VXLAN_SC_FTABLE_SHIFT           9
139 #define VXLAN_SC_FTABLE_SIZE            (1 << VXLAN_SC_FTABLE_SHIFT)
140 #define VXLAN_SC_FTABLE_MASK            (VXLAN_SC_FTABLE_SIZE - 1)
141 #define VXLAN_SC_FTABLE_HASH(_sc, _mac) \
142     (vxlan_mac_hash(_sc, _mac) % VXLAN_SC_FTABLE_SIZE)
143
144 LIST_HEAD(vxlan_ftable_head, vxlan_ftable_entry);
145
146 struct vxlan_statistics {
147         uint32_t        ftable_nospace;
148         uint32_t        ftable_lock_upgrade_failed;
149 };
150
151 struct vxlan_softc {
152         struct ifnet                    *vxl_ifp;
153         struct vxlan_socket             *vxl_sock;
154         uint32_t                         vxl_vni;
155         union vxlan_sockaddr             vxl_src_addr;
156         union vxlan_sockaddr             vxl_dst_addr;
157         uint32_t                         vxl_flags;
158 #define VXLAN_FLAG_INIT         0x0001
159 #define VXLAN_FLAG_TEARDOWN     0x0002
160 #define VXLAN_FLAG_LEARN        0x0004
161
162         uint32_t                         vxl_port_hash_key;
163         uint16_t                         vxl_min_port;
164         uint16_t                         vxl_max_port;
165         uint8_t                          vxl_ttl;
166
167         /* Lookup table from MAC address to forwarding entry. */
168         uint32_t                         vxl_ftable_cnt;
169         uint32_t                         vxl_ftable_max;
170         uint32_t                         vxl_ftable_timeout;
171         uint32_t                         vxl_ftable_hash_key;
172         struct vxlan_ftable_head        *vxl_ftable;
173
174         /* Derived from vxl_dst_addr. */
175         struct vxlan_ftable_entry        vxl_default_fe;
176
177         struct ip_moptions              *vxl_im4o;
178         struct ip6_moptions             *vxl_im6o;
179
180         struct rmlock                    vxl_lock;
181         volatile u_int                   vxl_refcnt;
182
183         int                              vxl_unit;
184         int                              vxl_vso_mc_index;
185         struct vxlan_statistics          vxl_stats;
186         struct sysctl_oid               *vxl_sysctl_node;
187         struct sysctl_ctx_list           vxl_sysctl_ctx;
188         struct callout                   vxl_callout;
189         struct ether_addr                vxl_hwaddr;
190         int                              vxl_mc_ifindex;
191         struct ifnet                    *vxl_mc_ifp;
192         struct ifmedia                   vxl_media;
193         char                             vxl_mc_ifname[IFNAMSIZ];
194         LIST_ENTRY(vxlan_softc)          vxl_entry;
195         LIST_ENTRY(vxlan_softc)          vxl_ifdetach_list;
196 };
197
198 #define VXLAN_RLOCK(_sc, _p)    rm_rlock(&(_sc)->vxl_lock, (_p))
199 #define VXLAN_RUNLOCK(_sc, _p)  rm_runlock(&(_sc)->vxl_lock, (_p))
200 #define VXLAN_WLOCK(_sc)        rm_wlock(&(_sc)->vxl_lock)
201 #define VXLAN_WUNLOCK(_sc)      rm_wunlock(&(_sc)->vxl_lock)
202 #define VXLAN_LOCK_WOWNED(_sc)  rm_wowned(&(_sc)->vxl_lock)
203 #define VXLAN_LOCK_ASSERT(_sc)  rm_assert(&(_sc)->vxl_lock, RA_LOCKED)
204 #define VXLAN_LOCK_WASSERT(_sc) rm_assert(&(_sc)->vxl_lock, RA_WLOCKED)
205 #define VXLAN_UNLOCK(_sc, _p) do {              \
206     if (VXLAN_LOCK_WOWNED(_sc))                 \
207         VXLAN_WUNLOCK(_sc);                     \
208     else                                        \
209         VXLAN_RUNLOCK(_sc, _p);                 \
210 } while (0)
211
212 #define VXLAN_ACQUIRE(_sc)      refcount_acquire(&(_sc)->vxl_refcnt)
213 #define VXLAN_RELEASE(_sc)      refcount_release(&(_sc)->vxl_refcnt)
214
215 #define satoconstsin(sa)        ((const struct sockaddr_in *)(sa))
216 #define satoconstsin6(sa)       ((const struct sockaddr_in6 *)(sa))
217
218 struct vxlanudphdr {
219         struct udphdr           vxlh_udp;
220         struct vxlan_header     vxlh_hdr;
221 } __packed;
222
223 static int      vxlan_ftable_addr_cmp(const uint8_t *, const uint8_t *);
224 static void     vxlan_ftable_init(struct vxlan_softc *);
225 static void     vxlan_ftable_fini(struct vxlan_softc *);
226 static void     vxlan_ftable_flush(struct vxlan_softc *, int);
227 static void     vxlan_ftable_expire(struct vxlan_softc *);
228 static int      vxlan_ftable_update_locked(struct vxlan_softc *,
229                     const union vxlan_sockaddr *, const uint8_t *,
230                     struct rm_priotracker *);
231 static int      vxlan_ftable_learn(struct vxlan_softc *,
232                     const struct sockaddr *, const uint8_t *);
233 static int      vxlan_ftable_sysctl_dump(SYSCTL_HANDLER_ARGS);
234
235 static struct vxlan_ftable_entry *
236                 vxlan_ftable_entry_alloc(void);
237 static void     vxlan_ftable_entry_free(struct vxlan_ftable_entry *);
238 static void     vxlan_ftable_entry_init(struct vxlan_softc *,
239                     struct vxlan_ftable_entry *, const uint8_t *,
240                     const struct sockaddr *, uint32_t);
241 static void     vxlan_ftable_entry_destroy(struct vxlan_softc *,
242                     struct vxlan_ftable_entry *);
243 static int      vxlan_ftable_entry_insert(struct vxlan_softc *,
244                     struct vxlan_ftable_entry *);
245 static struct vxlan_ftable_entry *
246                 vxlan_ftable_entry_lookup(struct vxlan_softc *,
247                     const uint8_t *);
248 static void     vxlan_ftable_entry_dump(struct vxlan_ftable_entry *,
249                     struct sbuf *);
250
251 static struct vxlan_socket *
252                 vxlan_socket_alloc(const union vxlan_sockaddr *);
253 static void     vxlan_socket_destroy(struct vxlan_socket *);
254 static void     vxlan_socket_release(struct vxlan_socket *);
255 static struct vxlan_socket *
256                 vxlan_socket_lookup(union vxlan_sockaddr *vxlsa);
257 static void     vxlan_socket_insert(struct vxlan_socket *);
258 static int      vxlan_socket_init(struct vxlan_socket *, struct ifnet *);
259 static int      vxlan_socket_bind(struct vxlan_socket *, struct ifnet *);
260 static int      vxlan_socket_create(struct ifnet *, int,
261                     const union vxlan_sockaddr *, struct vxlan_socket **);
262 static void     vxlan_socket_ifdetach(struct vxlan_socket *,
263                     struct ifnet *, struct vxlan_softc_head *);
264
265 static struct vxlan_socket *
266                 vxlan_socket_mc_lookup(const union vxlan_sockaddr *);
267 static int      vxlan_sockaddr_mc_info_match(
268                     const struct vxlan_socket_mc_info *,
269                     const union vxlan_sockaddr *,
270                     const union vxlan_sockaddr *, int);
271 static int      vxlan_socket_mc_join_group(struct vxlan_socket *,
272                     const union vxlan_sockaddr *, const union vxlan_sockaddr *,
273                     int *, union vxlan_sockaddr *);
274 static int      vxlan_socket_mc_leave_group(struct vxlan_socket *,
275                     const union vxlan_sockaddr *,
276                     const union vxlan_sockaddr *, int);
277 static int      vxlan_socket_mc_add_group(struct vxlan_socket *,
278                     const union vxlan_sockaddr *, const union vxlan_sockaddr *,
279                     int, int *);
280 static void     vxlan_socket_mc_release_group_by_idx(struct vxlan_socket *,
281                     int);
282
283 static struct vxlan_softc *
284                 vxlan_socket_lookup_softc_locked(struct vxlan_socket *,
285                     uint32_t);
286 static struct vxlan_softc *
287                 vxlan_socket_lookup_softc(struct vxlan_socket *, uint32_t);
288 static int      vxlan_socket_insert_softc(struct vxlan_socket *,
289                     struct vxlan_softc *);
290 static void     vxlan_socket_remove_softc(struct vxlan_socket *,
291                     struct vxlan_softc *);
292
293 static struct ifnet *
294                 vxlan_multicast_if_ref(struct vxlan_softc *, int);
295 static void     vxlan_free_multicast(struct vxlan_softc *);
296 static int      vxlan_setup_multicast_interface(struct vxlan_softc *);
297
298 static int      vxlan_setup_multicast(struct vxlan_softc *);
299 static int      vxlan_setup_socket(struct vxlan_softc *);
300 static void     vxlan_setup_interface(struct vxlan_softc *);
301 static int      vxlan_valid_init_config(struct vxlan_softc *);
302 static void     vxlan_init_wait(struct vxlan_softc *);
303 static void     vxlan_init_complete(struct vxlan_softc *);
304 static void     vxlan_init(void *);
305 static void     vxlan_release(struct vxlan_softc *);
306 static void     vxlan_teardown_wait(struct vxlan_softc *);
307 static void     vxlan_teardown_complete(struct vxlan_softc *);
308 static void     vxlan_teardown_locked(struct vxlan_softc *);
309 static void     vxlan_teardown(struct vxlan_softc *);
310 static void     vxlan_ifdetach(struct vxlan_softc *, struct ifnet *,
311                     struct vxlan_softc_head *);
312 static void     vxlan_timer(void *);
313
314 static int      vxlan_ctrl_get_config(struct vxlan_softc *, void *);
315 static int      vxlan_ctrl_set_vni(struct vxlan_softc *, void *);
316 static int      vxlan_ctrl_set_local_addr(struct vxlan_softc *, void *);
317 static int      vxlan_ctrl_set_remote_addr(struct vxlan_softc *, void *);
318 static int      vxlan_ctrl_set_local_port(struct vxlan_softc *, void *);
319 static int      vxlan_ctrl_set_remote_port(struct vxlan_softc *, void *);
320 static int      vxlan_ctrl_set_port_range(struct vxlan_softc *, void *);
321 static int      vxlan_ctrl_set_ftable_timeout(struct vxlan_softc *, void *);
322 static int      vxlan_ctrl_set_ftable_max(struct vxlan_softc *, void *);
323 static int      vxlan_ctrl_set_multicast_if(struct vxlan_softc * , void *);
324 static int      vxlan_ctrl_set_ttl(struct vxlan_softc *, void *);
325 static int      vxlan_ctrl_set_learn(struct vxlan_softc *, void *);
326 static int      vxlan_ctrl_ftable_entry_add(struct vxlan_softc *, void *);
327 static int      vxlan_ctrl_ftable_entry_rem(struct vxlan_softc *, void *);
328 static int      vxlan_ctrl_flush(struct vxlan_softc *, void *);
329 static int      vxlan_ioctl_drvspec(struct vxlan_softc *,
330                     struct ifdrv *, int);
331 static int      vxlan_ioctl_ifflags(struct vxlan_softc *);
332 static int      vxlan_ioctl(struct ifnet *, u_long, caddr_t);
333
334 #if defined(INET) || defined(INET6)
335 static uint16_t vxlan_pick_source_port(struct vxlan_softc *, struct mbuf *);
336 static void     vxlan_encap_header(struct vxlan_softc *, struct mbuf *,
337                     int, uint16_t, uint16_t);
338 #endif
339 static int      vxlan_encap4(struct vxlan_softc *,
340                     const union vxlan_sockaddr *, struct mbuf *);
341 static int      vxlan_encap6(struct vxlan_softc *,
342                     const union vxlan_sockaddr *, struct mbuf *);
343 static int      vxlan_transmit(struct ifnet *, struct mbuf *);
344 static void     vxlan_qflush(struct ifnet *);
345 static void     vxlan_rcv_udp_packet(struct mbuf *, int, struct inpcb *,
346                     const struct sockaddr *, void *);
347 static int      vxlan_input(struct vxlan_socket *, uint32_t, struct mbuf **,
348                     const struct sockaddr *);
349
350 static void     vxlan_set_default_config(struct vxlan_softc *);
351 static int      vxlan_set_user_config(struct vxlan_softc *,
352                      struct ifvxlanparam *);
353 static int      vxlan_clone_create(struct if_clone *, int, caddr_t);
354 static void     vxlan_clone_destroy(struct ifnet *);
355
356 static uint32_t vxlan_mac_hash(struct vxlan_softc *, const uint8_t *);
357 static int      vxlan_media_change(struct ifnet *);
358 static void     vxlan_media_status(struct ifnet *, struct ifmediareq *);
359
360 static int      vxlan_sockaddr_cmp(const union vxlan_sockaddr *,
361                     const struct sockaddr *);
362 static void     vxlan_sockaddr_copy(union vxlan_sockaddr *,
363                     const struct sockaddr *);
364 static int      vxlan_sockaddr_in_equal(const union vxlan_sockaddr *,
365                     const struct sockaddr *);
366 static void     vxlan_sockaddr_in_copy(union vxlan_sockaddr *,
367                     const struct sockaddr *);
368 static int      vxlan_sockaddr_supported(const union vxlan_sockaddr *, int);
369 static int      vxlan_sockaddr_in_any(const union vxlan_sockaddr *);
370 static int      vxlan_sockaddr_in_multicast(const union vxlan_sockaddr *);
371 static int      vxlan_sockaddr_in6_embedscope(union vxlan_sockaddr *);
372
373 static int      vxlan_can_change_config(struct vxlan_softc *);
374 static int      vxlan_check_vni(uint32_t);
375 static int      vxlan_check_ttl(int);
376 static int      vxlan_check_ftable_timeout(uint32_t);
377 static int      vxlan_check_ftable_max(uint32_t);
378
379 static void     vxlan_sysctl_setup(struct vxlan_softc *);
380 static void     vxlan_sysctl_destroy(struct vxlan_softc *);
381 static int      vxlan_tunable_int(struct vxlan_softc *, const char *, int);
382
383 static void     vxlan_ifdetach_event(void *, struct ifnet *);
384 static void     vxlan_load(void);
385 static void     vxlan_unload(void);
386 static int      vxlan_modevent(module_t, int, void *);
387
388 static const char vxlan_name[] = "vxlan";
389 static MALLOC_DEFINE(M_VXLAN, vxlan_name,
390     "Virtual eXtensible LAN Interface");
391 static struct if_clone *vxlan_cloner;
392
393 static struct mtx vxlan_list_mtx;
394 #define VXLAN_LIST_LOCK()       mtx_lock(&vxlan_list_mtx)
395 #define VXLAN_LIST_UNLOCK()     mtx_unlock(&vxlan_list_mtx)
396
397 static LIST_HEAD(, vxlan_socket) vxlan_socket_list;
398
399 static eventhandler_tag vxlan_ifdetach_event_tag;
400
401 SYSCTL_DECL(_net_link);
402 SYSCTL_NODE(_net_link, OID_AUTO, vxlan, CTLFLAG_RW, 0,
403     "Virtual eXtensible Local Area Network");
404
405 static int vxlan_legacy_port = 0;
406 TUNABLE_INT("net.link.vxlan.legacy_port", &vxlan_legacy_port);
407 static int vxlan_reuse_port = 0;
408 TUNABLE_INT("net.link.vxlan.reuse_port", &vxlan_reuse_port);
409
410 /* Default maximum number of addresses in the forwarding table. */
411 #ifndef VXLAN_FTABLE_MAX
412 #define VXLAN_FTABLE_MAX        2000
413 #endif
414
415 /* Timeout (in seconds) of addresses learned in the forwarding table. */
416 #ifndef VXLAN_FTABLE_TIMEOUT
417 #define VXLAN_FTABLE_TIMEOUT    (20 * 60)
418 #endif
419
420 /*
421  * Maximum timeout (in seconds) of addresses learned in the forwarding
422  * table.
423  */
424 #ifndef VXLAN_FTABLE_MAX_TIMEOUT
425 #define VXLAN_FTABLE_MAX_TIMEOUT        (60 * 60 * 24)
426 #endif
427
428 /* Number of seconds between pruning attempts of the forwarding table. */
429 #ifndef VXLAN_FTABLE_PRUNE
430 #define VXLAN_FTABLE_PRUNE      (5 * 60)
431 #endif
432
433 static int vxlan_ftable_prune_period = VXLAN_FTABLE_PRUNE;
434
435 struct vxlan_control {
436         int     (*vxlc_func)(struct vxlan_softc *, void *);
437         int     vxlc_argsize;
438         int     vxlc_flags;
439 #define VXLAN_CTRL_FLAG_COPYIN  0x01
440 #define VXLAN_CTRL_FLAG_COPYOUT 0x02
441 #define VXLAN_CTRL_FLAG_SUSER   0x04
442 };
443
444 static const struct vxlan_control vxlan_control_table[] = {
445         [VXLAN_CMD_GET_CONFIG] =
446             {   vxlan_ctrl_get_config, sizeof(struct ifvxlancfg),
447                 VXLAN_CTRL_FLAG_COPYOUT
448             },
449
450         [VXLAN_CMD_SET_VNI] =
451             {   vxlan_ctrl_set_vni, sizeof(struct ifvxlancmd),
452                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
453             },
454
455         [VXLAN_CMD_SET_LOCAL_ADDR] =
456             {   vxlan_ctrl_set_local_addr, sizeof(struct ifvxlancmd),
457                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
458             },
459
460         [VXLAN_CMD_SET_REMOTE_ADDR] =
461             {   vxlan_ctrl_set_remote_addr, sizeof(struct ifvxlancmd),
462                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
463             },
464
465         [VXLAN_CMD_SET_LOCAL_PORT] =
466             {   vxlan_ctrl_set_local_port, sizeof(struct ifvxlancmd),
467                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
468             },
469
470         [VXLAN_CMD_SET_REMOTE_PORT] =
471             {   vxlan_ctrl_set_remote_port, sizeof(struct ifvxlancmd),
472                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
473             },
474
475         [VXLAN_CMD_SET_PORT_RANGE] =
476             {   vxlan_ctrl_set_port_range, sizeof(struct ifvxlancmd),
477                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
478             },
479
480         [VXLAN_CMD_SET_FTABLE_TIMEOUT] =
481             {   vxlan_ctrl_set_ftable_timeout, sizeof(struct ifvxlancmd),
482                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
483             },
484
485         [VXLAN_CMD_SET_FTABLE_MAX] =
486             {   vxlan_ctrl_set_ftable_max, sizeof(struct ifvxlancmd),
487                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
488             },
489
490         [VXLAN_CMD_SET_MULTICAST_IF] =
491             {   vxlan_ctrl_set_multicast_if, sizeof(struct ifvxlancmd),
492                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
493             },
494
495         [VXLAN_CMD_SET_TTL] =
496             {   vxlan_ctrl_set_ttl, sizeof(struct ifvxlancmd),
497                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
498             },
499
500         [VXLAN_CMD_SET_LEARN] =
501             {   vxlan_ctrl_set_learn, sizeof(struct ifvxlancmd),
502                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
503             },
504
505         [VXLAN_CMD_FTABLE_ENTRY_ADD] =
506             {   vxlan_ctrl_ftable_entry_add, sizeof(struct ifvxlancmd),
507                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
508             },
509
510         [VXLAN_CMD_FTABLE_ENTRY_REM] =
511             {   vxlan_ctrl_ftable_entry_rem, sizeof(struct ifvxlancmd),
512                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
513             },
514
515         [VXLAN_CMD_FLUSH] =
516             {   vxlan_ctrl_flush, sizeof(struct ifvxlancmd),
517                 VXLAN_CTRL_FLAG_COPYIN | VXLAN_CTRL_FLAG_SUSER,
518             },
519 };
520
521 static const int vxlan_control_table_size = nitems(vxlan_control_table);
522
523 static int
524 vxlan_ftable_addr_cmp(const uint8_t *a, const uint8_t *b)
525 {
526         int i, d;
527
528         for (i = 0, d = 0; i < ETHER_ADDR_LEN && d == 0; i++)
529                 d = ((int)a[i]) - ((int)b[i]);
530
531         return (d);
532 }
533
534 static void
535 vxlan_ftable_init(struct vxlan_softc *sc)
536 {
537         int i;
538
539         sc->vxl_ftable = malloc(sizeof(struct vxlan_ftable_head) *
540             VXLAN_SC_FTABLE_SIZE, M_VXLAN, M_ZERO | M_WAITOK);
541
542         for (i = 0; i < VXLAN_SC_FTABLE_SIZE; i++)
543                 LIST_INIT(&sc->vxl_ftable[i]);
544         sc->vxl_ftable_hash_key = arc4random();
545 }
546
547 static void
548 vxlan_ftable_fini(struct vxlan_softc *sc)
549 {
550         int i;
551
552         for (i = 0; i < VXLAN_SC_FTABLE_SIZE; i++) {
553                 KASSERT(LIST_EMPTY(&sc->vxl_ftable[i]),
554                     ("%s: vxlan %p ftable[%d] not empty", __func__, sc, i));
555         }
556         MPASS(sc->vxl_ftable_cnt == 0);
557
558         free(sc->vxl_ftable, M_VXLAN);
559         sc->vxl_ftable = NULL;
560 }
561
562 static void
563 vxlan_ftable_flush(struct vxlan_softc *sc, int all)
564 {
565         struct vxlan_ftable_entry *fe, *tfe;
566         int i;
567
568         for (i = 0; i < VXLAN_SC_FTABLE_SIZE; i++) {
569                 LIST_FOREACH_SAFE(fe, &sc->vxl_ftable[i], vxlfe_hash, tfe) {
570                         if (all || VXLAN_FE_IS_DYNAMIC(fe))
571                                 vxlan_ftable_entry_destroy(sc, fe);
572                 }
573         }
574 }
575
576 static void
577 vxlan_ftable_expire(struct vxlan_softc *sc)
578 {
579         struct vxlan_ftable_entry *fe, *tfe;
580         int i;
581
582         VXLAN_LOCK_WASSERT(sc);
583
584         for (i = 0; i < VXLAN_SC_FTABLE_SIZE; i++) {
585                 LIST_FOREACH_SAFE(fe, &sc->vxl_ftable[i], vxlfe_hash, tfe) {
586                         if (VXLAN_FE_IS_DYNAMIC(fe) &&
587                             time_uptime >= fe->vxlfe_expire)
588                                 vxlan_ftable_entry_destroy(sc, fe);
589                 }
590         }
591 }
592
593 static int
594 vxlan_ftable_update_locked(struct vxlan_softc *sc,
595     const union vxlan_sockaddr *vxlsa, const uint8_t *mac,
596     struct rm_priotracker *tracker)
597 {
598         struct vxlan_ftable_entry *fe;
599         int error __unused;
600
601         VXLAN_LOCK_ASSERT(sc);
602
603 again:
604         /*
605          * A forwarding entry for this MAC address might already exist. If
606          * so, update it, otherwise create a new one. We may have to upgrade
607          * the lock if we have to change or create an entry.
608          */
609         fe = vxlan_ftable_entry_lookup(sc, mac);
610         if (fe != NULL) {
611                 fe->vxlfe_expire = time_uptime + sc->vxl_ftable_timeout;
612
613                 if (!VXLAN_FE_IS_DYNAMIC(fe) ||
614                     vxlan_sockaddr_in_equal(&fe->vxlfe_raddr, &vxlsa->sa))
615                         return (0);
616                 if (!VXLAN_LOCK_WOWNED(sc)) {
617                         VXLAN_RUNLOCK(sc, tracker);
618                         VXLAN_WLOCK(sc);
619                         sc->vxl_stats.ftable_lock_upgrade_failed++;
620                         goto again;
621                 }
622                 vxlan_sockaddr_in_copy(&fe->vxlfe_raddr, &vxlsa->sa);
623                 return (0);
624         }
625
626         if (!VXLAN_LOCK_WOWNED(sc)) {
627                 VXLAN_RUNLOCK(sc, tracker);
628                 VXLAN_WLOCK(sc);
629                 sc->vxl_stats.ftable_lock_upgrade_failed++;
630                 goto again;
631         }
632
633         if (sc->vxl_ftable_cnt >= sc->vxl_ftable_max) {
634                 sc->vxl_stats.ftable_nospace++;
635                 return (ENOSPC);
636         }
637
638         fe = vxlan_ftable_entry_alloc();
639         if (fe == NULL)
640                 return (ENOMEM);
641
642         vxlan_ftable_entry_init(sc, fe, mac, &vxlsa->sa, VXLAN_FE_FLAG_DYNAMIC);
643
644         /* The prior lookup failed, so the insert should not. */
645         error = vxlan_ftable_entry_insert(sc, fe);
646         MPASS(error == 0);
647
648         return (0);
649 }
650
651 static int
652 vxlan_ftable_learn(struct vxlan_softc *sc, const struct sockaddr *sa,
653     const uint8_t *mac)
654 {
655         struct rm_priotracker tracker;
656         union vxlan_sockaddr vxlsa;
657         int error;
658
659         /*
660          * The source port may be randomly selected by the remote host, so
661          * use the port of the default destination address.
662          */
663         vxlan_sockaddr_copy(&vxlsa, sa);
664         vxlsa.in4.sin_port = sc->vxl_dst_addr.in4.sin_port;
665
666         if (VXLAN_SOCKADDR_IS_IPV6(&vxlsa)) {
667                 error = vxlan_sockaddr_in6_embedscope(&vxlsa);
668                 if (error)
669                         return (error);
670         }
671
672         VXLAN_RLOCK(sc, &tracker);
673         error = vxlan_ftable_update_locked(sc, &vxlsa, mac, &tracker);
674         VXLAN_UNLOCK(sc, &tracker);
675
676         return (error);
677 }
678
679 static int
680 vxlan_ftable_sysctl_dump(SYSCTL_HANDLER_ARGS)
681 {
682         struct rm_priotracker tracker;
683         struct sbuf sb;
684         struct vxlan_softc *sc;
685         struct vxlan_ftable_entry *fe;
686         size_t size;
687         int i, error;
688
689         /*
690          * This is mostly intended for debugging during development. It is
691          * not practical to dump an entire large table this way.
692          */
693
694         sc = arg1;
695         size = PAGE_SIZE;       /* Calculate later. */
696
697         sbuf_new(&sb, NULL, size, SBUF_FIXEDLEN);
698         sbuf_putc(&sb, '\n');
699
700         VXLAN_RLOCK(sc, &tracker);
701         for (i = 0; i < VXLAN_SC_FTABLE_SIZE; i++) {
702                 LIST_FOREACH(fe, &sc->vxl_ftable[i], vxlfe_hash) {
703                         if (sbuf_error(&sb) != 0)
704                                 break;
705                         vxlan_ftable_entry_dump(fe, &sb);
706                 }
707         }
708         VXLAN_RUNLOCK(sc, &tracker);
709
710         if (sbuf_len(&sb) == 1)
711                 sbuf_setpos(&sb, 0);
712
713         sbuf_finish(&sb);
714         error = sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);
715         sbuf_delete(&sb);
716
717         return (error);
718 }
719
720 static struct vxlan_ftable_entry *
721 vxlan_ftable_entry_alloc(void)
722 {
723         struct vxlan_ftable_entry *fe;
724
725         fe = malloc(sizeof(*fe), M_VXLAN, M_ZERO | M_NOWAIT);
726
727         return (fe);
728 }
729
730 static void
731 vxlan_ftable_entry_free(struct vxlan_ftable_entry *fe)
732 {
733
734         free(fe, M_VXLAN);
735 }
736
737 static void
738 vxlan_ftable_entry_init(struct vxlan_softc *sc, struct vxlan_ftable_entry *fe,
739     const uint8_t *mac, const struct sockaddr *sa, uint32_t flags)
740 {
741
742         fe->vxlfe_flags = flags;
743         fe->vxlfe_expire = time_uptime + sc->vxl_ftable_timeout;
744         memcpy(fe->vxlfe_mac, mac, ETHER_ADDR_LEN);
745         vxlan_sockaddr_copy(&fe->vxlfe_raddr, sa);
746 }
747
748 static void
749 vxlan_ftable_entry_destroy(struct vxlan_softc *sc,
750     struct vxlan_ftable_entry *fe)
751 {
752
753         sc->vxl_ftable_cnt--;
754         LIST_REMOVE(fe, vxlfe_hash);
755         vxlan_ftable_entry_free(fe);
756 }
757
758 static int
759 vxlan_ftable_entry_insert(struct vxlan_softc *sc,
760     struct vxlan_ftable_entry *fe)
761 {
762         struct vxlan_ftable_entry *lfe;
763         uint32_t hash;
764         int dir;
765
766         VXLAN_LOCK_WASSERT(sc);
767         hash = VXLAN_SC_FTABLE_HASH(sc, fe->vxlfe_mac);
768
769         lfe = LIST_FIRST(&sc->vxl_ftable[hash]);
770         if (lfe == NULL) {
771                 LIST_INSERT_HEAD(&sc->vxl_ftable[hash], fe, vxlfe_hash);
772                 goto out;
773         }
774
775         do {
776                 dir = vxlan_ftable_addr_cmp(fe->vxlfe_mac, lfe->vxlfe_mac);
777                 if (dir == 0)
778                         return (EEXIST);
779                 if (dir > 0) {
780                         LIST_INSERT_BEFORE(lfe, fe, vxlfe_hash);
781                         goto out;
782                 } else if (LIST_NEXT(lfe, vxlfe_hash) == NULL) {
783                         LIST_INSERT_AFTER(lfe, fe, vxlfe_hash);
784                         goto out;
785                 } else
786                         lfe = LIST_NEXT(lfe, vxlfe_hash);
787         } while (lfe != NULL);
788
789 out:
790         sc->vxl_ftable_cnt++;
791
792         return (0);
793 }
794
795 static struct vxlan_ftable_entry *
796 vxlan_ftable_entry_lookup(struct vxlan_softc *sc, const uint8_t *mac)
797 {
798         struct vxlan_ftable_entry *fe;
799         uint32_t hash;
800         int dir;
801
802         VXLAN_LOCK_ASSERT(sc);
803         hash = VXLAN_SC_FTABLE_HASH(sc, mac);
804
805         LIST_FOREACH(fe, &sc->vxl_ftable[hash], vxlfe_hash) {
806                 dir = vxlan_ftable_addr_cmp(mac, fe->vxlfe_mac);
807                 if (dir == 0)
808                         return (fe);
809                 if (dir > 0)
810                         break;
811         }
812
813         return (NULL);
814 }
815
816 static void
817 vxlan_ftable_entry_dump(struct vxlan_ftable_entry *fe, struct sbuf *sb)
818 {
819         char buf[64];
820         const union vxlan_sockaddr *sa;
821         const void *addr;
822         int i, len, af, width;
823
824         sa = &fe->vxlfe_raddr;
825         af = sa->sa.sa_family;
826         len = sbuf_len(sb);
827
828         sbuf_printf(sb, "%c 0x%02X ", VXLAN_FE_IS_DYNAMIC(fe) ? 'D' : 'S',
829             fe->vxlfe_flags);
830
831         for (i = 0; i < ETHER_ADDR_LEN - 1; i++)
832                 sbuf_printf(sb, "%02X:", fe->vxlfe_mac[i]);
833         sbuf_printf(sb, "%02X ", fe->vxlfe_mac[i]);
834
835         if (af == AF_INET) {
836                 addr = &sa->in4.sin_addr;
837                 width = INET_ADDRSTRLEN - 1;
838         } else {
839                 addr = &sa->in6.sin6_addr;
840                 width = INET6_ADDRSTRLEN - 1;
841         }
842         inet_ntop(af, addr, buf, sizeof(buf));
843         sbuf_printf(sb, "%*s ", width, buf);
844
845         sbuf_printf(sb, "%08jd", (intmax_t)fe->vxlfe_expire);
846
847         sbuf_putc(sb, '\n');
848
849         /* Truncate a partial line. */
850         if (sbuf_error(sb) != 0)
851                 sbuf_setpos(sb, len);
852 }
853
854 static struct vxlan_socket *
855 vxlan_socket_alloc(const union vxlan_sockaddr *sa)
856 {
857         struct vxlan_socket *vso;
858         int i;
859
860         vso = malloc(sizeof(*vso), M_VXLAN, M_WAITOK | M_ZERO);
861         rm_init(&vso->vxlso_lock, "vxlansorm");
862         refcount_init(&vso->vxlso_refcnt, 0);
863         for (i = 0; i < VXLAN_SO_VNI_HASH_SIZE; i++)
864                 LIST_INIT(&vso->vxlso_vni_hash[i]);
865         vso->vxlso_laddr = *sa;
866
867         return (vso);
868 }
869
870 static void
871 vxlan_socket_destroy(struct vxlan_socket *vso)
872 {
873         struct socket *so;
874 #ifdef INVARIANTS
875         int i;
876         struct vxlan_socket_mc_info *mc;
877
878         for (i = 0; i < VXLAN_SO_MC_MAX_GROUPS; i++) {
879                 mc = &vso->vxlso_mc[i];
880                 KASSERT(mc->vxlsomc_gaddr.sa.sa_family == AF_UNSPEC,
881                     ("%s: socket %p mc[%d] still has address",
882                      __func__, vso, i));
883         }
884
885         for (i = 0; i < VXLAN_SO_VNI_HASH_SIZE; i++) {
886                 KASSERT(LIST_EMPTY(&vso->vxlso_vni_hash[i]),
887                     ("%s: socket %p vni_hash[%d] not empty",
888                      __func__, vso, i));
889         }
890 #endif
891         so = vso->vxlso_sock;
892         if (so != NULL) {
893                 vso->vxlso_sock = NULL;
894                 soclose(so);
895         }
896
897         rm_destroy(&vso->vxlso_lock);
898         free(vso, M_VXLAN);
899 }
900
901 static void
902 vxlan_socket_release(struct vxlan_socket *vso)
903 {
904         int destroy;
905
906         VXLAN_LIST_LOCK();
907         destroy = VXLAN_SO_RELEASE(vso);
908         if (destroy != 0)
909                 LIST_REMOVE(vso, vxlso_entry);
910         VXLAN_LIST_UNLOCK();
911
912         if (destroy != 0)
913                 vxlan_socket_destroy(vso);
914 }
915
916 static struct vxlan_socket *
917 vxlan_socket_lookup(union vxlan_sockaddr *vxlsa)
918 {
919         struct vxlan_socket *vso;
920
921         VXLAN_LIST_LOCK();
922         LIST_FOREACH(vso, &vxlan_socket_list, vxlso_entry) {
923                 if (vxlan_sockaddr_cmp(&vso->vxlso_laddr, &vxlsa->sa) == 0) {
924                         VXLAN_SO_ACQUIRE(vso);
925                         break;
926                 }
927         }
928         VXLAN_LIST_UNLOCK();
929
930         return (vso);
931 }
932
933 static void
934 vxlan_socket_insert(struct vxlan_socket *vso)
935 {
936
937         VXLAN_LIST_LOCK();
938         VXLAN_SO_ACQUIRE(vso);
939         LIST_INSERT_HEAD(&vxlan_socket_list, vso, vxlso_entry);
940         VXLAN_LIST_UNLOCK();
941 }
942
943 static int
944 vxlan_socket_init(struct vxlan_socket *vso, struct ifnet *ifp)
945 {
946         struct thread *td;
947         int error;
948
949         td = curthread;
950
951         error = socreate(vso->vxlso_laddr.sa.sa_family, &vso->vxlso_sock,
952             SOCK_DGRAM, IPPROTO_UDP, td->td_ucred, td);
953         if (error) {
954                 if_printf(ifp, "cannot create socket: %d\n", error);
955                 return (error);
956         }
957
958         error = udp_set_kernel_tunneling(vso->vxlso_sock,
959             vxlan_rcv_udp_packet, NULL, vso);
960         if (error) {
961                 if_printf(ifp, "cannot set tunneling function: %d\n", error);
962                 return (error);
963         }
964
965         if (vxlan_reuse_port != 0) {
966                 struct sockopt sopt;
967                 int val = 1;
968
969                 bzero(&sopt, sizeof(sopt));
970                 sopt.sopt_dir = SOPT_SET;
971                 sopt.sopt_level = IPPROTO_IP;
972                 sopt.sopt_name = SO_REUSEPORT;
973                 sopt.sopt_val = &val;
974                 sopt.sopt_valsize = sizeof(val);
975                 error = sosetopt(vso->vxlso_sock, &sopt);
976                 if (error) {
977                         if_printf(ifp,
978                             "cannot set REUSEADDR socket opt: %d\n", error);
979                         return (error);
980                 }
981         }
982
983         return (0);
984 }
985
986 static int
987 vxlan_socket_bind(struct vxlan_socket *vso, struct ifnet *ifp)
988 {
989         union vxlan_sockaddr laddr;
990         struct thread *td;
991         int error;
992
993         td = curthread;
994         laddr = vso->vxlso_laddr;
995
996         error = sobind(vso->vxlso_sock, &laddr.sa, td);
997         if (error) {
998                 if (error != EADDRINUSE)
999                         if_printf(ifp, "cannot bind socket: %d\n", error);
1000                 return (error);
1001         }
1002
1003         return (0);
1004 }
1005
1006 static int
1007 vxlan_socket_create(struct ifnet *ifp, int multicast,
1008     const union vxlan_sockaddr *saddr, struct vxlan_socket **vsop)
1009 {
1010         union vxlan_sockaddr laddr;
1011         struct vxlan_socket *vso;
1012         int error;
1013
1014         laddr = *saddr;
1015
1016         /*
1017          * If this socket will be multicast, then only the local port
1018          * must be specified when binding.
1019          */
1020         if (multicast != 0) {
1021                 if (VXLAN_SOCKADDR_IS_IPV4(&laddr))
1022                         laddr.in4.sin_addr.s_addr = INADDR_ANY;
1023 #ifdef INET6
1024                 else
1025                         laddr.in6.sin6_addr = in6addr_any;
1026 #endif
1027         }
1028
1029         vso = vxlan_socket_alloc(&laddr);
1030         if (vso == NULL)
1031                 return (ENOMEM);
1032
1033         error = vxlan_socket_init(vso, ifp);
1034         if (error)
1035                 goto fail;
1036
1037         error = vxlan_socket_bind(vso, ifp);
1038         if (error)
1039                 goto fail;
1040
1041         /*
1042          * There is a small window between the bind completing and
1043          * inserting the socket, so that a concurrent create may fail.
1044          * Let's not worry about that for now.
1045          */
1046         vxlan_socket_insert(vso);
1047         *vsop = vso;
1048
1049         return (0);
1050
1051 fail:
1052         vxlan_socket_destroy(vso);
1053
1054         return (error);
1055 }
1056
1057 static void
1058 vxlan_socket_ifdetach(struct vxlan_socket *vso, struct ifnet *ifp,
1059     struct vxlan_softc_head *list)
1060 {
1061         struct rm_priotracker tracker;
1062         struct vxlan_softc *sc;
1063         int i;
1064
1065         VXLAN_SO_RLOCK(vso, &tracker);
1066         for (i = 0; i < VXLAN_SO_VNI_HASH_SIZE; i++) {
1067                 LIST_FOREACH(sc, &vso->vxlso_vni_hash[i], vxl_entry)
1068                         vxlan_ifdetach(sc, ifp, list);
1069         }
1070         VXLAN_SO_RUNLOCK(vso, &tracker);
1071 }
1072
1073 static struct vxlan_socket *
1074 vxlan_socket_mc_lookup(const union vxlan_sockaddr *vxlsa)
1075 {
1076         union vxlan_sockaddr laddr;
1077         struct vxlan_socket *vso;
1078
1079         laddr = *vxlsa;
1080
1081         if (VXLAN_SOCKADDR_IS_IPV4(&laddr))
1082                 laddr.in4.sin_addr.s_addr = INADDR_ANY;
1083 #ifdef INET6
1084         else
1085                 laddr.in6.sin6_addr = in6addr_any;
1086 #endif
1087
1088         vso = vxlan_socket_lookup(&laddr);
1089
1090         return (vso);
1091 }
1092
1093 static int
1094 vxlan_sockaddr_mc_info_match(const struct vxlan_socket_mc_info *mc,
1095     const union vxlan_sockaddr *group, const union vxlan_sockaddr *local,
1096     int ifidx)
1097 {
1098
1099         if (!vxlan_sockaddr_in_any(local) &&
1100             !vxlan_sockaddr_in_equal(&mc->vxlsomc_saddr, &local->sa))
1101                 return (0);
1102         if (!vxlan_sockaddr_in_equal(&mc->vxlsomc_gaddr, &group->sa))
1103                 return (0);
1104         if (ifidx != 0 && ifidx != mc->vxlsomc_ifidx)
1105                 return (0);
1106
1107         return (1);
1108 }
1109
1110 static int
1111 vxlan_socket_mc_join_group(struct vxlan_socket *vso,
1112     const union vxlan_sockaddr *group, const union vxlan_sockaddr *local,
1113     int *ifidx, union vxlan_sockaddr *source)
1114 {
1115         struct sockopt sopt;
1116         int error;
1117
1118         *source = *local;
1119
1120         if (VXLAN_SOCKADDR_IS_IPV4(group)) {
1121                 struct ip_mreq mreq;
1122
1123                 mreq.imr_multiaddr = group->in4.sin_addr;
1124                 mreq.imr_interface = local->in4.sin_addr;
1125
1126                 bzero(&sopt, sizeof(sopt));
1127                 sopt.sopt_dir = SOPT_SET;
1128                 sopt.sopt_level = IPPROTO_IP;
1129                 sopt.sopt_name = IP_ADD_MEMBERSHIP;
1130                 sopt.sopt_val = &mreq;
1131                 sopt.sopt_valsize = sizeof(mreq);
1132                 error = sosetopt(vso->vxlso_sock, &sopt);
1133                 if (error)
1134                         return (error);
1135
1136                 /*
1137                  * BMV: Ideally, there would be a formal way for us to get
1138                  * the local interface that was selected based on the
1139                  * imr_interface address. We could then update *ifidx so
1140                  * vxlan_sockaddr_mc_info_match() would return a match for
1141                  * later creates that explicitly set the multicast interface.
1142                  *
1143                  * If we really need to, we can of course look in the INP's
1144                  * membership list:
1145                  *     sotoinpcb(vso->vxlso_sock)->inp_moptions->
1146                  *         imo_head[]->imf_inm->inm_ifp
1147                  * similarly to imo_match_group().
1148                  */
1149                 source->in4.sin_addr = local->in4.sin_addr;
1150
1151         } else if (VXLAN_SOCKADDR_IS_IPV6(group)) {
1152                 struct ipv6_mreq mreq;
1153
1154                 mreq.ipv6mr_multiaddr = group->in6.sin6_addr;
1155                 mreq.ipv6mr_interface = *ifidx;
1156
1157                 bzero(&sopt, sizeof(sopt));
1158                 sopt.sopt_dir = SOPT_SET;
1159                 sopt.sopt_level = IPPROTO_IPV6;
1160                 sopt.sopt_name = IPV6_JOIN_GROUP;
1161                 sopt.sopt_val = &mreq;
1162                 sopt.sopt_valsize = sizeof(mreq);
1163                 error = sosetopt(vso->vxlso_sock, &sopt);
1164                 if (error)
1165                         return (error);
1166
1167                 /*
1168                  * BMV: As with IPv4, we would really like to know what
1169                  * interface in6p_lookup_mcast_ifp() selected.
1170                  */
1171         } else
1172                 error = EAFNOSUPPORT;
1173
1174         return (error);
1175 }
1176
1177 static int
1178 vxlan_socket_mc_leave_group(struct vxlan_socket *vso,
1179     const union vxlan_sockaddr *group, const union vxlan_sockaddr *source,
1180     int ifidx)
1181 {
1182         struct sockopt sopt;
1183         int error;
1184
1185         bzero(&sopt, sizeof(sopt));
1186         sopt.sopt_dir = SOPT_SET;
1187
1188         if (VXLAN_SOCKADDR_IS_IPV4(group)) {
1189                 struct ip_mreq mreq;
1190
1191                 mreq.imr_multiaddr = group->in4.sin_addr;
1192                 mreq.imr_interface = source->in4.sin_addr;
1193
1194                 sopt.sopt_level = IPPROTO_IP;
1195                 sopt.sopt_name = IP_DROP_MEMBERSHIP;
1196                 sopt.sopt_val = &mreq;
1197                 sopt.sopt_valsize = sizeof(mreq);
1198                 error = sosetopt(vso->vxlso_sock, &sopt);
1199
1200         } else if (VXLAN_SOCKADDR_IS_IPV6(group)) {
1201                 struct ipv6_mreq mreq;
1202
1203                 mreq.ipv6mr_multiaddr = group->in6.sin6_addr;
1204                 mreq.ipv6mr_interface = ifidx;
1205
1206                 sopt.sopt_level = IPPROTO_IPV6;
1207                 sopt.sopt_name = IPV6_LEAVE_GROUP;
1208                 sopt.sopt_val = &mreq;
1209                 sopt.sopt_valsize = sizeof(mreq);
1210                 error = sosetopt(vso->vxlso_sock, &sopt);
1211
1212         } else
1213                 error = EAFNOSUPPORT;
1214
1215         return (error);
1216 }
1217
1218 static int
1219 vxlan_socket_mc_add_group(struct vxlan_socket *vso,
1220     const union vxlan_sockaddr *group, const union vxlan_sockaddr *local,
1221     int ifidx, int *idx)
1222 {
1223         union vxlan_sockaddr source;
1224         struct vxlan_socket_mc_info *mc;
1225         int i, empty, error;
1226
1227         /*
1228          * Within a socket, the same multicast group may be used by multiple
1229          * interfaces, each with a different network identifier. But a socket
1230          * may only join a multicast group once, so keep track of the users
1231          * here.
1232          */
1233
1234         VXLAN_SO_WLOCK(vso);
1235         for (empty = 0, i = 0; i < VXLAN_SO_MC_MAX_GROUPS; i++) {
1236                 mc = &vso->vxlso_mc[i];
1237
1238                 if (mc->vxlsomc_gaddr.sa.sa_family == AF_UNSPEC) {
1239                         empty++;
1240                         continue;
1241                 }
1242
1243                 if (vxlan_sockaddr_mc_info_match(mc, group, local, ifidx))
1244                         goto out;
1245         }
1246         VXLAN_SO_WUNLOCK(vso);
1247
1248         if (empty == 0)
1249                 return (ENOSPC);
1250
1251         error = vxlan_socket_mc_join_group(vso, group, local, &ifidx, &source);
1252         if (error)
1253                 return (error);
1254
1255         VXLAN_SO_WLOCK(vso);
1256         for (i = 0; i < VXLAN_SO_MC_MAX_GROUPS; i++) {
1257                 mc = &vso->vxlso_mc[i];
1258
1259                 if (mc->vxlsomc_gaddr.sa.sa_family == AF_UNSPEC) {
1260                         vxlan_sockaddr_copy(&mc->vxlsomc_gaddr, &group->sa);
1261                         vxlan_sockaddr_copy(&mc->vxlsomc_saddr, &source.sa);
1262                         mc->vxlsomc_ifidx = ifidx;
1263                         goto out;
1264                 }
1265         }
1266         VXLAN_SO_WUNLOCK(vso);
1267
1268         error = vxlan_socket_mc_leave_group(vso, group, &source, ifidx);
1269         MPASS(error == 0);
1270
1271         return (ENOSPC);
1272
1273 out:
1274         mc->vxlsomc_users++;
1275         VXLAN_SO_WUNLOCK(vso);
1276
1277         *idx = i;
1278
1279         return (0);
1280 }
1281
1282 static void
1283 vxlan_socket_mc_release_group_by_idx(struct vxlan_socket *vso, int idx)
1284 {
1285         union vxlan_sockaddr group, source;
1286         struct vxlan_socket_mc_info *mc;
1287         int ifidx, leave;
1288
1289         KASSERT(idx >= 0 && idx < VXLAN_SO_MC_MAX_GROUPS,
1290             ("%s: vso %p idx %d out of bounds", __func__, vso, idx));
1291
1292         leave = 0;
1293         mc = &vso->vxlso_mc[idx];
1294
1295         VXLAN_SO_WLOCK(vso);
1296         mc->vxlsomc_users--;
1297         if (mc->vxlsomc_users == 0) {
1298                 group = mc->vxlsomc_gaddr;
1299                 source = mc->vxlsomc_saddr;
1300                 ifidx = mc->vxlsomc_ifidx;
1301                 bzero(mc, sizeof(*mc));
1302                 leave = 1;
1303         }
1304         VXLAN_SO_WUNLOCK(vso);
1305
1306         if (leave != 0) {
1307                 /*
1308                  * Our socket's membership in this group may have already
1309                  * been removed if we joined through an interface that's
1310                  * been detached.
1311                  */
1312                 vxlan_socket_mc_leave_group(vso, &group, &source, ifidx);
1313         }
1314 }
1315
1316 static struct vxlan_softc *
1317 vxlan_socket_lookup_softc_locked(struct vxlan_socket *vso, uint32_t vni)
1318 {
1319         struct vxlan_softc *sc;
1320         uint32_t hash;
1321
1322         VXLAN_SO_LOCK_ASSERT(vso);
1323         hash = VXLAN_SO_VNI_HASH(vni);
1324
1325         LIST_FOREACH(sc, &vso->vxlso_vni_hash[hash], vxl_entry) {
1326                 if (sc->vxl_vni == vni) {
1327                         VXLAN_ACQUIRE(sc);
1328                         break;
1329                 }
1330         }
1331
1332         return (sc);
1333 }
1334
1335 static struct vxlan_softc *
1336 vxlan_socket_lookup_softc(struct vxlan_socket *vso, uint32_t vni)
1337 {
1338         struct rm_priotracker tracker;
1339         struct vxlan_softc *sc;
1340
1341         VXLAN_SO_RLOCK(vso, &tracker);
1342         sc = vxlan_socket_lookup_softc_locked(vso, vni);
1343         VXLAN_SO_RUNLOCK(vso, &tracker);
1344
1345         return (sc);
1346 }
1347
1348 static int
1349 vxlan_socket_insert_softc(struct vxlan_socket *vso, struct vxlan_softc *sc)
1350 {
1351         struct vxlan_softc *tsc;
1352         uint32_t vni, hash;
1353
1354         vni = sc->vxl_vni;
1355         hash = VXLAN_SO_VNI_HASH(vni);
1356
1357         VXLAN_SO_WLOCK(vso);
1358         tsc = vxlan_socket_lookup_softc_locked(vso, vni);
1359         if (tsc != NULL) {
1360                 VXLAN_SO_WUNLOCK(vso);
1361                 vxlan_release(tsc);
1362                 return (EEXIST);
1363         }
1364
1365         VXLAN_ACQUIRE(sc);
1366         LIST_INSERT_HEAD(&vso->vxlso_vni_hash[hash], sc, vxl_entry);
1367         VXLAN_SO_WUNLOCK(vso);
1368
1369         return (0);
1370 }
1371
1372 static void
1373 vxlan_socket_remove_softc(struct vxlan_socket *vso, struct vxlan_softc *sc)
1374 {
1375
1376         VXLAN_SO_WLOCK(vso);
1377         LIST_REMOVE(sc, vxl_entry);
1378         VXLAN_SO_WUNLOCK(vso);
1379
1380         vxlan_release(sc);
1381 }
1382
1383 static struct ifnet *
1384 vxlan_multicast_if_ref(struct vxlan_softc *sc, int ipv4)
1385 {
1386         struct ifnet *ifp;
1387
1388         VXLAN_LOCK_ASSERT(sc);
1389
1390         if (ipv4 && sc->vxl_im4o != NULL)
1391                 ifp = sc->vxl_im4o->imo_multicast_ifp;
1392         else if (!ipv4 && sc->vxl_im6o != NULL)
1393                 ifp = sc->vxl_im6o->im6o_multicast_ifp;
1394         else
1395                 ifp = NULL;
1396
1397         if (ifp != NULL)
1398                 if_ref(ifp);
1399
1400         return (ifp);
1401 }
1402
1403 static void
1404 vxlan_free_multicast(struct vxlan_softc *sc)
1405 {
1406
1407         if (sc->vxl_mc_ifp != NULL) {
1408                 if_rele(sc->vxl_mc_ifp);
1409                 sc->vxl_mc_ifp = NULL;
1410                 sc->vxl_mc_ifindex = 0;
1411         }
1412
1413         if (sc->vxl_im4o != NULL) {
1414                 free(sc->vxl_im4o, M_VXLAN);
1415                 sc->vxl_im4o = NULL;
1416         }
1417
1418         if (sc->vxl_im6o != NULL) {
1419                 free(sc->vxl_im6o, M_VXLAN);
1420                 sc->vxl_im6o = NULL;
1421         }
1422 }
1423
1424 static int
1425 vxlan_setup_multicast_interface(struct vxlan_softc *sc)
1426 {
1427         struct ifnet *ifp;
1428
1429         ifp = ifunit_ref(sc->vxl_mc_ifname);
1430         if (ifp == NULL) {
1431                 if_printf(sc->vxl_ifp, "multicast interface %s does "
1432                     "not exist\n", sc->vxl_mc_ifname);
1433                 return (ENOENT);
1434         }
1435
1436         if ((ifp->if_flags & IFF_MULTICAST) == 0) {
1437                 if_printf(sc->vxl_ifp, "interface %s does not support "
1438                      "multicast\n", sc->vxl_mc_ifname);
1439                 if_rele(ifp);
1440                 return (ENOTSUP);
1441         }
1442
1443         sc->vxl_mc_ifp = ifp;
1444         sc->vxl_mc_ifindex = ifp->if_index;
1445
1446         return (0);
1447 }
1448
1449 static int
1450 vxlan_setup_multicast(struct vxlan_softc *sc)
1451 {
1452         const union vxlan_sockaddr *group;
1453         int error;
1454
1455         group = &sc->vxl_dst_addr;
1456         error = 0;
1457
1458         if (sc->vxl_mc_ifname[0] != '\0') {
1459                 error = vxlan_setup_multicast_interface(sc);
1460                 if (error)
1461                         return (error);
1462         }
1463
1464         /*
1465          * Initialize an multicast options structure that is sufficiently
1466          * populated for use in the respective IP output routine. This
1467          * structure is typically stored in the socket, but our sockets
1468          * may be shared among multiple interfaces.
1469          */
1470         if (VXLAN_SOCKADDR_IS_IPV4(group)) {
1471                 sc->vxl_im4o = malloc(sizeof(struct ip_moptions), M_VXLAN,
1472                     M_ZERO | M_WAITOK);
1473                 sc->vxl_im4o->imo_multicast_ifp = sc->vxl_mc_ifp;
1474                 sc->vxl_im4o->imo_multicast_ttl = sc->vxl_ttl;
1475                 sc->vxl_im4o->imo_multicast_vif = -1;
1476         } else if (VXLAN_SOCKADDR_IS_IPV6(group)) {
1477                 sc->vxl_im6o = malloc(sizeof(struct ip6_moptions), M_VXLAN,
1478                     M_ZERO | M_WAITOK);
1479                 sc->vxl_im6o->im6o_multicast_ifp = sc->vxl_mc_ifp;
1480                 sc->vxl_im6o->im6o_multicast_hlim = sc->vxl_ttl;
1481         }
1482
1483         return (error);
1484 }
1485
1486 static int
1487 vxlan_setup_socket(struct vxlan_softc *sc)
1488 {
1489         struct vxlan_socket *vso;
1490         struct ifnet *ifp;
1491         union vxlan_sockaddr *saddr, *daddr;
1492         int multicast, error;
1493
1494         vso = NULL;
1495         ifp = sc->vxl_ifp;
1496         saddr = &sc->vxl_src_addr;
1497         daddr = &sc->vxl_dst_addr;
1498
1499         multicast = vxlan_sockaddr_in_multicast(daddr);
1500         MPASS(multicast != -1);
1501         sc->vxl_vso_mc_index = -1;
1502
1503         /*
1504          * Try to create the socket. If that fails, attempt to use an
1505          * existing socket.
1506          */
1507         error = vxlan_socket_create(ifp, multicast, saddr, &vso);
1508         if (error) {
1509                 if (multicast != 0)
1510                         vso = vxlan_socket_mc_lookup(saddr);
1511                 else
1512                         vso = vxlan_socket_lookup(saddr);
1513
1514                 if (vso == NULL) {
1515                         if_printf(ifp, "cannot create socket (error: %d), "
1516                             "and no existing socket found\n", error);
1517                         goto out;
1518                 }
1519         }
1520
1521         if (multicast != 0) {
1522                 error = vxlan_setup_multicast(sc);
1523                 if (error)
1524                         goto out;
1525
1526                 error = vxlan_socket_mc_add_group(vso, daddr, saddr,
1527                     sc->vxl_mc_ifindex, &sc->vxl_vso_mc_index);
1528                 if (error)
1529                         goto out;
1530         }
1531
1532         sc->vxl_sock = vso;
1533         error = vxlan_socket_insert_softc(vso, sc);
1534         if (error) {
1535                 sc->vxl_sock = NULL;
1536                 if_printf(ifp, "network identifier %d already exists in "
1537                     "this socket\n", sc->vxl_vni);
1538                 goto out;
1539         }
1540
1541         return (0);
1542
1543 out:
1544         if (vso != NULL) {
1545                 if (sc->vxl_vso_mc_index != -1) {
1546                         vxlan_socket_mc_release_group_by_idx(vso,
1547                             sc->vxl_vso_mc_index);
1548                         sc->vxl_vso_mc_index = -1;
1549                 }
1550                 if (multicast != 0)
1551                         vxlan_free_multicast(sc);
1552                 vxlan_socket_release(vso);
1553         }
1554
1555         return (error);
1556 }
1557
1558 static void
1559 vxlan_setup_interface(struct vxlan_softc *sc)
1560 {
1561         struct ifnet *ifp;
1562
1563         ifp = sc->vxl_ifp;
1564         ifp->if_hdrlen = ETHER_HDR_LEN + sizeof(struct vxlanudphdr);
1565
1566         if (VXLAN_SOCKADDR_IS_IPV4(&sc->vxl_dst_addr) != 0)
1567                 ifp->if_hdrlen += sizeof(struct ip);
1568         else if (VXLAN_SOCKADDR_IS_IPV6(&sc->vxl_dst_addr) != 0)
1569                 ifp->if_hdrlen += sizeof(struct ip6_hdr);
1570 }
1571
1572 static int
1573 vxlan_valid_init_config(struct vxlan_softc *sc)
1574 {
1575         const char *reason;
1576
1577         if (vxlan_check_vni(sc->vxl_vni) != 0) {
1578                 reason = "invalid virtual network identifier specified";
1579                 goto fail;
1580         }
1581
1582         if (vxlan_sockaddr_supported(&sc->vxl_src_addr, 1) == 0) {
1583                 reason = "source address type is not supported";
1584                 goto fail;
1585         }
1586
1587         if (vxlan_sockaddr_supported(&sc->vxl_dst_addr, 0) == 0) {
1588                 reason = "destination address type is not supported";
1589                 goto fail;
1590         }
1591
1592         if (vxlan_sockaddr_in_any(&sc->vxl_dst_addr) != 0) {
1593                 reason = "no valid destination address specified";
1594                 goto fail;
1595         }
1596
1597         if (vxlan_sockaddr_in_multicast(&sc->vxl_dst_addr) == 0 &&
1598             sc->vxl_mc_ifname[0] != '\0') {
1599                 reason = "can only specify interface with a group address";
1600                 goto fail;
1601         }
1602
1603         if (vxlan_sockaddr_in_any(&sc->vxl_src_addr) == 0) {
1604                 if (VXLAN_SOCKADDR_IS_IPV4(&sc->vxl_src_addr) ^
1605                     VXLAN_SOCKADDR_IS_IPV4(&sc->vxl_dst_addr)) {
1606                         reason = "source and destination address must both "
1607                             "be either IPv4 or IPv6";
1608                         goto fail;
1609                 }
1610         }
1611
1612         if (sc->vxl_src_addr.in4.sin_port == 0) {
1613                 reason = "local port not specified";
1614                 goto fail;
1615         }
1616
1617         if (sc->vxl_dst_addr.in4.sin_port == 0) {
1618                 reason = "remote port not specified";
1619                 goto fail;
1620         }
1621
1622         return (0);
1623
1624 fail:
1625         if_printf(sc->vxl_ifp, "cannot initialize interface: %s\n", reason);
1626         return (EINVAL);
1627 }
1628
1629 static void
1630 vxlan_init_wait(struct vxlan_softc *sc)
1631 {
1632
1633         VXLAN_LOCK_WASSERT(sc);
1634         while (sc->vxl_flags & VXLAN_FLAG_INIT)
1635                 rm_sleep(sc, &sc->vxl_lock, 0, "vxlint", hz);
1636 }
1637
1638 static void
1639 vxlan_init_complete(struct vxlan_softc *sc)
1640 {
1641
1642         VXLAN_WLOCK(sc);
1643         sc->vxl_flags &= ~VXLAN_FLAG_INIT;
1644         wakeup(sc);
1645         VXLAN_WUNLOCK(sc);
1646 }
1647
1648 static void
1649 vxlan_init(void *xsc)
1650 {
1651         static const uint8_t empty_mac[ETHER_ADDR_LEN];
1652         struct vxlan_softc *sc;
1653         struct ifnet *ifp;
1654
1655         sc = xsc;
1656         ifp = sc->vxl_ifp;
1657
1658         VXLAN_WLOCK(sc);
1659         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1660                 VXLAN_WUNLOCK(sc);
1661                 return;
1662         }
1663         sc->vxl_flags |= VXLAN_FLAG_INIT;
1664         VXLAN_WUNLOCK(sc);
1665
1666         if (vxlan_valid_init_config(sc) != 0)
1667                 goto out;
1668
1669         vxlan_setup_interface(sc);
1670
1671         if (vxlan_setup_socket(sc) != 0)
1672                 goto out;
1673
1674         /* Initialize the default forwarding entry. */
1675         vxlan_ftable_entry_init(sc, &sc->vxl_default_fe, empty_mac,
1676             &sc->vxl_dst_addr.sa, VXLAN_FE_FLAG_STATIC);
1677
1678         VXLAN_WLOCK(sc);
1679         ifp->if_drv_flags |= IFF_DRV_RUNNING;
1680         callout_reset(&sc->vxl_callout, vxlan_ftable_prune_period * hz,
1681             vxlan_timer, sc);
1682         VXLAN_WUNLOCK(sc);
1683
1684         if_link_state_change(ifp, LINK_STATE_UP);
1685 out:
1686         vxlan_init_complete(sc);
1687 }
1688
1689 static void
1690 vxlan_release(struct vxlan_softc *sc)
1691 {
1692
1693         /*
1694          * The softc may be destroyed as soon as we release our reference,
1695          * so we cannot serialize the wakeup with the softc lock. We use a
1696          * timeout in our sleeps so a missed wakeup is unfortunate but not
1697          * fatal.
1698          */
1699         if (VXLAN_RELEASE(sc) != 0)
1700                 wakeup(sc);
1701 }
1702
1703 static void
1704 vxlan_teardown_wait(struct vxlan_softc *sc)
1705 {
1706
1707         VXLAN_LOCK_WASSERT(sc);
1708         while (sc->vxl_flags & VXLAN_FLAG_TEARDOWN)
1709                 rm_sleep(sc, &sc->vxl_lock, 0, "vxltrn", hz);
1710 }
1711
1712 static void
1713 vxlan_teardown_complete(struct vxlan_softc *sc)
1714 {
1715
1716         VXLAN_WLOCK(sc);
1717         sc->vxl_flags &= ~VXLAN_FLAG_TEARDOWN;
1718         wakeup(sc);
1719         VXLAN_WUNLOCK(sc);
1720 }
1721
1722 static void
1723 vxlan_teardown_locked(struct vxlan_softc *sc)
1724 {
1725         struct ifnet *ifp;
1726         struct vxlan_socket *vso;
1727
1728         ifp = sc->vxl_ifp;
1729
1730         VXLAN_LOCK_WASSERT(sc);
1731         MPASS(sc->vxl_flags & VXLAN_FLAG_TEARDOWN);
1732
1733         ifp->if_flags &= ~IFF_UP;
1734         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1735         callout_stop(&sc->vxl_callout);
1736         vso = sc->vxl_sock;
1737         sc->vxl_sock = NULL;
1738
1739         VXLAN_WUNLOCK(sc);
1740         if_link_state_change(ifp, LINK_STATE_DOWN);
1741
1742         if (vso != NULL) {
1743                 vxlan_socket_remove_softc(vso, sc);
1744
1745                 if (sc->vxl_vso_mc_index != -1) {
1746                         vxlan_socket_mc_release_group_by_idx(vso,
1747                             sc->vxl_vso_mc_index);
1748                         sc->vxl_vso_mc_index = -1;
1749                 }
1750         }
1751
1752         VXLAN_WLOCK(sc);
1753         while (sc->vxl_refcnt != 0)
1754                 rm_sleep(sc, &sc->vxl_lock, 0, "vxldrn", hz);
1755         VXLAN_WUNLOCK(sc);
1756
1757         callout_drain(&sc->vxl_callout);
1758
1759         vxlan_free_multicast(sc);
1760         if (vso != NULL)
1761                 vxlan_socket_release(vso);
1762
1763         vxlan_teardown_complete(sc);
1764 }
1765
1766 static void
1767 vxlan_teardown(struct vxlan_softc *sc)
1768 {
1769
1770         VXLAN_WLOCK(sc);
1771         if (sc->vxl_flags & VXLAN_FLAG_TEARDOWN) {
1772                 vxlan_teardown_wait(sc);
1773                 VXLAN_WUNLOCK(sc);
1774                 return;
1775         }
1776
1777         sc->vxl_flags |= VXLAN_FLAG_TEARDOWN;
1778         vxlan_teardown_locked(sc);
1779 }
1780
1781 static void
1782 vxlan_ifdetach(struct vxlan_softc *sc, struct ifnet *ifp,
1783     struct vxlan_softc_head *list)
1784 {
1785
1786         VXLAN_WLOCK(sc);
1787
1788         if (sc->vxl_mc_ifp != ifp)
1789                 goto out;
1790         if (sc->vxl_flags & VXLAN_FLAG_TEARDOWN)
1791                 goto out;
1792
1793         sc->vxl_flags |= VXLAN_FLAG_TEARDOWN;
1794         LIST_INSERT_HEAD(list, sc, vxl_ifdetach_list);
1795
1796 out:
1797         VXLAN_WUNLOCK(sc);
1798 }
1799
1800 static void
1801 vxlan_timer(void *xsc)
1802 {
1803         struct vxlan_softc *sc;
1804
1805         sc = xsc;
1806         VXLAN_LOCK_WASSERT(sc);
1807
1808         vxlan_ftable_expire(sc);
1809         callout_schedule(&sc->vxl_callout, vxlan_ftable_prune_period * hz);
1810 }
1811
1812 static int
1813 vxlan_ioctl_ifflags(struct vxlan_softc *sc)
1814 {
1815         struct ifnet *ifp;
1816
1817         ifp = sc->vxl_ifp;
1818
1819         if (ifp->if_flags & IFF_UP) {
1820                 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1821                         vxlan_init(sc);
1822         } else {
1823                 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1824                         vxlan_teardown(sc);
1825         }
1826
1827         return (0);
1828 }
1829
1830 static int
1831 vxlan_ctrl_get_config(struct vxlan_softc *sc, void *arg)
1832 {
1833         struct rm_priotracker tracker;
1834         struct ifvxlancfg *cfg;
1835
1836         cfg = arg;
1837         bzero(cfg, sizeof(*cfg));
1838
1839         VXLAN_RLOCK(sc, &tracker);
1840         cfg->vxlc_vni = sc->vxl_vni;
1841         memcpy(&cfg->vxlc_local_sa, &sc->vxl_src_addr,
1842             sizeof(union vxlan_sockaddr));
1843         memcpy(&cfg->vxlc_remote_sa, &sc->vxl_dst_addr,
1844             sizeof(union vxlan_sockaddr));
1845         cfg->vxlc_mc_ifindex = sc->vxl_mc_ifindex;
1846         cfg->vxlc_ftable_cnt = sc->vxl_ftable_cnt;
1847         cfg->vxlc_ftable_max = sc->vxl_ftable_max;
1848         cfg->vxlc_ftable_timeout = sc->vxl_ftable_timeout;
1849         cfg->vxlc_port_min = sc->vxl_min_port;
1850         cfg->vxlc_port_max = sc->vxl_max_port;
1851         cfg->vxlc_learn = (sc->vxl_flags & VXLAN_FLAG_LEARN) != 0;
1852         cfg->vxlc_ttl = sc->vxl_ttl;
1853         VXLAN_RUNLOCK(sc, &tracker);
1854
1855 #ifdef INET6
1856         if (VXLAN_SOCKADDR_IS_IPV6(&cfg->vxlc_local_sa))
1857                 sa6_recoverscope(&cfg->vxlc_local_sa.in6);
1858         if (VXLAN_SOCKADDR_IS_IPV6(&cfg->vxlc_remote_sa))
1859                 sa6_recoverscope(&cfg->vxlc_remote_sa.in6);
1860 #endif
1861
1862         return (0);
1863 }
1864
1865 static int
1866 vxlan_ctrl_set_vni(struct vxlan_softc *sc, void *arg)
1867 {
1868         struct ifvxlancmd *cmd;
1869         int error;
1870
1871         cmd = arg;
1872
1873         if (vxlan_check_vni(cmd->vxlcmd_vni) != 0)
1874                 return (EINVAL);
1875
1876         VXLAN_WLOCK(sc);
1877         if (vxlan_can_change_config(sc)) {
1878                 sc->vxl_vni = cmd->vxlcmd_vni;
1879                 error = 0;
1880         } else
1881                 error = EBUSY;
1882         VXLAN_WUNLOCK(sc);
1883
1884         return (error);
1885 }
1886
1887 static int
1888 vxlan_ctrl_set_local_addr(struct vxlan_softc *sc, void *arg)
1889 {
1890         struct ifvxlancmd *cmd;
1891         union vxlan_sockaddr *vxlsa;
1892         int error;
1893
1894         cmd = arg;
1895         vxlsa = &cmd->vxlcmd_sa;
1896
1897         if (!VXLAN_SOCKADDR_IS_IPV46(vxlsa))
1898                 return (EINVAL);
1899         if (vxlan_sockaddr_in_multicast(vxlsa) != 0)
1900                 return (EINVAL);
1901         if (VXLAN_SOCKADDR_IS_IPV6(vxlsa)) {
1902                 error = vxlan_sockaddr_in6_embedscope(vxlsa);
1903                 if (error)
1904                         return (error);
1905         }
1906
1907         VXLAN_WLOCK(sc);
1908         if (vxlan_can_change_config(sc)) {
1909                 vxlan_sockaddr_in_copy(&sc->vxl_src_addr, &vxlsa->sa);
1910                 error = 0;
1911         } else
1912                 error = EBUSY;
1913         VXLAN_WUNLOCK(sc);
1914
1915         return (error);
1916 }
1917
1918 static int
1919 vxlan_ctrl_set_remote_addr(struct vxlan_softc *sc, void *arg)
1920 {
1921         struct ifvxlancmd *cmd;
1922         union vxlan_sockaddr *vxlsa;
1923         int error;
1924
1925         cmd = arg;
1926         vxlsa = &cmd->vxlcmd_sa;
1927
1928         if (!VXLAN_SOCKADDR_IS_IPV46(vxlsa))
1929                 return (EINVAL);
1930         if (VXLAN_SOCKADDR_IS_IPV6(vxlsa)) {
1931                 error = vxlan_sockaddr_in6_embedscope(vxlsa);
1932                 if (error)
1933                         return (error);
1934         }
1935
1936         VXLAN_WLOCK(sc);
1937         if (vxlan_can_change_config(sc)) {
1938                 vxlan_sockaddr_in_copy(&sc->vxl_dst_addr, &vxlsa->sa);
1939                 error = 0;
1940         } else
1941                 error = EBUSY;
1942         VXLAN_WUNLOCK(sc);
1943
1944         return (error);
1945 }
1946
1947 static int
1948 vxlan_ctrl_set_local_port(struct vxlan_softc *sc, void *arg)
1949 {
1950         struct ifvxlancmd *cmd;
1951         int error;
1952
1953         cmd = arg;
1954
1955         if (cmd->vxlcmd_port == 0)
1956                 return (EINVAL);
1957
1958         VXLAN_WLOCK(sc);
1959         if (vxlan_can_change_config(sc)) {
1960                 sc->vxl_src_addr.in4.sin_port = htons(cmd->vxlcmd_port);
1961                 error = 0;
1962         } else
1963                 error = EBUSY;
1964         VXLAN_WUNLOCK(sc);
1965
1966         return (error);
1967 }
1968
1969 static int
1970 vxlan_ctrl_set_remote_port(struct vxlan_softc *sc, void *arg)
1971 {
1972         struct ifvxlancmd *cmd;
1973         int error;
1974
1975         cmd = arg;
1976
1977         if (cmd->vxlcmd_port == 0)
1978                 return (EINVAL);
1979
1980         VXLAN_WLOCK(sc);
1981         if (vxlan_can_change_config(sc)) {
1982                 sc->vxl_dst_addr.in4.sin_port = htons(cmd->vxlcmd_port);
1983                 error = 0;
1984         } else
1985                 error = EBUSY;
1986         VXLAN_WUNLOCK(sc);
1987
1988         return (error);
1989 }
1990
1991 static int
1992 vxlan_ctrl_set_port_range(struct vxlan_softc *sc, void *arg)
1993 {
1994         struct ifvxlancmd *cmd;
1995         uint16_t min, max;
1996         int error;
1997
1998         cmd = arg;
1999         min = cmd->vxlcmd_port_min;
2000         max = cmd->vxlcmd_port_max;
2001
2002         if (max < min)
2003                 return (EINVAL);
2004
2005         VXLAN_WLOCK(sc);
2006         if (vxlan_can_change_config(sc)) {
2007                 sc->vxl_min_port = min;
2008                 sc->vxl_max_port = max;
2009                 error = 0;
2010         } else
2011                 error = EBUSY;
2012         VXLAN_WUNLOCK(sc);
2013
2014         return (error);
2015 }
2016
2017 static int
2018 vxlan_ctrl_set_ftable_timeout(struct vxlan_softc *sc, void *arg)
2019 {
2020         struct ifvxlancmd *cmd;
2021         int error;
2022
2023         cmd = arg;
2024
2025         VXLAN_WLOCK(sc);
2026         if (vxlan_check_ftable_timeout(cmd->vxlcmd_ftable_timeout) == 0) {
2027                 sc->vxl_ftable_timeout = cmd->vxlcmd_ftable_timeout;
2028                 error = 0;
2029         } else
2030                 error = EINVAL;
2031         VXLAN_WUNLOCK(sc);
2032
2033         return (error);
2034 }
2035
2036 static int
2037 vxlan_ctrl_set_ftable_max(struct vxlan_softc *sc, void *arg)
2038 {
2039         struct ifvxlancmd *cmd;
2040         int error;
2041
2042         cmd = arg;
2043
2044         VXLAN_WLOCK(sc);
2045         if (vxlan_check_ftable_max(cmd->vxlcmd_ftable_max) == 0) {
2046                 sc->vxl_ftable_max = cmd->vxlcmd_ftable_max;
2047                 error = 0;
2048         } else
2049                 error = EINVAL;
2050         VXLAN_WUNLOCK(sc);
2051
2052         return (error);
2053 }
2054
2055 static int
2056 vxlan_ctrl_set_multicast_if(struct vxlan_softc * sc, void *arg)
2057 {
2058         struct ifvxlancmd *cmd;
2059         int error;
2060
2061         cmd = arg;
2062
2063         VXLAN_WLOCK(sc);
2064         if (vxlan_can_change_config(sc)) {
2065                 strlcpy(sc->vxl_mc_ifname, cmd->vxlcmd_ifname, IFNAMSIZ);
2066                 error = 0;
2067         } else
2068                 error = EBUSY;
2069         VXLAN_WUNLOCK(sc);
2070
2071         return (error);
2072 }
2073
2074 static int
2075 vxlan_ctrl_set_ttl(struct vxlan_softc *sc, void *arg)
2076 {
2077         struct ifvxlancmd *cmd;
2078         int error;
2079
2080         cmd = arg;
2081
2082         VXLAN_WLOCK(sc);
2083         if (vxlan_check_ttl(cmd->vxlcmd_ttl) == 0) {
2084                 sc->vxl_ttl = cmd->vxlcmd_ttl;
2085                 if (sc->vxl_im4o != NULL)
2086                         sc->vxl_im4o->imo_multicast_ttl = sc->vxl_ttl;
2087                 if (sc->vxl_im6o != NULL)
2088                         sc->vxl_im6o->im6o_multicast_hlim = sc->vxl_ttl;
2089                 error = 0;
2090         } else
2091                 error = EINVAL;
2092         VXLAN_WUNLOCK(sc);
2093
2094         return (error);
2095 }
2096
2097 static int
2098 vxlan_ctrl_set_learn(struct vxlan_softc *sc, void *arg)
2099 {
2100         struct ifvxlancmd *cmd;
2101
2102         cmd = arg;
2103
2104         VXLAN_WLOCK(sc);
2105         if (cmd->vxlcmd_flags & VXLAN_CMD_FLAG_LEARN)
2106                 sc->vxl_flags |= VXLAN_FLAG_LEARN;
2107         else
2108                 sc->vxl_flags &= ~VXLAN_FLAG_LEARN;
2109         VXLAN_WUNLOCK(sc);
2110
2111         return (0);
2112 }
2113
2114 static int
2115 vxlan_ctrl_ftable_entry_add(struct vxlan_softc *sc, void *arg)
2116 {
2117         union vxlan_sockaddr vxlsa;
2118         struct ifvxlancmd *cmd;
2119         struct vxlan_ftable_entry *fe;
2120         int error;
2121
2122         cmd = arg;
2123         vxlsa = cmd->vxlcmd_sa;
2124
2125         if (!VXLAN_SOCKADDR_IS_IPV46(&vxlsa))
2126                 return (EINVAL);
2127         if (vxlan_sockaddr_in_any(&vxlsa) != 0)
2128                 return (EINVAL);
2129         if (vxlan_sockaddr_in_multicast(&vxlsa) != 0)
2130                 return (EINVAL);
2131         /* BMV: We could support both IPv4 and IPv6 later. */
2132         if (vxlsa.sa.sa_family != sc->vxl_dst_addr.sa.sa_family)
2133                 return (EAFNOSUPPORT);
2134
2135         if (VXLAN_SOCKADDR_IS_IPV6(&vxlsa)) {
2136                 error = vxlan_sockaddr_in6_embedscope(&vxlsa);
2137                 if (error)
2138                         return (error);
2139         }
2140
2141         fe = vxlan_ftable_entry_alloc();
2142         if (fe == NULL)
2143                 return (ENOMEM);
2144
2145         if (vxlsa.in4.sin_port == 0)
2146                 vxlsa.in4.sin_port = sc->vxl_dst_addr.in4.sin_port;
2147
2148         vxlan_ftable_entry_init(sc, fe, cmd->vxlcmd_mac, &vxlsa.sa,
2149             VXLAN_FE_FLAG_STATIC);
2150
2151         VXLAN_WLOCK(sc);
2152         error = vxlan_ftable_entry_insert(sc, fe);
2153         VXLAN_WUNLOCK(sc);
2154
2155         if (error)
2156                 vxlan_ftable_entry_free(fe);
2157
2158         return (error);
2159 }
2160
2161 static int
2162 vxlan_ctrl_ftable_entry_rem(struct vxlan_softc *sc, void *arg)
2163 {
2164         struct ifvxlancmd *cmd;
2165         struct vxlan_ftable_entry *fe;
2166         int error;
2167
2168         cmd = arg;
2169
2170         VXLAN_WLOCK(sc);
2171         fe = vxlan_ftable_entry_lookup(sc, cmd->vxlcmd_mac);
2172         if (fe != NULL) {
2173                 vxlan_ftable_entry_destroy(sc, fe);
2174                 error = 0;
2175         } else
2176                 error = ENOENT;
2177         VXLAN_WUNLOCK(sc);
2178
2179         return (error);
2180 }
2181
2182 static int
2183 vxlan_ctrl_flush(struct vxlan_softc *sc, void *arg)
2184 {
2185         struct ifvxlancmd *cmd;
2186         int all;
2187
2188         cmd = arg;
2189         all = cmd->vxlcmd_flags & VXLAN_CMD_FLAG_FLUSH_ALL;
2190
2191         VXLAN_WLOCK(sc);
2192         vxlan_ftable_flush(sc, all);
2193         VXLAN_WUNLOCK(sc);
2194
2195         return (0);
2196 }
2197
2198 static int
2199 vxlan_ioctl_drvspec(struct vxlan_softc *sc, struct ifdrv *ifd, int get)
2200 {
2201         const struct vxlan_control *vc;
2202         union {
2203                 struct ifvxlancfg       cfg;
2204                 struct ifvxlancmd       cmd;
2205         } args;
2206         int out, error;
2207
2208         if (ifd->ifd_cmd >= vxlan_control_table_size)
2209                 return (EINVAL);
2210
2211         bzero(&args, sizeof(args));
2212         vc = &vxlan_control_table[ifd->ifd_cmd];
2213         out = (vc->vxlc_flags & VXLAN_CTRL_FLAG_COPYOUT) != 0;
2214
2215         if ((get != 0 && out == 0) || (get == 0 && out != 0))
2216                 return (EINVAL);
2217
2218         if (vc->vxlc_flags & VXLAN_CTRL_FLAG_SUSER) {
2219                 error = priv_check(curthread, PRIV_NET_VXLAN);
2220                 if (error)
2221                         return (error);
2222         }
2223
2224         if (ifd->ifd_len != vc->vxlc_argsize ||
2225             ifd->ifd_len > sizeof(args))
2226                 return (EINVAL);
2227
2228         if (vc->vxlc_flags & VXLAN_CTRL_FLAG_COPYIN) {
2229                 error = copyin(ifd->ifd_data, &args, ifd->ifd_len);
2230                 if (error)
2231                         return (error);
2232         }
2233
2234         error = vc->vxlc_func(sc, &args);
2235         if (error)
2236                 return (error);
2237
2238         if (vc->vxlc_flags & VXLAN_CTRL_FLAG_COPYOUT) {
2239                 error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
2240                 if (error)
2241                         return (error);
2242         }
2243
2244         return (0);
2245 }
2246
2247 static int
2248 vxlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2249 {
2250         struct vxlan_softc *sc;
2251         struct ifreq *ifr;
2252         struct ifdrv *ifd;
2253         int error;
2254
2255         sc = ifp->if_softc;
2256         ifr = (struct ifreq *) data;
2257         ifd = (struct ifdrv *) data;
2258
2259         error = 0;
2260
2261         switch (cmd) {
2262         case SIOCADDMULTI:
2263         case SIOCDELMULTI:
2264                 break;
2265
2266         case SIOCGDRVSPEC:
2267         case SIOCSDRVSPEC:
2268                 error = vxlan_ioctl_drvspec(sc, ifd, cmd == SIOCGDRVSPEC);
2269                 break;
2270
2271         case SIOCSIFFLAGS:
2272                 error = vxlan_ioctl_ifflags(sc);
2273                 break;
2274
2275         case SIOCSIFMEDIA:
2276         case SIOCGIFMEDIA:
2277                 error = ifmedia_ioctl(ifp, ifr, &sc->vxl_media, cmd);
2278                 break;
2279
2280         case SIOCSIFMTU:
2281                 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > VXLAN_MAX_MTU)
2282                         error = EINVAL;
2283                 else
2284                         ifp->if_mtu = ifr->ifr_mtu;
2285                 break;
2286
2287         default:
2288                 error = ether_ioctl(ifp, cmd, data);
2289                 break;
2290         }
2291
2292         return (error);
2293 }
2294
2295 #if defined(INET) || defined(INET6)
2296 static uint16_t
2297 vxlan_pick_source_port(struct vxlan_softc *sc, struct mbuf *m)
2298 {
2299         int range;
2300         uint32_t hash;
2301
2302         range = sc->vxl_max_port - sc->vxl_min_port + 1;
2303
2304         if (M_HASHTYPE_ISHASH(m))
2305                 hash = m->m_pkthdr.flowid;
2306         else
2307                 hash = jenkins_hash(m->m_data, ETHER_HDR_LEN,
2308                     sc->vxl_port_hash_key);
2309
2310         return (sc->vxl_min_port + (hash % range));
2311 }
2312
2313 static void
2314 vxlan_encap_header(struct vxlan_softc *sc, struct mbuf *m, int ipoff,
2315     uint16_t srcport, uint16_t dstport)
2316 {
2317         struct vxlanudphdr *hdr;
2318         struct udphdr *udph;
2319         struct vxlan_header *vxh;
2320         int len;
2321
2322         len = m->m_pkthdr.len - ipoff;
2323         MPASS(len >= sizeof(struct vxlanudphdr));
2324         hdr = mtodo(m, ipoff);
2325
2326         udph = &hdr->vxlh_udp;
2327         udph->uh_sport = srcport;
2328         udph->uh_dport = dstport;
2329         udph->uh_ulen = htons(len);
2330         udph->uh_sum = 0;
2331
2332         vxh = &hdr->vxlh_hdr;
2333         vxh->vxlh_flags = htonl(VXLAN_HDR_FLAGS_VALID_VNI);
2334         vxh->vxlh_vni = htonl(sc->vxl_vni << VXLAN_HDR_VNI_SHIFT);
2335 }
2336 #endif
2337
2338 static int
2339 vxlan_encap4(struct vxlan_softc *sc, const union vxlan_sockaddr *fvxlsa,
2340     struct mbuf *m)
2341 {
2342 #ifdef INET
2343         struct ifnet *ifp;
2344         struct ip *ip;
2345         struct in_addr srcaddr, dstaddr;
2346         uint16_t srcport, dstport;
2347         int len, mcast, error;
2348
2349         ifp = sc->vxl_ifp;
2350         srcaddr = sc->vxl_src_addr.in4.sin_addr;
2351         srcport = vxlan_pick_source_port(sc, m);
2352         dstaddr = fvxlsa->in4.sin_addr;
2353         dstport = fvxlsa->in4.sin_port;
2354
2355         M_PREPEND(m, sizeof(struct ip) + sizeof(struct vxlanudphdr),
2356             M_NOWAIT);
2357         if (m == NULL) {
2358                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2359                 return (ENOBUFS);
2360         }
2361
2362         len = m->m_pkthdr.len;
2363
2364         ip = mtod(m, struct ip *);
2365         ip->ip_tos = 0;
2366         ip->ip_len = htons(len);
2367         ip->ip_off = 0;
2368         ip->ip_ttl = sc->vxl_ttl;
2369         ip->ip_p = IPPROTO_UDP;
2370         ip->ip_sum = 0;
2371         ip->ip_src = srcaddr;
2372         ip->ip_dst = dstaddr;
2373
2374         vxlan_encap_header(sc, m, sizeof(struct ip), srcport, dstport);
2375
2376         mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0;
2377         m->m_flags &= ~(M_MCAST | M_BCAST);
2378
2379         error = ip_output(m, NULL, NULL, 0, sc->vxl_im4o, NULL);
2380         if (error == 0) {
2381                 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
2382                 if_inc_counter(ifp, IFCOUNTER_OBYTES, len);
2383                 if (mcast != 0)
2384                         if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
2385         } else
2386                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2387
2388         return (error);
2389 #else
2390         m_freem(m);
2391         return (ENOTSUP);
2392 #endif
2393 }
2394
2395 static int
2396 vxlan_encap6(struct vxlan_softc *sc, const union vxlan_sockaddr *fvxlsa,
2397     struct mbuf *m)
2398 {
2399 #ifdef INET6
2400         struct ifnet *ifp;
2401         struct ip6_hdr *ip6;
2402         const struct in6_addr *srcaddr, *dstaddr;
2403         uint16_t srcport, dstport;
2404         int len, mcast, error;
2405
2406         ifp = sc->vxl_ifp;
2407         srcaddr = &sc->vxl_src_addr.in6.sin6_addr;
2408         srcport = vxlan_pick_source_port(sc, m);
2409         dstaddr = &fvxlsa->in6.sin6_addr;
2410         dstport = fvxlsa->in6.sin6_port;
2411
2412         M_PREPEND(m, sizeof(struct ip6_hdr) + sizeof(struct vxlanudphdr),
2413             M_NOWAIT);
2414         if (m == NULL) {
2415                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2416                 return (ENOBUFS);
2417         }
2418
2419         len = m->m_pkthdr.len;
2420
2421         ip6 = mtod(m, struct ip6_hdr *);
2422         ip6->ip6_flow = 0;              /* BMV: Keep in forwarding entry? */
2423         ip6->ip6_vfc = IPV6_VERSION;
2424         ip6->ip6_plen = 0;
2425         ip6->ip6_nxt = IPPROTO_UDP;
2426         ip6->ip6_hlim = sc->vxl_ttl;
2427         ip6->ip6_src = *srcaddr;
2428         ip6->ip6_dst = *dstaddr;
2429
2430         vxlan_encap_header(sc, m, sizeof(struct ip6_hdr), srcport, dstport);
2431
2432         /*
2433          * XXX BMV We need support for RFC6935 before we can send and
2434          * receive IPv6 UDP packets with a zero checksum.
2435          */
2436         {
2437                 struct udphdr *hdr = mtodo(m, sizeof(struct ip6_hdr));
2438                 hdr->uh_sum = in6_cksum_pseudo(ip6,
2439                     m->m_pkthdr.len - sizeof(struct ip6_hdr), IPPROTO_UDP, 0);
2440                 m->m_pkthdr.csum_flags = CSUM_UDP_IPV6;
2441                 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
2442         }
2443
2444         mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0;
2445         m->m_flags &= ~(M_MCAST | M_BCAST);
2446
2447         error = ip6_output(m, NULL, NULL, 0, sc->vxl_im6o, NULL, NULL);
2448         if (error == 0) {
2449                 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
2450                 if_inc_counter(ifp, IFCOUNTER_OBYTES, len);
2451                 if (mcast != 0)
2452                         if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
2453         } else
2454                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2455
2456         return (error);
2457 #else
2458         m_freem(m);
2459         return (ENOTSUP);
2460 #endif
2461 }
2462
2463 static int
2464 vxlan_transmit(struct ifnet *ifp, struct mbuf *m)
2465 {
2466         struct rm_priotracker tracker;
2467         union vxlan_sockaddr vxlsa;
2468         struct vxlan_softc *sc;
2469         struct vxlan_ftable_entry *fe;
2470         struct ifnet *mcifp;
2471         struct ether_header *eh;
2472         int ipv4, error;
2473
2474         sc = ifp->if_softc;
2475         eh = mtod(m, struct ether_header *);
2476         fe = NULL;
2477         mcifp = NULL;
2478
2479         ETHER_BPF_MTAP(ifp, m);
2480
2481         VXLAN_RLOCK(sc, &tracker);
2482         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
2483                 VXLAN_RUNLOCK(sc, &tracker);
2484                 m_freem(m);
2485                 return (ENETDOWN);
2486         }
2487
2488         if ((m->m_flags & (M_BCAST | M_MCAST)) == 0)
2489                 fe = vxlan_ftable_entry_lookup(sc, eh->ether_dhost);
2490         if (fe == NULL)
2491                 fe = &sc->vxl_default_fe;
2492         vxlan_sockaddr_copy(&vxlsa, &fe->vxlfe_raddr.sa);
2493
2494         ipv4 = VXLAN_SOCKADDR_IS_IPV4(&vxlsa) != 0;
2495         if (vxlan_sockaddr_in_multicast(&vxlsa) != 0)
2496                 mcifp = vxlan_multicast_if_ref(sc, ipv4);
2497
2498         VXLAN_ACQUIRE(sc);
2499         VXLAN_RUNLOCK(sc, &tracker);
2500
2501         if (ipv4 != 0)
2502                 error = vxlan_encap4(sc, &vxlsa, m);
2503         else
2504                 error = vxlan_encap6(sc, &vxlsa, m);
2505
2506         vxlan_release(sc);
2507         if (mcifp != NULL)
2508                 if_rele(mcifp);
2509
2510         return (error);
2511 }
2512
2513 static void
2514 vxlan_qflush(struct ifnet *ifp __unused)
2515 {
2516 }
2517
2518 static void
2519 vxlan_rcv_udp_packet(struct mbuf *m, int offset, struct inpcb *inpcb,
2520     const struct sockaddr *srcsa, void *xvso)
2521 {
2522         struct vxlan_socket *vso;
2523         struct vxlan_header *vxh, vxlanhdr;
2524         uint32_t vni;
2525         int error __unused;
2526
2527         M_ASSERTPKTHDR(m);
2528         vso = xvso;
2529         offset += sizeof(struct udphdr);
2530
2531         if (m->m_pkthdr.len < offset + sizeof(struct vxlan_header))
2532                 goto out;
2533
2534         if (__predict_false(m->m_len < offset + sizeof(struct vxlan_header))) {
2535                 m_copydata(m, offset, sizeof(struct vxlan_header),
2536                     (caddr_t) &vxlanhdr);
2537                 vxh = &vxlanhdr;
2538         } else
2539                 vxh = mtodo(m, offset);
2540
2541         /*
2542          * Drop if there is a reserved bit set in either the flags or VNI
2543          * fields of the header. This goes against the specification, but
2544          * a bit set may indicate an unsupported new feature. This matches
2545          * the behavior of the Linux implementation.
2546          */
2547         if (vxh->vxlh_flags != htonl(VXLAN_HDR_FLAGS_VALID_VNI) ||
2548             vxh->vxlh_vni & ~htonl(VXLAN_VNI_MASK))
2549                 goto out;
2550
2551         vni = ntohl(vxh->vxlh_vni) >> VXLAN_HDR_VNI_SHIFT;
2552         /* Adjust to the start of the inner Ethernet frame. */
2553         m_adj(m, offset + sizeof(struct vxlan_header));
2554
2555         error = vxlan_input(vso, vni, &m, srcsa);
2556         MPASS(error != 0 || m == NULL);
2557
2558 out:
2559         if (m != NULL)
2560                 m_freem(m);
2561 }
2562
2563 static int
2564 vxlan_input(struct vxlan_socket *vso, uint32_t vni, struct mbuf **m0,
2565     const struct sockaddr *sa)
2566 {
2567         struct vxlan_softc *sc;
2568         struct ifnet *ifp;
2569         struct mbuf *m;
2570         struct ether_header *eh;
2571         int error;
2572
2573         sc = vxlan_socket_lookup_softc(vso, vni);
2574         if (sc == NULL)
2575                 return (ENOENT);
2576
2577         ifp = sc->vxl_ifp;
2578         m = *m0;
2579         eh = mtod(m, struct ether_header *);
2580
2581         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
2582                 error = ENETDOWN;
2583                 goto out;
2584         } else if (ifp == m->m_pkthdr.rcvif) {
2585                 /* XXX Does not catch more complex loops. */
2586                 error = EDEADLK;
2587                 goto out;
2588         }
2589
2590         if (sc->vxl_flags & VXLAN_FLAG_LEARN)
2591                 vxlan_ftable_learn(sc, sa, eh->ether_shost);
2592
2593         m_clrprotoflags(m);
2594         m->m_pkthdr.rcvif = ifp;
2595         M_SETFIB(m, ifp->if_fib);
2596
2597         error = netisr_queue_src(NETISR_ETHER, 0, m);
2598         *m0 = NULL;
2599
2600 out:
2601         vxlan_release(sc);
2602         return (error);
2603 }
2604
2605 static void
2606 vxlan_set_default_config(struct vxlan_softc *sc)
2607 {
2608
2609         sc->vxl_flags |= VXLAN_FLAG_LEARN;
2610
2611         sc->vxl_vni = VXLAN_VNI_MAX;
2612         sc->vxl_ttl = IPDEFTTL;
2613
2614         if (!vxlan_tunable_int(sc, "legacy_port", vxlan_legacy_port)) {
2615                 sc->vxl_src_addr.in4.sin_port = htons(VXLAN_PORT);
2616                 sc->vxl_dst_addr.in4.sin_port = htons(VXLAN_PORT);
2617         } else {
2618                 sc->vxl_src_addr.in4.sin_port = htons(VXLAN_LEGACY_PORT);
2619                 sc->vxl_dst_addr.in4.sin_port = htons(VXLAN_LEGACY_PORT);
2620         }
2621
2622         sc->vxl_min_port = V_ipport_firstauto;
2623         sc->vxl_max_port = V_ipport_lastauto;
2624
2625         sc->vxl_ftable_max = VXLAN_FTABLE_MAX;
2626         sc->vxl_ftable_timeout = VXLAN_FTABLE_TIMEOUT;
2627 }
2628
2629 static int
2630 vxlan_set_user_config(struct vxlan_softc *sc, struct ifvxlanparam *vxlp)
2631 {
2632
2633 #ifndef INET
2634         if (vxlp->vxlp_with & (VXLAN_PARAM_WITH_LOCAL_ADDR4 |
2635             VXLAN_PARAM_WITH_REMOTE_ADDR4))
2636                 return (EAFNOSUPPORT);
2637 #endif
2638
2639 #ifndef INET6
2640         if (vxlp->vxlp_with & (VXLAN_PARAM_WITH_LOCAL_ADDR6 |
2641             VXLAN_PARAM_WITH_REMOTE_ADDR6))
2642                 return (EAFNOSUPPORT);
2643 #else
2644         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR6) {
2645                 int error = vxlan_sockaddr_in6_embedscope(&vxlp->vxlp_local_sa);
2646                 if (error)
2647                         return (error);
2648         }
2649         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR6) {
2650                 int error = vxlan_sockaddr_in6_embedscope(
2651                    &vxlp->vxlp_remote_sa);
2652                 if (error)
2653                         return (error);
2654         }
2655 #endif
2656
2657         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_VNI) {
2658                 if (vxlan_check_vni(vxlp->vxlp_vni) == 0)
2659                         sc->vxl_vni = vxlp->vxlp_vni;
2660         }
2661
2662         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR4) {
2663                 sc->vxl_src_addr.in4.sin_len = sizeof(struct sockaddr_in);
2664                 sc->vxl_src_addr.in4.sin_family = AF_INET;
2665                 sc->vxl_src_addr.in4.sin_addr =
2666                     vxlp->vxlp_local_sa.in4.sin_addr;
2667         } else if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR6) {
2668                 sc->vxl_src_addr.in6.sin6_len = sizeof(struct sockaddr_in6);
2669                 sc->vxl_src_addr.in6.sin6_family = AF_INET6;
2670                 sc->vxl_src_addr.in6.sin6_addr =
2671                     vxlp->vxlp_local_sa.in6.sin6_addr;
2672         }
2673
2674         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR4) {
2675                 sc->vxl_dst_addr.in4.sin_len = sizeof(struct sockaddr_in);
2676                 sc->vxl_dst_addr.in4.sin_family = AF_INET;
2677                 sc->vxl_dst_addr.in4.sin_addr =
2678                     vxlp->vxlp_remote_sa.in4.sin_addr;
2679         } else if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR6) {
2680                 sc->vxl_dst_addr.in6.sin6_len = sizeof(struct sockaddr_in6);
2681                 sc->vxl_dst_addr.in6.sin6_family = AF_INET6;
2682                 sc->vxl_dst_addr.in6.sin6_addr =
2683                     vxlp->vxlp_remote_sa.in6.sin6_addr;
2684         }
2685
2686         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_PORT)
2687                 sc->vxl_src_addr.in4.sin_port = htons(vxlp->vxlp_local_port);
2688         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_PORT)
2689                 sc->vxl_dst_addr.in4.sin_port = htons(vxlp->vxlp_remote_port);
2690
2691         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_PORT_RANGE) {
2692                 if (vxlp->vxlp_min_port <= vxlp->vxlp_max_port) {
2693                         sc->vxl_min_port = vxlp->vxlp_min_port;
2694                         sc->vxl_max_port = vxlp->vxlp_max_port;
2695                 }
2696         }
2697
2698         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_MULTICAST_IF)
2699                 strlcpy(sc->vxl_mc_ifname, vxlp->vxlp_mc_ifname, IFNAMSIZ);
2700
2701         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_FTABLE_TIMEOUT) {
2702                 if (vxlan_check_ftable_timeout(vxlp->vxlp_ftable_timeout) == 0)
2703                         sc->vxl_ftable_timeout = vxlp->vxlp_ftable_timeout;
2704         }
2705
2706         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_FTABLE_MAX) {
2707                 if (vxlan_check_ftable_max(vxlp->vxlp_ftable_max) == 0)
2708                         sc->vxl_ftable_max = vxlp->vxlp_ftable_max;
2709         }
2710
2711         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_TTL) {
2712                 if (vxlan_check_ttl(vxlp->vxlp_ttl) == 0)
2713                         sc->vxl_ttl = vxlp->vxlp_ttl;
2714         }
2715
2716         if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LEARN) {
2717                 if (vxlp->vxlp_learn == 0)
2718                         sc->vxl_flags &= ~VXLAN_FLAG_LEARN;
2719         }
2720
2721         return (0);
2722 }
2723
2724 static int
2725 vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
2726 {
2727         struct vxlan_softc *sc;
2728         struct ifnet *ifp;
2729         struct ifvxlanparam vxlp;
2730         int error;
2731
2732         sc = malloc(sizeof(struct vxlan_softc), M_VXLAN, M_WAITOK | M_ZERO);
2733         sc->vxl_unit = unit;
2734         vxlan_set_default_config(sc);
2735
2736         if (params != 0) {
2737                 error = copyin(params, &vxlp, sizeof(vxlp));
2738                 if (error)
2739                         goto fail;
2740
2741                 error = vxlan_set_user_config(sc, &vxlp);
2742                 if (error)
2743                         goto fail;
2744         }
2745
2746         ifp = if_alloc(IFT_ETHER);
2747         if (ifp == NULL) {
2748                 error = ENOSPC;
2749                 goto fail;
2750         }
2751
2752         sc->vxl_ifp = ifp;
2753         rm_init(&sc->vxl_lock, "vxlanrm");
2754         callout_init_rw(&sc->vxl_callout, &sc->vxl_lock, 0);
2755         sc->vxl_port_hash_key = arc4random();
2756         vxlan_ftable_init(sc);
2757
2758         vxlan_sysctl_setup(sc);
2759
2760         ifp->if_softc = sc;
2761         if_initname(ifp, vxlan_name, unit);
2762         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
2763         ifp->if_init = vxlan_init;
2764         ifp->if_ioctl = vxlan_ioctl;
2765         ifp->if_transmit = vxlan_transmit;
2766         ifp->if_qflush = vxlan_qflush;
2767         ifp->if_capabilities |= IFCAP_LINKSTATE | IFCAP_JUMBO_MTU;
2768         ifp->if_capenable |= IFCAP_LINKSTATE | IFCAP_JUMBO_MTU;
2769
2770         ifmedia_init(&sc->vxl_media, 0, vxlan_media_change, vxlan_media_status);
2771         ifmedia_add(&sc->vxl_media, IFM_ETHER | IFM_AUTO, 0, NULL);
2772         ifmedia_set(&sc->vxl_media, IFM_ETHER | IFM_AUTO);
2773
2774         ether_gen_addr(ifp, &sc->vxl_hwaddr);
2775         ether_ifattach(ifp, sc->vxl_hwaddr.octet);
2776
2777         ifp->if_baudrate = 0;
2778         ifp->if_hdrlen = 0;
2779
2780         return (0);
2781
2782 fail:
2783         free(sc, M_VXLAN);
2784         return (error);
2785 }
2786
2787 static void
2788 vxlan_clone_destroy(struct ifnet *ifp)
2789 {
2790         struct vxlan_softc *sc;
2791
2792         sc = ifp->if_softc;
2793
2794         vxlan_teardown(sc);
2795
2796         vxlan_ftable_flush(sc, 1);
2797
2798         ether_ifdetach(ifp);
2799         if_free(ifp);
2800         ifmedia_removeall(&sc->vxl_media);
2801
2802         vxlan_ftable_fini(sc);
2803
2804         vxlan_sysctl_destroy(sc);
2805         rm_destroy(&sc->vxl_lock);
2806         free(sc, M_VXLAN);
2807 }
2808
2809 /* BMV: Taken from if_bridge. */
2810 static uint32_t
2811 vxlan_mac_hash(struct vxlan_softc *sc, const uint8_t *addr)
2812 {
2813         uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->vxl_ftable_hash_key;
2814
2815         b += addr[5] << 8;
2816         b += addr[4];
2817         a += addr[3] << 24;
2818         a += addr[2] << 16;
2819         a += addr[1] << 8;
2820         a += addr[0];
2821
2822 /*
2823  * The following hash function is adapted from "Hash Functions" by Bob Jenkins
2824  * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
2825  */
2826 #define mix(a, b, c)                                                    \
2827 do {                                                                    \
2828         a -= b; a -= c; a ^= (c >> 13);                                 \
2829         b -= c; b -= a; b ^= (a << 8);                                  \
2830         c -= a; c -= b; c ^= (b >> 13);                                 \
2831         a -= b; a -= c; a ^= (c >> 12);                                 \
2832         b -= c; b -= a; b ^= (a << 16);                                 \
2833         c -= a; c -= b; c ^= (b >> 5);                                  \
2834         a -= b; a -= c; a ^= (c >> 3);                                  \
2835         b -= c; b -= a; b ^= (a << 10);                                 \
2836         c -= a; c -= b; c ^= (b >> 15);                                 \
2837 } while (0)
2838
2839         mix(a, b, c);
2840
2841 #undef mix
2842
2843         return (c);
2844 }
2845
2846 static int
2847 vxlan_media_change(struct ifnet *ifp)
2848 {
2849
2850         /* Ignore. */
2851         return (0);
2852 }
2853
2854 static void
2855 vxlan_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
2856 {
2857
2858         ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
2859         ifmr->ifm_active = IFM_ETHER | IFM_FDX;
2860 }
2861
2862 static int
2863 vxlan_sockaddr_cmp(const union vxlan_sockaddr *vxladdr,
2864     const struct sockaddr *sa)
2865 {
2866
2867         return (bcmp(&vxladdr->sa, sa, vxladdr->sa.sa_len));
2868 }
2869
2870 static void
2871 vxlan_sockaddr_copy(union vxlan_sockaddr *vxladdr,
2872     const struct sockaddr *sa)
2873 {
2874
2875         MPASS(sa->sa_family == AF_INET || sa->sa_family == AF_INET6);
2876         bzero(vxladdr, sizeof(*vxladdr));
2877
2878         if (sa->sa_family == AF_INET) {
2879                 vxladdr->in4 = *satoconstsin(sa);
2880                 vxladdr->in4.sin_len = sizeof(struct sockaddr_in);
2881         } else if (sa->sa_family == AF_INET6) {
2882                 vxladdr->in6 = *satoconstsin6(sa);
2883                 vxladdr->in6.sin6_len = sizeof(struct sockaddr_in6);
2884         }
2885 }
2886
2887 static int
2888 vxlan_sockaddr_in_equal(const union vxlan_sockaddr *vxladdr,
2889     const struct sockaddr *sa)
2890 {
2891         int equal;
2892
2893         if (sa->sa_family == AF_INET) {
2894                 const struct in_addr *in4 = &satoconstsin(sa)->sin_addr;
2895                 equal = in4->s_addr == vxladdr->in4.sin_addr.s_addr;
2896         } else if (sa->sa_family == AF_INET6) {
2897                 const struct in6_addr *in6 = &satoconstsin6(sa)->sin6_addr;
2898                 equal = IN6_ARE_ADDR_EQUAL(in6, &vxladdr->in6.sin6_addr);
2899         } else
2900                 equal = 0;
2901
2902         return (equal);
2903 }
2904
2905 static void
2906 vxlan_sockaddr_in_copy(union vxlan_sockaddr *vxladdr,
2907     const struct sockaddr *sa)
2908 {
2909
2910         MPASS(sa->sa_family == AF_INET || sa->sa_family == AF_INET6);
2911
2912         if (sa->sa_family == AF_INET) {
2913                 const struct in_addr *in4 = &satoconstsin(sa)->sin_addr;
2914                 vxladdr->in4.sin_family = AF_INET;
2915                 vxladdr->in4.sin_len = sizeof(struct sockaddr_in);
2916                 vxladdr->in4.sin_addr = *in4;
2917         } else if (sa->sa_family == AF_INET6) {
2918                 const struct in6_addr *in6 = &satoconstsin6(sa)->sin6_addr;
2919                 vxladdr->in6.sin6_family = AF_INET6;
2920                 vxladdr->in6.sin6_len = sizeof(struct sockaddr_in6);
2921                 vxladdr->in6.sin6_addr = *in6;
2922         }
2923 }
2924
2925 static int
2926 vxlan_sockaddr_supported(const union vxlan_sockaddr *vxladdr, int unspec)
2927 {
2928         const struct sockaddr *sa;
2929         int supported;
2930
2931         sa = &vxladdr->sa;
2932         supported = 0;
2933
2934         if (sa->sa_family == AF_UNSPEC && unspec != 0) {
2935                 supported = 1;
2936         } else if (sa->sa_family == AF_INET) {
2937 #ifdef INET
2938                 supported = 1;
2939 #endif
2940         } else if (sa->sa_family == AF_INET6) {
2941 #ifdef INET6
2942                 supported = 1;
2943 #endif
2944         }
2945
2946         return (supported);
2947 }
2948
2949 static int
2950 vxlan_sockaddr_in_any(const union vxlan_sockaddr *vxladdr)
2951 {
2952         const struct sockaddr *sa;
2953         int any;
2954
2955         sa = &vxladdr->sa;
2956
2957         if (sa->sa_family == AF_INET) {
2958                 const struct in_addr *in4 = &satoconstsin(sa)->sin_addr;
2959                 any = in4->s_addr == INADDR_ANY;
2960         } else if (sa->sa_family == AF_INET6) {
2961                 const struct in6_addr *in6 = &satoconstsin6(sa)->sin6_addr;
2962                 any = IN6_IS_ADDR_UNSPECIFIED(in6);
2963         } else
2964                 any = -1;
2965
2966         return (any);
2967 }
2968
2969 static int
2970 vxlan_sockaddr_in_multicast(const union vxlan_sockaddr *vxladdr)
2971 {
2972         const struct sockaddr *sa;
2973         int mc;
2974
2975         sa = &vxladdr->sa;
2976
2977         if (sa->sa_family == AF_INET) {
2978                 const struct in_addr *in4 = &satoconstsin(sa)->sin_addr;
2979                 mc = IN_MULTICAST(ntohl(in4->s_addr));
2980         } else if (sa->sa_family == AF_INET6) {
2981                 const struct in6_addr *in6 = &satoconstsin6(sa)->sin6_addr;
2982                 mc = IN6_IS_ADDR_MULTICAST(in6);
2983         } else
2984                 mc = -1;
2985
2986         return (mc);
2987 }
2988
2989 static int
2990 vxlan_sockaddr_in6_embedscope(union vxlan_sockaddr *vxladdr)
2991 {
2992         int error;
2993
2994         MPASS(VXLAN_SOCKADDR_IS_IPV6(vxladdr));
2995 #ifdef INET6
2996         error = sa6_embedscope(&vxladdr->in6, V_ip6_use_defzone);
2997 #else
2998         error = EAFNOSUPPORT;
2999 #endif
3000
3001         return (error);
3002 }
3003
3004 static int
3005 vxlan_can_change_config(struct vxlan_softc *sc)
3006 {
3007         struct ifnet *ifp;
3008
3009         ifp = sc->vxl_ifp;
3010         VXLAN_LOCK_ASSERT(sc);
3011
3012         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
3013                 return (0);
3014         if (sc->vxl_flags & (VXLAN_FLAG_INIT | VXLAN_FLAG_TEARDOWN))
3015                 return (0);
3016
3017         return (1);
3018 }
3019
3020 static int
3021 vxlan_check_vni(uint32_t vni)
3022 {
3023
3024         return (vni >= VXLAN_VNI_MAX);
3025 }
3026
3027 static int
3028 vxlan_check_ttl(int ttl)
3029 {
3030
3031         return (ttl > MAXTTL);
3032 }
3033
3034 static int
3035 vxlan_check_ftable_timeout(uint32_t timeout)
3036 {
3037
3038         return (timeout > VXLAN_FTABLE_MAX_TIMEOUT);
3039 }
3040
3041 static int
3042 vxlan_check_ftable_max(uint32_t max)
3043 {
3044
3045         return (max > VXLAN_FTABLE_MAX);
3046 }
3047
3048 static void
3049 vxlan_sysctl_setup(struct vxlan_softc *sc)
3050 {
3051         struct sysctl_ctx_list *ctx;
3052         struct sysctl_oid *node;
3053         struct vxlan_statistics *stats;
3054         char namebuf[8];
3055
3056         ctx = &sc->vxl_sysctl_ctx;
3057         stats = &sc->vxl_stats;
3058         snprintf(namebuf, sizeof(namebuf), "%d", sc->vxl_unit);
3059
3060         sysctl_ctx_init(ctx);
3061         sc->vxl_sysctl_node = SYSCTL_ADD_NODE(ctx,
3062             SYSCTL_STATIC_CHILDREN(_net_link_vxlan), OID_AUTO, namebuf,
3063             CTLFLAG_RD, NULL, "");
3064
3065         node = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(sc->vxl_sysctl_node),
3066             OID_AUTO, "ftable", CTLFLAG_RD, NULL, "");
3067         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(node), OID_AUTO, "count",
3068             CTLFLAG_RD, &sc->vxl_ftable_cnt, 0,
3069             "Number of entries in fowarding table");
3070         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(node), OID_AUTO, "max",
3071              CTLFLAG_RD, &sc->vxl_ftable_max, 0,
3072             "Maximum number of entries allowed in fowarding table");
3073         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(node), OID_AUTO, "timeout",
3074             CTLFLAG_RD, &sc->vxl_ftable_timeout, 0,
3075             "Number of seconds between prunes of the forwarding table");
3076         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(node), OID_AUTO, "dump",
3077             CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_SKIP,
3078             sc, 0, vxlan_ftable_sysctl_dump, "A",
3079             "Dump the forwarding table entries");
3080
3081         node = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(sc->vxl_sysctl_node),
3082             OID_AUTO, "stats", CTLFLAG_RD, NULL, "");
3083         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(node), OID_AUTO,
3084             "ftable_nospace", CTLFLAG_RD, &stats->ftable_nospace, 0,
3085             "Fowarding table reached maximum entries");
3086         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(node), OID_AUTO,
3087             "ftable_lock_upgrade_failed", CTLFLAG_RD,
3088             &stats->ftable_lock_upgrade_failed, 0,
3089             "Forwarding table update required lock upgrade");
3090 }
3091
3092 static void
3093 vxlan_sysctl_destroy(struct vxlan_softc *sc)
3094 {
3095
3096         sysctl_ctx_free(&sc->vxl_sysctl_ctx);
3097         sc->vxl_sysctl_node = NULL;
3098 }
3099
3100 static int
3101 vxlan_tunable_int(struct vxlan_softc *sc, const char *knob, int def)
3102 {
3103         char path[64];
3104
3105         snprintf(path, sizeof(path), "net.link.vxlan.%d.%s",
3106             sc->vxl_unit, knob);
3107         TUNABLE_INT_FETCH(path, &def);
3108
3109         return (def);
3110 }
3111
3112 static void
3113 vxlan_ifdetach_event(void *arg __unused, struct ifnet *ifp)
3114 {
3115         struct vxlan_softc_head list;
3116         struct vxlan_socket *vso;
3117         struct vxlan_softc *sc, *tsc;
3118
3119         LIST_INIT(&list);
3120
3121         if (ifp->if_flags & IFF_RENAMING)
3122                 return;
3123         if ((ifp->if_flags & IFF_MULTICAST) == 0)
3124                 return;
3125
3126         VXLAN_LIST_LOCK();
3127         LIST_FOREACH(vso, &vxlan_socket_list, vxlso_entry)
3128                 vxlan_socket_ifdetach(vso, ifp, &list);
3129         VXLAN_LIST_UNLOCK();
3130
3131         LIST_FOREACH_SAFE(sc, &list, vxl_ifdetach_list, tsc) {
3132                 LIST_REMOVE(sc, vxl_ifdetach_list);
3133
3134                 VXLAN_WLOCK(sc);
3135                 if (sc->vxl_flags & VXLAN_FLAG_INIT)
3136                         vxlan_init_wait(sc);
3137                 vxlan_teardown_locked(sc);
3138         }
3139 }
3140
3141 static void
3142 vxlan_load(void)
3143 {
3144
3145         mtx_init(&vxlan_list_mtx, "vxlan list", NULL, MTX_DEF);
3146         LIST_INIT(&vxlan_socket_list);
3147         vxlan_ifdetach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event,
3148             vxlan_ifdetach_event, NULL, EVENTHANDLER_PRI_ANY);
3149         vxlan_cloner = if_clone_simple(vxlan_name, vxlan_clone_create,
3150             vxlan_clone_destroy, 0);
3151 }
3152
3153 static void
3154 vxlan_unload(void)
3155 {
3156
3157         EVENTHANDLER_DEREGISTER(ifnet_departure_event,
3158             vxlan_ifdetach_event_tag);
3159         if_clone_detach(vxlan_cloner);
3160         mtx_destroy(&vxlan_list_mtx);
3161         MPASS(LIST_EMPTY(&vxlan_socket_list));
3162 }
3163
3164 static int
3165 vxlan_modevent(module_t mod, int type, void *unused)
3166 {
3167         int error;
3168
3169         error = 0;
3170
3171         switch (type) {
3172         case MOD_LOAD:
3173                 vxlan_load();
3174                 break;
3175         case MOD_UNLOAD:
3176                 vxlan_unload();
3177                 break;
3178         default:
3179                 error = ENOTSUP;
3180                 break;
3181         }
3182
3183         return (error);
3184 }
3185
3186 static moduledata_t vxlan_mod = {
3187         "if_vxlan",
3188         vxlan_modevent,
3189         0
3190 };
3191
3192 DECLARE_MODULE(if_vxlan, vxlan_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
3193 MODULE_VERSION(if_vxlan, 1);