]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-netdev-tunnel.c
man: add man ipv6 flowlabel support for ip6 tunnels
[thirdparty/systemd.git] / src / network / networkd-netdev-tunnel.c
CommitLineData
7951dea2
SS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
855ee1a1 6 Copyright 2014 Susant Sahani
7951dea2
SS
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
7951dea2
SS
22#include <arpa/inet.h>
23#include <net/if.h>
24#include <linux/ip.h>
25#include <linux/if_tunnel.h>
855ee1a1 26#include <linux/ip6_tunnel.h>
7951dea2 27
1c4baffc 28#include "sd-netlink.h"
3be1d7e0 29#include "networkd-netdev-tunnel.h"
0b1831c2 30#include "networkd-link.h"
7951dea2 31#include "util.h"
81577dc2 32#include "missing.h"
6ef892fc 33#include "conf-parser.h"
7951dea2 34
855ee1a1 35#define DEFAULT_TNL_HOP_LIMIT 64
407af9dd 36#define IP6_FLOWINFO_FLOWLABEL htonl(0x000FFFFF)
855ee1a1
SS
37
38static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = {
39 [NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6",
73b23bea 40 [NETDEV_IP6_TNL_MODE_IPIP6] = "ipip6",
855ee1a1
SS
41 [NETDEV_IP6_TNL_MODE_ANYIP6] = "any",
42};
43
44DEFINE_STRING_TABLE_LOOKUP(ip6tnl_mode, Ip6TnlMode);
45DEFINE_CONFIG_PARSE_ENUM(config_parse_ip6tnl_mode, ip6tnl_mode, Ip6TnlMode, "Failed to parse ip6 tunnel Mode");
46
1c4baffc 47static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
aa9f1140 48 Tunnel *t = IPIP(netdev);
7951dea2
SS
49 int r;
50
3be1d7e0 51 assert(netdev);
7951dea2 52 assert(link);
7951dea2 53 assert(m);
aa9f1140
TG
54 assert(t);
55 assert(t->family == AF_INET);
7951dea2 56
1c4baffc 57 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
5289f3ff
SS
58 if (r < 0)
59 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
7951dea2 60
1c4baffc 61 r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
5289f3ff
SS
62 if (r < 0)
63 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
7951dea2 64
1c4baffc 65 r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
5289f3ff
SS
66 if (r < 0)
67 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
7951dea2 68
1c4baffc 69 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
5289f3ff
SS
70 if (r < 0)
71 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
9ae70211 72
1c4baffc 73 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
5289f3ff
SS
74 if (r < 0)
75 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_PMTUDISC attribute: %m");
9243e967 76
7951dea2
SS
77 return r;
78}
79
1c4baffc 80static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
aa9f1140 81 Tunnel *t = SIT(netdev);
abf446af
SS
82 int r;
83
3be1d7e0 84 assert(netdev);
abf446af 85 assert(link);
abf446af 86 assert(m);
aa9f1140
TG
87 assert(t);
88 assert(t->family == AF_INET);
abf446af 89
1c4baffc 90 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
5289f3ff
SS
91 if (r < 0)
92 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
abf446af 93
1c4baffc 94 r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
5289f3ff
SS
95 if (r < 0)
96 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
abf446af 97
1c4baffc 98 r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
5289f3ff
SS
99 if (r < 0)
100 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
abf446af 101
1c4baffc 102 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
5289f3ff
SS
103 if (r < 0)
104 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
a9f434cf 105
1c4baffc 106 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
5289f3ff
SS
107 if (r < 0)
108 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_PMTUDISC attribute: %m");
436b910f 109
abf446af
SS
110 return r;
111}
112
1c4baffc 113static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
1af2536a 114 Tunnel *t;
8bb088c5
SS
115 int r;
116
3be1d7e0 117 assert(netdev);
1af2536a
SS
118
119 if (netdev->kind == NETDEV_KIND_GRE)
5289f3ff 120 t = GRE(netdev);
1af2536a 121 else
5289f3ff 122 t = GRETAP(netdev);
1af2536a 123
aa9f1140
TG
124 assert(t);
125 assert(t->family == AF_INET);
1af2536a
SS
126 assert(link);
127 assert(m);
8bb088c5 128
1c4baffc 129 r = sd_netlink_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
5289f3ff
SS
130 if (r < 0)
131 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LINK attribute: %m");
8bb088c5 132
1c4baffc 133 r = sd_netlink_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
5289f3ff
SS
134 if (r < 0)
135 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LOCAL attribute: %m");
8bb088c5 136
1c4baffc 137 r = sd_netlink_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
5289f3ff
SS
138 if (r < 0)
139 log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_REMOTE attribute: %m");
8bb088c5 140
1c4baffc 141 r = sd_netlink_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
5289f3ff
SS
142 if (r < 0)
143 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_TTL attribute: %m");
8bb088c5 144
1c4baffc 145 r = sd_netlink_message_append_u8(m, IFLA_GRE_TOS, t->tos);
5289f3ff
SS
146 if (r < 0)
147 log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_TOS attribute: %m");
8bb088c5 148
1c4baffc 149 r = sd_netlink_message_append_u8(m, IFLA_GRE_PMTUDISC, t->pmtudisc);
5289f3ff
SS
150 if (r < 0)
151 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_PMTUDISC attribute: %m");
9243e967 152
8bb088c5
SS
153 return r;
154}
155
1c4baffc 156static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
b16492f8
SS
157 Tunnel *t;
158 int r;
159
160 assert(netdev);
161
162 if (netdev->kind == NETDEV_KIND_IP6GRE)
5289f3ff 163 t = IP6GRE(netdev);
b16492f8 164 else
5289f3ff 165 t = IP6GRETAP(netdev);
b16492f8
SS
166
167 assert(t);
168 assert(t->family == AF_INET6);
169 assert(link);
170 assert(m);
171
1c4baffc 172 r = sd_netlink_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
5289f3ff
SS
173 if (r < 0)
174 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LINK attribute: %m");
b16492f8 175
1c4baffc 176 r = sd_netlink_message_append_in6_addr(m, IFLA_GRE_LOCAL, &t->local.in6);
5289f3ff
SS
177 if (r < 0)
178 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LOCAL attribute: %m");
b16492f8 179
1c4baffc 180 r = sd_netlink_message_append_in6_addr(m, IFLA_GRE_REMOTE, &t->remote.in6);
5289f3ff
SS
181 if (r < 0)
182 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_REMOTE attribute: %m");
b16492f8 183
1c4baffc 184 r = sd_netlink_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
5289f3ff
SS
185 if (r < 0)
186 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_TTL attribute: %m");
b16492f8
SS
187
188 return r;
189}
190
1c4baffc 191static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
aa9f1140 192 Tunnel *t = VTI(netdev);
a613382b
SS
193 int r;
194
3be1d7e0 195 assert(netdev);
a613382b 196 assert(link);
a613382b 197 assert(m);
aa9f1140
TG
198 assert(t);
199 assert(t->family == AF_INET);
a613382b 200
1c4baffc 201 r = sd_netlink_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
5289f3ff
SS
202 if (r < 0)
203 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
a613382b 204
1c4baffc 205 r = sd_netlink_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
5289f3ff
SS
206 if (r < 0)
207 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
a613382b 208
1c4baffc 209 r = sd_netlink_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
5289f3ff
SS
210 if (r < 0)
211 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
a613382b 212
a613382b
SS
213 return r;
214}
8bb088c5 215
1c4baffc 216static int netdev_vti6_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
9011ce77
SS
217 Tunnel *t = VTI6(netdev);
218 int r;
219
220 assert(netdev);
221 assert(link);
222 assert(m);
223 assert(t);
224 assert(t->family == AF_INET6);
225
1c4baffc 226 r = sd_netlink_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
9011ce77
SS
227 if (r < 0)
228 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
229
1c4baffc 230 r = sd_netlink_message_append_in6_addr(m, IFLA_VTI_LOCAL, &t->local.in6);
9011ce77
SS
231 if (r < 0)
232 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
233
1c4baffc 234 r = sd_netlink_message_append_in6_addr(m, IFLA_VTI_REMOTE, &t->remote.in6);
9011ce77
SS
235 if (r < 0)
236 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
237
238 return r;
239}
240
1c4baffc 241static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
855ee1a1
SS
242 Tunnel *t = IP6TNL(netdev);
243 uint8_t proto;
244 int r;
245
246 assert(netdev);
247 assert(link);
248 assert(m);
249 assert(t);
250 assert(t->family == AF_INET6);
251
1c4baffc 252 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
5289f3ff
SS
253 if (r < 0)
254 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
855ee1a1 255
1c4baffc 256 r = sd_netlink_message_append_in6_addr(m, IFLA_IPTUN_LOCAL, &t->local.in6);
5289f3ff
SS
257 if (r < 0)
258 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
855ee1a1 259
1c4baffc 260 r = sd_netlink_message_append_in6_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in6);
5289f3ff
SS
261 if (r < 0)
262 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
855ee1a1 263
1c4baffc 264 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
5289f3ff
SS
265 if (r < 0)
266 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
855ee1a1 267
407af9dd
SS
268 if (t->ipv6_flowlabel != _NETDEV_IPV6_FLOWLABEL_INVALID) {
269 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_FLOWINFO, t->ipv6_flowlabel);
270 if (r < 0)
271 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLOWINFO attribute: %m");
272 }
273
274 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_FLAGS, t->flags);
275 if (r < 0)
276 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLAGS attribute: %m");
277
855ee1a1
SS
278 switch (t->ip6tnl_mode) {
279 case NETDEV_IP6_TNL_MODE_IP6IP6:
280 proto = IPPROTO_IPV6;
281 break;
282 case NETDEV_IP6_TNL_MODE_IPIP6:
283 proto = IPPROTO_IPIP;
284 break;
285 case NETDEV_IP6_TNL_MODE_ANYIP6:
286 default:
287 proto = 0;
288 break;
289 }
290
1c4baffc 291 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_PROTO, proto);
5289f3ff
SS
292 if (r < 0)
293 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_MODE attribute: %m");
855ee1a1
SS
294
295 return r;
296}
297
3be1d7e0 298static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
aa9f1140
TG
299 Tunnel *t = NULL;
300
7951dea2 301 assert(netdev);
3be1d7e0 302 assert(filename);
7951dea2 303
aa9f1140
TG
304 switch (netdev->kind) {
305 case NETDEV_KIND_IPIP:
306 t = IPIP(netdev);
307 break;
308 case NETDEV_KIND_SIT:
309 t = SIT(netdev);
310 break;
311 case NETDEV_KIND_GRE:
312 t = GRE(netdev);
313 break;
1af2536a
SS
314 case NETDEV_KIND_GRETAP:
315 t = GRETAP(netdev);
316 break;
b16492f8
SS
317 case NETDEV_KIND_IP6GRE:
318 t = IP6GRE(netdev);
319 break;
320 case NETDEV_KIND_IP6GRETAP:
321 t = IP6GRETAP(netdev);
322 break;
aa9f1140
TG
323 case NETDEV_KIND_VTI:
324 t = VTI(netdev);
325 break;
9011ce77
SS
326 case NETDEV_KIND_VTI6:
327 t = VTI6(netdev);
328 break;
855ee1a1
SS
329 case NETDEV_KIND_IP6TNL:
330 t = IP6TNL(netdev);
331 break;
aa9f1140
TG
332 default:
333 assert_not_reached("Invalid tunnel kind");
334 }
335
336 assert(t);
337
aa9f1140 338 if (t->remote.in.s_addr == INADDR_ANY) {
5289f3ff
SS
339 log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
340 return -EINVAL;
7951dea2
SS
341 }
342
855ee1a1 343 if (t->family != AF_INET && t->family != AF_INET6) {
5289f3ff
SS
344 log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
345 return -EINVAL;
7951dea2
SS
346 }
347
855ee1a1
SS
348 if (netdev->kind == NETDEV_KIND_IP6TNL) {
349 if (t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID) {
350 log_warning("IP6 Tunnel without mode configured in %s. Ignoring", filename);
351 return -EINVAL;
352 }
353 }
354
7951dea2
SS
355 return 0;
356}
6ef892fc
TG
357
358int config_parse_tunnel_address(const char *unit,
359 const char *filename,
360 unsigned line,
361 const char *section,
362 unsigned section_line,
363 const char *lvalue,
364 int ltype,
365 const char *rvalue,
366 void *data,
367 void *userdata) {
aa9f1140 368 Tunnel *t = userdata;
44e7b949
LP
369 union in_addr_union *addr = data, buffer;
370 int r, f;
6ef892fc
TG
371
372 assert(filename);
373 assert(lvalue);
374 assert(rvalue);
375 assert(data);
376
44e7b949 377 r = in_addr_from_string_auto(rvalue, &f, &buffer);
6ef892fc 378 if (r < 0) {
44e7b949 379 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
6ef892fc
TG
380 return 0;
381 }
382
44e7b949
LP
383 if (t->family != AF_UNSPEC && t->family != f) {
384 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
385 return 0;
386 }
387
388 t->family = f;
389 *addr = buffer;
390
6ef892fc
TG
391 return 0;
392}
3be1d7e0 393
407af9dd
SS
394static const char* const ipv6_flowlabel_table[_NETDEV_IPV6_FLOWLABEL_MAX] = {
395 [NETDEV_IPV6_FLOWLABEL_INHERIT] = "inherit",
396};
397
398DEFINE_STRING_TABLE_LOOKUP(ipv6_flowlabel, IPv6FlowLabel);
399
400int config_parse_ipv6_flowlabel(const char* unit,
401 const char *filename,
402 unsigned line,
403 const char *section,
404 unsigned section_line,
405 const char *lvalue,
406 int ltype,
407 const char *rvalue,
408 void *data,
409 void *userdata) {
410 IPv6FlowLabel *ipv6_flowlabel = data;
411 Tunnel *t = userdata;
412 IPv6FlowLabel s;
413 int k = 0;
414 int r;
415
416 assert(filename);
417 assert(lvalue);
418 assert(rvalue);
419 assert(ipv6_flowlabel);
420
421 s = ipv6_flowlabel_from_string(rvalue);
422 if (s != _NETDEV_IPV6_FLOWLABEL_INVALID) {
423 *ipv6_flowlabel = IP6_FLOWINFO_FLOWLABEL;
424 t->flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL;
425 } else {
426 r = config_parse_unsigned(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &k, userdata);
427 if (r >= 0) {
428 if (k > 0xFFFFF)
429 log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue);
430 else {
431 *ipv6_flowlabel = htonl(k) & IP6_FLOWINFO_FLOWLABEL;
432 t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
433 }
434 }
435 }
436
437 return 0;
438}
439
aa9f1140
TG
440static void ipip_init(NetDev *n) {
441 Tunnel *t = IPIP(n);
442
443 assert(n);
444 assert(t);
445
446 t->pmtudisc = true;
447}
448
449static void sit_init(NetDev *n) {
450 Tunnel *t = SIT(n);
451
452 assert(n);
453 assert(t);
454
455 t->pmtudisc = true;
456}
457
458static void vti_init(NetDev *n) {
7185d805 459 Tunnel *t;
aa9f1140
TG
460
461 assert(n);
9011ce77
SS
462
463 if (n->kind == NETDEV_KIND_VTI)
7185d805 464 t = VTI(n);
9011ce77
SS
465 else
466 t = VTI6(n);
467
aa9f1140
TG
468 assert(t);
469
470 t->pmtudisc = true;
471}
472
473static void gre_init(NetDev *n) {
1af2536a 474 Tunnel *t;
aa9f1140
TG
475
476 assert(n);
1af2536a
SS
477
478 if (n->kind == NETDEV_KIND_GRE)
479 t = GRE(n);
480 else
481 t = GRETAP(n);
482
aa9f1140
TG
483 assert(t);
484
485 t->pmtudisc = true;
486}
487
b16492f8
SS
488static void ip6gre_init(NetDev *n) {
489 Tunnel *t;
490
491 assert(n);
492
493 if (n->kind == NETDEV_KIND_IP6GRE)
494 t = IP6GRE(n);
495 else
496 t = IP6GRETAP(n);
497
498 assert(t);
499
500 t->ttl = DEFAULT_TNL_HOP_LIMIT;
501}
502
855ee1a1
SS
503static void ip6tnl_init(NetDev *n) {
504 Tunnel *t = IP6TNL(n);
505
506 assert(n);
507 assert(t);
508
509 t->ttl = DEFAULT_TNL_HOP_LIMIT;
510 t->encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
511 t->ip6tnl_mode = _NETDEV_IP6_TNL_MODE_INVALID;
407af9dd 512 t->ipv6_flowlabel = _NETDEV_IPV6_FLOWLABEL_INVALID;
855ee1a1
SS
513}
514
3be1d7e0 515const NetDevVTable ipip_vtable = {
aa9f1140
TG
516 .object_size = sizeof(Tunnel),
517 .init = ipip_init,
518 .sections = "Match\0NetDev\0Tunnel\0",
519 .fill_message_create = netdev_ipip_fill_message_create,
520 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
521 .config_verify = netdev_tunnel_verify,
522};
523
524const NetDevVTable sit_vtable = {
aa9f1140
TG
525 .object_size = sizeof(Tunnel),
526 .init = sit_init,
527 .sections = "Match\0NetDev\0Tunnel\0",
528 .fill_message_create = netdev_sit_fill_message_create,
529 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
530 .config_verify = netdev_tunnel_verify,
531};
532
533const NetDevVTable vti_vtable = {
aa9f1140
TG
534 .object_size = sizeof(Tunnel),
535 .init = vti_init,
536 .sections = "Match\0NetDev\0Tunnel\0",
537 .fill_message_create = netdev_vti_fill_message_create,
538 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
539 .config_verify = netdev_tunnel_verify,
540};
541
9011ce77
SS
542const NetDevVTable vti6_vtable = {
543 .object_size = sizeof(Tunnel),
544 .init = vti_init,
545 .sections = "Match\0NetDev\0Tunnel\0",
546 .fill_message_create = netdev_vti6_fill_message_create,
547 .create_type = NETDEV_CREATE_STACKED,
548 .config_verify = netdev_tunnel_verify,
549};
550
3be1d7e0 551const NetDevVTable gre_vtable = {
aa9f1140
TG
552 .object_size = sizeof(Tunnel),
553 .init = gre_init,
554 .sections = "Match\0NetDev\0Tunnel\0",
555 .fill_message_create = netdev_gre_fill_message_create,
556 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
557 .config_verify = netdev_tunnel_verify,
558};
1af2536a
SS
559
560const NetDevVTable gretap_vtable = {
561 .object_size = sizeof(Tunnel),
562 .init = gre_init,
563 .sections = "Match\0NetDev\0Tunnel\0",
564 .fill_message_create = netdev_gre_fill_message_create,
565 .create_type = NETDEV_CREATE_STACKED,
566 .config_verify = netdev_tunnel_verify,
567};
855ee1a1 568
b16492f8
SS
569const NetDevVTable ip6gre_vtable = {
570 .object_size = sizeof(Tunnel),
571 .init = ip6gre_init,
572 .sections = "Match\0NetDev\0Tunnel\0",
573 .fill_message_create = netdev_ip6gre_fill_message_create,
574 .create_type = NETDEV_CREATE_STACKED,
575 .config_verify = netdev_tunnel_verify,
576};
577
578const NetDevVTable ip6gretap_vtable = {
579 .object_size = sizeof(Tunnel),
580 .init = ip6gre_init,
581 .sections = "Match\0NetDev\0Tunnel\0",
582 .fill_message_create = netdev_ip6gre_fill_message_create,
583 .create_type = NETDEV_CREATE_STACKED,
584 .config_verify = netdev_tunnel_verify,
585};
586
855ee1a1
SS
587const NetDevVTable ip6tnl_vtable = {
588 .object_size = sizeof(Tunnel),
589 .init = ip6tnl_init,
590 .sections = "Match\0NetDev\0Tunnel\0",
591 .fill_message_create = netdev_ip6tnl_fill_message_create,
592 .create_type = NETDEV_CREATE_STACKED,
593 .config_verify = netdev_tunnel_verify,
594};