]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-netdev-tunnel.c
Merge pull request #674 from ssahani/tunnel
[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
ec2a3e3a
SS
274 if (t->dscp)
275 t->flags |= IP6_TNL_F_RCV_DSCP_COPY;
276
407af9dd
SS
277 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_FLAGS, t->flags);
278 if (r < 0)
279 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLAGS attribute: %m");
280
855ee1a1
SS
281 switch (t->ip6tnl_mode) {
282 case NETDEV_IP6_TNL_MODE_IP6IP6:
283 proto = IPPROTO_IPV6;
284 break;
285 case NETDEV_IP6_TNL_MODE_IPIP6:
286 proto = IPPROTO_IPIP;
287 break;
288 case NETDEV_IP6_TNL_MODE_ANYIP6:
289 default:
290 proto = 0;
291 break;
292 }
293
1c4baffc 294 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_PROTO, proto);
5289f3ff
SS
295 if (r < 0)
296 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_MODE attribute: %m");
855ee1a1
SS
297
298 return r;
299}
300
3be1d7e0 301static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
aa9f1140
TG
302 Tunnel *t = NULL;
303
7951dea2 304 assert(netdev);
3be1d7e0 305 assert(filename);
7951dea2 306
aa9f1140
TG
307 switch (netdev->kind) {
308 case NETDEV_KIND_IPIP:
309 t = IPIP(netdev);
310 break;
311 case NETDEV_KIND_SIT:
312 t = SIT(netdev);
313 break;
314 case NETDEV_KIND_GRE:
315 t = GRE(netdev);
316 break;
1af2536a
SS
317 case NETDEV_KIND_GRETAP:
318 t = GRETAP(netdev);
319 break;
b16492f8
SS
320 case NETDEV_KIND_IP6GRE:
321 t = IP6GRE(netdev);
322 break;
323 case NETDEV_KIND_IP6GRETAP:
324 t = IP6GRETAP(netdev);
325 break;
aa9f1140
TG
326 case NETDEV_KIND_VTI:
327 t = VTI(netdev);
328 break;
9011ce77
SS
329 case NETDEV_KIND_VTI6:
330 t = VTI6(netdev);
331 break;
855ee1a1
SS
332 case NETDEV_KIND_IP6TNL:
333 t = IP6TNL(netdev);
334 break;
aa9f1140
TG
335 default:
336 assert_not_reached("Invalid tunnel kind");
337 }
338
339 assert(t);
340
aa9f1140 341 if (t->remote.in.s_addr == INADDR_ANY) {
5289f3ff
SS
342 log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
343 return -EINVAL;
7951dea2
SS
344 }
345
855ee1a1 346 if (t->family != AF_INET && t->family != AF_INET6) {
5289f3ff
SS
347 log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
348 return -EINVAL;
7951dea2
SS
349 }
350
855ee1a1
SS
351 if (netdev->kind == NETDEV_KIND_IP6TNL) {
352 if (t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID) {
353 log_warning("IP6 Tunnel without mode configured in %s. Ignoring", filename);
354 return -EINVAL;
355 }
356 }
357
7951dea2
SS
358 return 0;
359}
6ef892fc
TG
360
361int config_parse_tunnel_address(const char *unit,
362 const char *filename,
363 unsigned line,
364 const char *section,
365 unsigned section_line,
366 const char *lvalue,
367 int ltype,
368 const char *rvalue,
369 void *data,
370 void *userdata) {
aa9f1140 371 Tunnel *t = userdata;
44e7b949
LP
372 union in_addr_union *addr = data, buffer;
373 int r, f;
6ef892fc
TG
374
375 assert(filename);
376 assert(lvalue);
377 assert(rvalue);
378 assert(data);
379
44e7b949 380 r = in_addr_from_string_auto(rvalue, &f, &buffer);
6ef892fc 381 if (r < 0) {
44e7b949 382 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
6ef892fc
TG
383 return 0;
384 }
385
44e7b949
LP
386 if (t->family != AF_UNSPEC && t->family != f) {
387 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
388 return 0;
389 }
390
391 t->family = f;
392 *addr = buffer;
393
6ef892fc
TG
394 return 0;
395}
3be1d7e0 396
407af9dd
SS
397static const char* const ipv6_flowlabel_table[_NETDEV_IPV6_FLOWLABEL_MAX] = {
398 [NETDEV_IPV6_FLOWLABEL_INHERIT] = "inherit",
399};
400
401DEFINE_STRING_TABLE_LOOKUP(ipv6_flowlabel, IPv6FlowLabel);
402
403int config_parse_ipv6_flowlabel(const char* unit,
404 const char *filename,
405 unsigned line,
406 const char *section,
407 unsigned section_line,
408 const char *lvalue,
409 int ltype,
410 const char *rvalue,
411 void *data,
412 void *userdata) {
413 IPv6FlowLabel *ipv6_flowlabel = data;
414 Tunnel *t = userdata;
415 IPv6FlowLabel s;
416 int k = 0;
417 int r;
418
419 assert(filename);
420 assert(lvalue);
421 assert(rvalue);
422 assert(ipv6_flowlabel);
423
424 s = ipv6_flowlabel_from_string(rvalue);
425 if (s != _NETDEV_IPV6_FLOWLABEL_INVALID) {
426 *ipv6_flowlabel = IP6_FLOWINFO_FLOWLABEL;
427 t->flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL;
428 } else {
429 r = config_parse_unsigned(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &k, userdata);
430 if (r >= 0) {
431 if (k > 0xFFFFF)
432 log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue);
433 else {
434 *ipv6_flowlabel = htonl(k) & IP6_FLOWINFO_FLOWLABEL;
435 t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
436 }
437 }
438 }
439
440 return 0;
441}
442
aa9f1140
TG
443static void ipip_init(NetDev *n) {
444 Tunnel *t = IPIP(n);
445
446 assert(n);
447 assert(t);
448
449 t->pmtudisc = true;
450}
451
452static void sit_init(NetDev *n) {
453 Tunnel *t = SIT(n);
454
455 assert(n);
456 assert(t);
457
458 t->pmtudisc = true;
459}
460
461static void vti_init(NetDev *n) {
7185d805 462 Tunnel *t;
aa9f1140
TG
463
464 assert(n);
9011ce77
SS
465
466 if (n->kind == NETDEV_KIND_VTI)
7185d805 467 t = VTI(n);
9011ce77
SS
468 else
469 t = VTI6(n);
470
aa9f1140
TG
471 assert(t);
472
473 t->pmtudisc = true;
474}
475
476static void gre_init(NetDev *n) {
1af2536a 477 Tunnel *t;
aa9f1140
TG
478
479 assert(n);
1af2536a
SS
480
481 if (n->kind == NETDEV_KIND_GRE)
482 t = GRE(n);
483 else
484 t = GRETAP(n);
485
aa9f1140
TG
486 assert(t);
487
488 t->pmtudisc = true;
489}
490
b16492f8
SS
491static void ip6gre_init(NetDev *n) {
492 Tunnel *t;
493
494 assert(n);
495
496 if (n->kind == NETDEV_KIND_IP6GRE)
497 t = IP6GRE(n);
498 else
499 t = IP6GRETAP(n);
500
501 assert(t);
502
503 t->ttl = DEFAULT_TNL_HOP_LIMIT;
504}
505
855ee1a1
SS
506static void ip6tnl_init(NetDev *n) {
507 Tunnel *t = IP6TNL(n);
508
509 assert(n);
510 assert(t);
511
512 t->ttl = DEFAULT_TNL_HOP_LIMIT;
513 t->encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
514 t->ip6tnl_mode = _NETDEV_IP6_TNL_MODE_INVALID;
407af9dd 515 t->ipv6_flowlabel = _NETDEV_IPV6_FLOWLABEL_INVALID;
855ee1a1
SS
516}
517
3be1d7e0 518const NetDevVTable ipip_vtable = {
aa9f1140
TG
519 .object_size = sizeof(Tunnel),
520 .init = ipip_init,
521 .sections = "Match\0NetDev\0Tunnel\0",
522 .fill_message_create = netdev_ipip_fill_message_create,
523 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
524 .config_verify = netdev_tunnel_verify,
525};
526
527const NetDevVTable sit_vtable = {
aa9f1140
TG
528 .object_size = sizeof(Tunnel),
529 .init = sit_init,
530 .sections = "Match\0NetDev\0Tunnel\0",
531 .fill_message_create = netdev_sit_fill_message_create,
532 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
533 .config_verify = netdev_tunnel_verify,
534};
535
536const NetDevVTable vti_vtable = {
aa9f1140
TG
537 .object_size = sizeof(Tunnel),
538 .init = vti_init,
539 .sections = "Match\0NetDev\0Tunnel\0",
540 .fill_message_create = netdev_vti_fill_message_create,
541 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
542 .config_verify = netdev_tunnel_verify,
543};
544
9011ce77
SS
545const NetDevVTable vti6_vtable = {
546 .object_size = sizeof(Tunnel),
547 .init = vti_init,
548 .sections = "Match\0NetDev\0Tunnel\0",
549 .fill_message_create = netdev_vti6_fill_message_create,
550 .create_type = NETDEV_CREATE_STACKED,
551 .config_verify = netdev_tunnel_verify,
552};
553
3be1d7e0 554const NetDevVTable gre_vtable = {
aa9f1140
TG
555 .object_size = sizeof(Tunnel),
556 .init = gre_init,
557 .sections = "Match\0NetDev\0Tunnel\0",
558 .fill_message_create = netdev_gre_fill_message_create,
559 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
560 .config_verify = netdev_tunnel_verify,
561};
1af2536a
SS
562
563const NetDevVTable gretap_vtable = {
564 .object_size = sizeof(Tunnel),
565 .init = gre_init,
566 .sections = "Match\0NetDev\0Tunnel\0",
567 .fill_message_create = netdev_gre_fill_message_create,
568 .create_type = NETDEV_CREATE_STACKED,
569 .config_verify = netdev_tunnel_verify,
570};
855ee1a1 571
b16492f8
SS
572const NetDevVTable ip6gre_vtable = {
573 .object_size = sizeof(Tunnel),
574 .init = ip6gre_init,
575 .sections = "Match\0NetDev\0Tunnel\0",
576 .fill_message_create = netdev_ip6gre_fill_message_create,
577 .create_type = NETDEV_CREATE_STACKED,
578 .config_verify = netdev_tunnel_verify,
579};
580
581const NetDevVTable ip6gretap_vtable = {
582 .object_size = sizeof(Tunnel),
583 .init = ip6gre_init,
584 .sections = "Match\0NetDev\0Tunnel\0",
585 .fill_message_create = netdev_ip6gre_fill_message_create,
586 .create_type = NETDEV_CREATE_STACKED,
587 .config_verify = netdev_tunnel_verify,
588};
589
855ee1a1
SS
590const NetDevVTable ip6tnl_vtable = {
591 .object_size = sizeof(Tunnel),
592 .init = ip6tnl_init,
593 .sections = "Match\0NetDev\0Tunnel\0",
594 .fill_message_create = netdev_ip6tnl_fill_message_create,
595 .create_type = NETDEV_CREATE_STACKED,
596 .config_verify = netdev_tunnel_verify,
597};