]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/ifconfig/ifvxlan.c
Merge llvm, clang, lld, lldb, compiler-rt and libc++ trunk r321545,
[FreeBSD/FreeBSD.git] / sbin / ifconfig / ifvxlan.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 <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/param.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33 #include <sys/sockio.h>
34
35 #include <stdlib.h>
36 #include <stdint.h>
37 #include <unistd.h>
38 #include <netdb.h>
39
40 #include <net/ethernet.h>
41 #include <net/if.h>
42 #include <net/if_vxlan.h>
43 #include <net/route.h>
44 #include <netinet/in.h>
45
46 #include <ctype.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <stdlib.h>
50 #include <unistd.h>
51 #include <err.h>
52 #include <errno.h>
53
54 #include "ifconfig.h"
55
56 static struct ifvxlanparam params = {
57         .vxlp_vni       = VXLAN_VNI_MAX,
58 };
59
60 static int
61 get_val(const char *cp, u_long *valp)
62 {
63         char *endptr;
64         u_long val;
65
66         errno = 0;
67         val = strtoul(cp, &endptr, 0);
68         if (cp[0] == '\0' || endptr[0] != '\0' || errno == ERANGE)
69                 return (-1);
70
71         *valp = val;
72         return (0);
73 }
74
75 static int
76 do_cmd(int sock, u_long op, void *arg, size_t argsize, int set)
77 {
78         struct ifdrv ifd;
79
80         bzero(&ifd, sizeof(ifd));
81
82         strlcpy(ifd.ifd_name, ifr.ifr_name, sizeof(ifd.ifd_name));
83         ifd.ifd_cmd = op;
84         ifd.ifd_len = argsize;
85         ifd.ifd_data = arg;
86
87         return (ioctl(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd));
88 }
89
90 static int
91 vxlan_exists(int sock)
92 {
93         struct ifvxlancfg cfg;
94
95         bzero(&cfg, sizeof(cfg));
96
97         return (do_cmd(sock, VXLAN_CMD_GET_CONFIG, &cfg, sizeof(cfg), 0) != -1);
98 }
99
100 static void
101 vxlan_status(int s)
102 {
103         struct ifvxlancfg cfg;
104         char src[NI_MAXHOST], dst[NI_MAXHOST];
105         char srcport[NI_MAXSERV], dstport[NI_MAXSERV];
106         struct sockaddr *lsa, *rsa;
107         int vni, mc, ipv6;
108
109         bzero(&cfg, sizeof(cfg));
110
111         if (do_cmd(s, VXLAN_CMD_GET_CONFIG, &cfg, sizeof(cfg), 0) < 0)
112                 return;
113
114         vni = cfg.vxlc_vni;
115         lsa = &cfg.vxlc_local_sa.sa;
116         rsa = &cfg.vxlc_remote_sa.sa;
117         ipv6 = rsa->sa_family == AF_INET6;
118
119         /* Just report nothing if the network identity isn't set yet. */
120         if (vni >= VXLAN_VNI_MAX)
121                 return;
122
123         if (getnameinfo(lsa, lsa->sa_len, src, sizeof(src),
124             srcport, sizeof(srcport), NI_NUMERICHOST | NI_NUMERICSERV) != 0)
125                 src[0] = srcport[0] = '\0';
126         if (getnameinfo(rsa, rsa->sa_len, dst, sizeof(dst),
127             dstport, sizeof(dstport), NI_NUMERICHOST | NI_NUMERICSERV) != 0)
128                 dst[0] = dstport[0] = '\0';
129
130         if (!ipv6) {
131                 struct sockaddr_in *sin = (struct sockaddr_in *)rsa;
132                 mc = IN_MULTICAST(ntohl(sin->sin_addr.s_addr));
133         } else {
134                 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rsa;
135                 mc = IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr);
136         }
137
138         printf("\tvxlan vni %d", vni);
139         printf(" local %s%s%s:%s", ipv6 ? "[" : "", src, ipv6 ? "]" : "",
140             srcport);
141         printf(" %s %s%s%s:%s", mc ? "group" : "remote", ipv6 ? "[" : "",
142             dst, ipv6 ? "]" : "", dstport);
143
144         if (verbose) {
145                 printf("\n\t\tconfig: ");
146                 printf("%slearning portrange %d-%d ttl %d",
147                     cfg.vxlc_learn ? "" : "no", cfg.vxlc_port_min,
148                     cfg.vxlc_port_max, cfg.vxlc_ttl);
149                 printf("\n\t\tftable: ");
150                 printf("cnt %d max %d timeout %d",
151                     cfg.vxlc_ftable_cnt, cfg.vxlc_ftable_max,
152                     cfg.vxlc_ftable_timeout);
153         }
154
155         putchar('\n');
156 }
157
158 #define _LOCAL_ADDR46 \
159     (VXLAN_PARAM_WITH_LOCAL_ADDR4 | VXLAN_PARAM_WITH_LOCAL_ADDR6)
160 #define _REMOTE_ADDR46 \
161     (VXLAN_PARAM_WITH_REMOTE_ADDR4 | VXLAN_PARAM_WITH_REMOTE_ADDR6)
162
163 static void
164 vxlan_check_params(void)
165 {
166
167         if ((params.vxlp_with & _LOCAL_ADDR46) == _LOCAL_ADDR46)
168                 errx(1, "cannot specify both local IPv4 and IPv6 addresses");
169         if ((params.vxlp_with & _REMOTE_ADDR46) == _REMOTE_ADDR46)
170                 errx(1, "cannot specify both remote IPv4 and IPv6 addresses");
171         if ((params.vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR4 &&
172              params.vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR6) ||
173             (params.vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR6 &&
174              params.vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR4))
175                 errx(1, "cannot mix IPv4 and IPv6 addresses");
176 }
177
178 #undef _LOCAL_ADDR46
179 #undef _REMOTE_ADDR46
180
181 static void
182 vxlan_cb(int s, void *arg)
183 {
184
185 }
186
187 static void
188 vxlan_create(int s, struct ifreq *ifr)
189 {
190
191         vxlan_check_params();
192
193         ifr->ifr_data = (caddr_t) &params;
194         if (ioctl(s, SIOCIFCREATE2, ifr) < 0)
195                 err(1, "SIOCIFCREATE2");
196 }
197
198 static
199 DECL_CMD_FUNC(setvxlan_vni, arg, d)
200 {
201         struct ifvxlancmd cmd;
202         u_long val;
203
204         if (get_val(arg, &val) < 0 || val >= VXLAN_VNI_MAX)
205                 errx(1, "invalid network identifier: %s", arg);
206
207         if (!vxlan_exists(s)) {
208                 params.vxlp_with |= VXLAN_PARAM_WITH_VNI;
209                 params.vxlp_vni = val;
210                 return;
211         }
212
213         bzero(&cmd, sizeof(cmd));
214         cmd.vxlcmd_vni = val;
215
216         if (do_cmd(s, VXLAN_CMD_SET_VNI, &cmd, sizeof(cmd), 1) < 0)
217                 err(1, "VXLAN_CMD_SET_VNI");
218 }
219
220 static
221 DECL_CMD_FUNC(setvxlan_local, addr, d)
222 {
223         struct ifvxlancmd cmd;
224         struct addrinfo *ai;
225         struct sockaddr *sa;
226         int error;
227
228         bzero(&cmd, sizeof(cmd));
229
230         if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
231                 errx(1, "error in parsing local address string: %s",
232                     gai_strerror(error));
233
234         sa = ai->ai_addr;
235
236         switch (ai->ai_family) {
237 #ifdef INET
238         case AF_INET: {
239                 struct in_addr addr = ((struct sockaddr_in *) sa)->sin_addr;
240
241                 if (IN_MULTICAST(ntohl(addr.s_addr)))
242                         errx(1, "local address cannot be multicast");
243
244                 cmd.vxlcmd_sa.in4.sin_family = AF_INET;
245                 cmd.vxlcmd_sa.in4.sin_addr = addr;
246                 break;
247         }
248 #endif
249 #ifdef INET6
250         case AF_INET6: {
251                 struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
252
253                 if (IN6_IS_ADDR_MULTICAST(addr))
254                         errx(1, "local address cannot be multicast");
255
256                 cmd.vxlcmd_sa.in6.sin6_family = AF_INET6;
257                 cmd.vxlcmd_sa.in6.sin6_addr = *addr;
258                 break;
259         }
260 #endif
261         default:
262                 errx(1, "local address %s not supported", addr);
263         }
264
265         freeaddrinfo(ai);
266
267         if (!vxlan_exists(s)) {
268                 if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
269                         params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_ADDR4;
270                         params.vxlp_local_in4 = cmd.vxlcmd_sa.in4.sin_addr;
271                 } else {
272                         params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_ADDR6;
273                         params.vxlp_local_in6 = cmd.vxlcmd_sa.in6.sin6_addr;
274                 }
275                 return;
276         }
277
278         if (do_cmd(s, VXLAN_CMD_SET_LOCAL_ADDR, &cmd, sizeof(cmd), 1) < 0)
279                 err(1, "VXLAN_CMD_SET_LOCAL_ADDR");
280 }
281
282 static
283 DECL_CMD_FUNC(setvxlan_remote, addr, d)
284 {
285         struct ifvxlancmd cmd;
286         struct addrinfo *ai;
287         struct sockaddr *sa;
288         int error;
289
290         bzero(&cmd, sizeof(cmd));
291
292         if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
293                 errx(1, "error in parsing remote address string: %s",
294                     gai_strerror(error));
295
296         sa = ai->ai_addr;
297
298         switch (ai->ai_family) {
299 #ifdef INET
300         case AF_INET: {
301                 struct in_addr addr = ((struct sockaddr_in *)sa)->sin_addr;
302
303                 if (IN_MULTICAST(ntohl(addr.s_addr)))
304                         errx(1, "remote address cannot be multicast");
305
306                 cmd.vxlcmd_sa.in4.sin_family = AF_INET;
307                 cmd.vxlcmd_sa.in4.sin_addr = addr;
308                 break;
309         }
310 #endif
311 #ifdef INET6
312         case AF_INET6: {
313                 struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
314
315                 if (IN6_IS_ADDR_MULTICAST(addr))
316                         errx(1, "remote address cannot be multicast");
317
318                 cmd.vxlcmd_sa.in6.sin6_family = AF_INET6;
319                 cmd.vxlcmd_sa.in6.sin6_addr = *addr;
320                 break;
321         }
322 #endif
323         default:
324                 errx(1, "remote address %s not supported", addr);
325         }
326
327         freeaddrinfo(ai);
328
329         if (!vxlan_exists(s)) {
330                 if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
331                         params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR4;
332                         params.vxlp_remote_in4 = cmd.vxlcmd_sa.in4.sin_addr;
333                 } else {
334                         params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR6;
335                         params.vxlp_remote_in6 = cmd.vxlcmd_sa.in6.sin6_addr;
336                 }
337                 return;
338         }
339
340         if (do_cmd(s, VXLAN_CMD_SET_REMOTE_ADDR, &cmd, sizeof(cmd), 1) < 0)
341                 err(1, "VXLAN_CMD_SET_REMOTE_ADDR");
342 }
343
344 static
345 DECL_CMD_FUNC(setvxlan_group, addr, d)
346 {
347         struct ifvxlancmd cmd;
348         struct addrinfo *ai;
349         struct sockaddr *sa;
350         int error;
351
352         bzero(&cmd, sizeof(cmd));
353
354         if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
355                 errx(1, "error in parsing group address string: %s",
356                     gai_strerror(error));
357
358         sa = ai->ai_addr;
359
360         switch (ai->ai_family) {
361 #ifdef INET
362         case AF_INET: {
363                 struct in_addr addr = ((struct sockaddr_in *)sa)->sin_addr;
364
365                 if (!IN_MULTICAST(ntohl(addr.s_addr)))
366                         errx(1, "group address must be multicast");
367
368                 cmd.vxlcmd_sa.in4.sin_family = AF_INET;
369                 cmd.vxlcmd_sa.in4.sin_addr = addr;
370                 break;
371         }
372 #endif
373 #ifdef INET6
374         case AF_INET6: {
375                 struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
376
377                 if (!IN6_IS_ADDR_MULTICAST(addr))
378                         errx(1, "group address must be multicast");
379
380                 cmd.vxlcmd_sa.in6.sin6_family = AF_INET6;
381                 cmd.vxlcmd_sa.in6.sin6_addr = *addr;
382                 break;
383         }
384 #endif
385         default:
386                 errx(1, "group address %s not supported", addr);
387         }
388
389         freeaddrinfo(ai);
390
391         if (!vxlan_exists(s)) {
392                 if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
393                         params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR4;
394                         params.vxlp_remote_in4 = cmd.vxlcmd_sa.in4.sin_addr;
395                 } else {
396                         params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR6;
397                         params.vxlp_remote_in6 = cmd.vxlcmd_sa.in6.sin6_addr;
398                 }
399                 return;
400         }
401
402         if (do_cmd(s, VXLAN_CMD_SET_REMOTE_ADDR, &cmd, sizeof(cmd), 1) < 0)
403                 err(1, "VXLAN_CMD_SET_REMOTE_ADDR");
404 }
405
406 static
407 DECL_CMD_FUNC(setvxlan_local_port, arg, d)
408 {
409         struct ifvxlancmd cmd;
410         u_long val;
411
412         if (get_val(arg, &val) < 0 || val >= UINT16_MAX)
413                 errx(1, "invalid local port: %s", arg);
414
415         if (!vxlan_exists(s)) {
416                 params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_PORT;
417                 params.vxlp_local_port = val;
418                 return;
419         }
420
421         bzero(&cmd, sizeof(cmd));
422         cmd.vxlcmd_port = val;
423
424         if (do_cmd(s, VXLAN_CMD_SET_LOCAL_PORT, &cmd, sizeof(cmd), 1) < 0)
425                 err(1, "VXLAN_CMD_SET_LOCAL_PORT");
426 }
427
428 static
429 DECL_CMD_FUNC(setvxlan_remote_port, arg, d)
430 {
431         struct ifvxlancmd cmd;
432         u_long val;
433
434         if (get_val(arg, &val) < 0 || val >= UINT16_MAX)
435                 errx(1, "invalid remote port: %s", arg);
436
437         if (!vxlan_exists(s)) {
438                 params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_PORT;
439                 params.vxlp_remote_port = val;
440                 return;
441         }
442
443         bzero(&cmd, sizeof(cmd));
444         cmd.vxlcmd_port = val;
445
446         if (do_cmd(s, VXLAN_CMD_SET_REMOTE_PORT, &cmd, sizeof(cmd), 1) < 0)
447                 err(1, "VXLAN_CMD_SET_REMOTE_PORT");
448 }
449
450 static
451 DECL_CMD_FUNC2(setvxlan_port_range, arg1, arg2)
452 {
453         struct ifvxlancmd cmd;
454         u_long min, max;
455
456         if (get_val(arg1, &min) < 0 || min >= UINT16_MAX)
457                 errx(1, "invalid port range minimum: %s", arg1);
458         if (get_val(arg2, &max) < 0 || max >= UINT16_MAX)
459                 errx(1, "invalid port range maximum: %s", arg2);
460         if (max < min)
461                 errx(1, "invalid port range");
462
463         if (!vxlan_exists(s)) {
464                 params.vxlp_with |= VXLAN_PARAM_WITH_PORT_RANGE;
465                 params.vxlp_min_port = min;
466                 params.vxlp_max_port = max;
467                 return;
468         }
469
470         bzero(&cmd, sizeof(cmd));
471         cmd.vxlcmd_port_min = min;
472         cmd.vxlcmd_port_max = max;
473
474         if (do_cmd(s, VXLAN_CMD_SET_PORT_RANGE, &cmd, sizeof(cmd), 1) < 0)
475                 err(1, "VXLAN_CMD_SET_PORT_RANGE");
476 }
477
478 static
479 DECL_CMD_FUNC(setvxlan_timeout, arg, d)
480 {
481         struct ifvxlancmd cmd;
482         u_long val;
483
484         if (get_val(arg, &val) < 0 || (val & ~0xFFFFFFFF) != 0)
485                 errx(1, "invalid timeout value: %s", arg);
486
487         if (!vxlan_exists(s)) {
488                 params.vxlp_with |= VXLAN_PARAM_WITH_FTABLE_TIMEOUT;
489                 params.vxlp_ftable_timeout = val & 0xFFFFFFFF;
490                 return;
491         }
492
493         bzero(&cmd, sizeof(cmd));
494         cmd.vxlcmd_ftable_timeout = val & 0xFFFFFFFF;
495
496         if (do_cmd(s, VXLAN_CMD_SET_FTABLE_TIMEOUT, &cmd, sizeof(cmd), 1) < 0)
497                 err(1, "VXLAN_CMD_SET_FTABLE_TIMEOUT");
498 }
499
500 static
501 DECL_CMD_FUNC(setvxlan_maxaddr, arg, d)
502 {
503         struct ifvxlancmd cmd;
504         u_long val;
505
506         if (get_val(arg, &val) < 0 || (val & ~0xFFFFFFFF) != 0)
507                 errx(1, "invalid maxaddr value: %s",  arg);
508
509         if (!vxlan_exists(s)) {
510                 params.vxlp_with |= VXLAN_PARAM_WITH_FTABLE_MAX;
511                 params.vxlp_ftable_max = val & 0xFFFFFFFF;
512                 return;
513         }
514
515         bzero(&cmd, sizeof(cmd));
516         cmd.vxlcmd_ftable_max = val & 0xFFFFFFFF;
517
518         if (do_cmd(s, VXLAN_CMD_SET_FTABLE_MAX, &cmd, sizeof(cmd), 1) < 0)
519                 err(1, "VXLAN_CMD_SET_FTABLE_MAX");
520 }
521
522 static
523 DECL_CMD_FUNC(setvxlan_dev, arg, d)
524 {
525         struct ifvxlancmd cmd;
526
527         if (!vxlan_exists(s)) {
528                 params.vxlp_with |= VXLAN_PARAM_WITH_MULTICAST_IF;
529                 strlcpy(params.vxlp_mc_ifname, arg,
530                     sizeof(params.vxlp_mc_ifname));
531                 return;
532         }
533
534         bzero(&cmd, sizeof(cmd));
535         strlcpy(cmd.vxlcmd_ifname, arg, sizeof(cmd.vxlcmd_ifname));
536
537         if (do_cmd(s, VXLAN_CMD_SET_MULTICAST_IF, &cmd, sizeof(cmd), 1) < 0)
538                 err(1, "VXLAN_CMD_SET_MULTICAST_IF");
539 }
540
541 static
542 DECL_CMD_FUNC(setvxlan_ttl, arg, d)
543 {
544         struct ifvxlancmd cmd;
545         u_long val;
546
547         if (get_val(arg, &val) < 0 || val > 256)
548                 errx(1, "invalid TTL value: %s", arg);
549
550         if (!vxlan_exists(s)) {
551                 params.vxlp_with |= VXLAN_PARAM_WITH_TTL;
552                 params.vxlp_ttl = val;
553                 return;
554         }
555
556         bzero(&cmd, sizeof(cmd));
557         cmd.vxlcmd_ttl = val;
558
559         if (do_cmd(s, VXLAN_CMD_SET_TTL, &cmd, sizeof(cmd), 1) < 0)
560                 err(1, "VXLAN_CMD_SET_TTL");
561 }
562
563 static
564 DECL_CMD_FUNC(setvxlan_learn, arg, d)
565 {
566         struct ifvxlancmd cmd;
567
568         if (!vxlan_exists(s)) {
569                 params.vxlp_with |= VXLAN_PARAM_WITH_LEARN;
570                 params.vxlp_learn = d;
571                 return;
572         }
573
574         bzero(&cmd, sizeof(cmd));
575         if (d != 0)
576                 cmd.vxlcmd_flags |= VXLAN_CMD_FLAG_LEARN;
577
578         if (do_cmd(s, VXLAN_CMD_SET_LEARN, &cmd, sizeof(cmd), 1) < 0)
579                 err(1, "VXLAN_CMD_SET_LEARN");
580 }
581
582 static void
583 setvxlan_flush(const char *val, int d, int s, const struct afswtch *afp)
584 {
585         struct ifvxlancmd cmd;
586
587         bzero(&cmd, sizeof(cmd));
588         if (d != 0)
589                 cmd.vxlcmd_flags |= VXLAN_CMD_FLAG_FLUSH_ALL;
590
591         if (do_cmd(s, VXLAN_CMD_FLUSH, &cmd, sizeof(cmd), 1) < 0)
592                 err(1, "VXLAN_CMD_FLUSH");
593 }
594
595 static struct cmd vxlan_cmds[] = {
596
597         DEF_CLONE_CMD_ARG("vni",                setvxlan_vni),
598         DEF_CLONE_CMD_ARG("vxlanid",            setvxlan_vni),
599         DEF_CLONE_CMD_ARG("vxlanlocal",         setvxlan_local),
600         DEF_CLONE_CMD_ARG("vxlanremote",        setvxlan_remote),
601         DEF_CLONE_CMD_ARG("vxlangroup",         setvxlan_group),
602         DEF_CLONE_CMD_ARG("vxlanlocalport",     setvxlan_local_port),
603         DEF_CLONE_CMD_ARG("vxlanremoteport",    setvxlan_remote_port),
604         DEF_CLONE_CMD_ARG2("vxlanportrange",    setvxlan_port_range),
605         DEF_CLONE_CMD_ARG("vxlantimeout",       setvxlan_timeout),
606         DEF_CLONE_CMD_ARG("vxlanmaxaddr",       setvxlan_maxaddr),
607         DEF_CLONE_CMD_ARG("vxlandev",           setvxlan_dev),
608         DEF_CLONE_CMD_ARG("vxlanttl",           setvxlan_ttl),
609         DEF_CLONE_CMD("vxlanlearn", 1,          setvxlan_learn),
610         DEF_CLONE_CMD("-vxlanlearn", 0,         setvxlan_learn),
611
612         DEF_CMD_ARG("vni",                      setvxlan_vni),
613         DEF_CMD_ARG("vxlanid",                  setvxlan_vni),
614         DEF_CMD_ARG("vxlanlocal",               setvxlan_local),
615         DEF_CMD_ARG("vxlanremote",              setvxlan_remote),
616         DEF_CMD_ARG("vxlangroup",               setvxlan_group),
617         DEF_CMD_ARG("vxlanlocalport",           setvxlan_local_port),
618         DEF_CMD_ARG("vxlanremoteport",          setvxlan_remote_port),
619         DEF_CMD_ARG2("vxlanportrange",          setvxlan_port_range),
620         DEF_CMD_ARG("vxlantimeout",             setvxlan_timeout),
621         DEF_CMD_ARG("vxlanmaxaddr",             setvxlan_maxaddr),
622         DEF_CMD_ARG("vxlandev",                 setvxlan_dev),
623         DEF_CMD_ARG("vxlanttl",                 setvxlan_ttl),
624         DEF_CMD("vxlanlearn", 1,                setvxlan_learn),
625         DEF_CMD("-vxlanlearn", 0,               setvxlan_learn),
626
627         DEF_CMD("vxlanflush", 0,                setvxlan_flush),
628         DEF_CMD("vxlanflushall", 1,             setvxlan_flush),
629 };
630
631 static struct afswtch af_vxlan = {
632         .af_name                = "af_vxlan",
633         .af_af                  = AF_UNSPEC,
634         .af_other_status        = vxlan_status,
635 };
636
637 static __constructor void
638 vxlan_ctor(void)
639 {
640         size_t i;
641
642         for (i = 0; i < nitems(vxlan_cmds); i++)
643                 cmd_register(&vxlan_cmds[i]);
644         af_register(&af_vxlan);
645         callback_register(vxlan_cb, NULL);
646         clone_setdefcallback("vxlan", vxlan_create);
647 }