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