]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/netdev/tunnel.c
Merge pull request #7705 from keszybz/redo-linking
[thirdparty/systemd.git] / src / network / netdev / tunnel.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2014 Susant Sahani
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <arpa/inet.h>
22 #include <net/if.h>
23 #include <linux/ip.h>
24 #include <linux/if_tunnel.h>
25 #include <linux/ip6_tunnel.h>
26
27 #include "sd-netlink.h"
28
29 #include "conf-parser.h"
30 #include "missing.h"
31 #include "networkd-link.h"
32 #include "netdev/tunnel.h"
33 #include "parse-util.h"
34 #include "string-table.h"
35 #include "string-util.h"
36 #include "util.h"
37
38 #define DEFAULT_TNL_HOP_LIMIT 64
39 #define IP6_FLOWINFO_FLOWLABEL htobe32(0x000FFFFF)
40 #define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0x40
41
42 static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = {
43 [NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6",
44 [NETDEV_IP6_TNL_MODE_IPIP6] = "ipip6",
45 [NETDEV_IP6_TNL_MODE_ANYIP6] = "any",
46 };
47
48 DEFINE_STRING_TABLE_LOOKUP(ip6tnl_mode, Ip6TnlMode);
49 DEFINE_CONFIG_PARSE_ENUM(config_parse_ip6tnl_mode, ip6tnl_mode, Ip6TnlMode, "Failed to parse ip6 tunnel Mode");
50
51 static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
52 Tunnel *t = IPIP(netdev);
53 int r;
54
55 assert(netdev);
56 assert(m);
57 assert(t);
58 assert(IN_SET(t->family, AF_INET, AF_UNSPEC));
59
60 if (link) {
61 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
62 if (r < 0)
63 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
64
65 }
66
67 r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
68 if (r < 0)
69 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
70
71 r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
72 if (r < 0)
73 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
74
75 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
76 if (r < 0)
77 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
78
79 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
80 if (r < 0)
81 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_PMTUDISC attribute: %m");
82
83 return r;
84 }
85
86 static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
87 Tunnel *t = SIT(netdev);
88 int r;
89
90 assert(netdev);
91 assert(m);
92 assert(t);
93 assert(IN_SET(t->family, AF_INET, AF_UNSPEC));
94
95 if (link) {
96 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
97 if (r < 0)
98 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
99
100 }
101
102 r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
103 if (r < 0)
104 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
105
106 r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
107 if (r < 0)
108 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
109
110 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
111 if (r < 0)
112 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
113
114 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
115 if (r < 0)
116 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_PMTUDISC attribute: %m");
117
118 return r;
119 }
120
121 static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
122 Tunnel *t;
123 int r;
124
125 assert(netdev);
126
127 if (netdev->kind == NETDEV_KIND_GRE)
128 t = GRE(netdev);
129 else
130 t = GRETAP(netdev);
131
132 assert(t);
133 assert(IN_SET(t->family, AF_INET, AF_UNSPEC));
134 assert(m);
135
136 if (link) {
137 r = sd_netlink_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
138 if (r < 0)
139 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LINK attribute: %m");
140 }
141
142 r = sd_netlink_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
143 if (r < 0)
144 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LOCAL attribute: %m");
145
146 r = sd_netlink_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
147 if (r < 0)
148 log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_REMOTE attribute: %m");
149
150 r = sd_netlink_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
151 if (r < 0)
152 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_TTL attribute: %m");
153
154 r = sd_netlink_message_append_u8(m, IFLA_GRE_TOS, t->tos);
155 if (r < 0)
156 log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_TOS attribute: %m");
157
158 r = sd_netlink_message_append_u8(m, IFLA_GRE_PMTUDISC, t->pmtudisc);
159 if (r < 0)
160 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_PMTUDISC attribute: %m");
161
162 return r;
163 }
164
165 static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
166 Tunnel *t;
167 int r;
168
169 assert(netdev);
170
171 if (netdev->kind == NETDEV_KIND_IP6GRE)
172 t = IP6GRE(netdev);
173 else
174 t = IP6GRETAP(netdev);
175
176 assert(t);
177 assert(t->family == AF_INET6);
178 assert(m);
179
180 if (link) {
181 r = sd_netlink_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
182 if (r < 0)
183 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LINK attribute: %m");
184 }
185
186 r = sd_netlink_message_append_in6_addr(m, IFLA_GRE_LOCAL, &t->local.in6);
187 if (r < 0)
188 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LOCAL attribute: %m");
189
190 r = sd_netlink_message_append_in6_addr(m, IFLA_GRE_REMOTE, &t->remote.in6);
191 if (r < 0)
192 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_REMOTE attribute: %m");
193
194 r = sd_netlink_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
195 if (r < 0)
196 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_TTL attribute: %m");
197
198 if (t->ipv6_flowlabel != _NETDEV_IPV6_FLOWLABEL_INVALID) {
199 r = sd_netlink_message_append_u32(m, IFLA_GRE_FLOWINFO, t->ipv6_flowlabel);
200 if (r < 0)
201 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_FLOWINFO attribute: %m");
202 }
203
204 r = sd_netlink_message_append_u32(m, IFLA_GRE_FLAGS, t->flags);
205 if (r < 0)
206 return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_FLAGS attribute: %m");
207
208 return r;
209 }
210
211 static int netdev_vti_fill_message_key(NetDev *netdev, Link *link, sd_netlink_message *m) {
212 uint32_t ikey, okey;
213 Tunnel *t;
214 int r;
215
216 assert(m);
217
218 if (netdev->kind == NETDEV_KIND_VTI)
219 t = VTI(netdev);
220 else
221 t = VTI6(netdev);
222
223 assert(t);
224
225 if (t->key != 0)
226 ikey = okey = htobe32(t->key);
227 else {
228 ikey = htobe32(t->ikey);
229 okey = htobe32(t->okey);
230 }
231
232 r = sd_netlink_message_append_u32(m, IFLA_VTI_IKEY, ikey);
233 if (r < 0)
234 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VTI_IKEY attribute: %m");
235
236 r = sd_netlink_message_append_u32(m, IFLA_VTI_OKEY, okey);
237 if (r < 0)
238 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VTI_OKEY attribute: %m");
239
240 return 0;
241 }
242
243 static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
244 Tunnel *t = VTI(netdev);
245 int r;
246
247 assert(netdev);
248 assert(m);
249 assert(t);
250 assert(t->family == AF_INET);
251
252 if (link) {
253 r = sd_netlink_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
254 if (r < 0)
255 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
256 }
257
258 r = netdev_vti_fill_message_key(netdev, link, m);
259 if (r < 0)
260 return r;
261
262 r = sd_netlink_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
263 if (r < 0)
264 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
265
266 r = sd_netlink_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
267 if (r < 0)
268 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
269
270 return r;
271 }
272
273 static int netdev_vti6_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
274 Tunnel *t = VTI6(netdev);
275 int r;
276
277 assert(netdev);
278 assert(m);
279 assert(t);
280 assert(t->family == AF_INET6);
281
282 if (link) {
283 r = sd_netlink_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
284 if (r < 0)
285 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
286 }
287
288 r = netdev_vti_fill_message_key(netdev, link, m);
289 if (r < 0)
290 return r;
291
292 r = sd_netlink_message_append_in6_addr(m, IFLA_VTI_LOCAL, &t->local.in6);
293 if (r < 0)
294 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
295
296 r = sd_netlink_message_append_in6_addr(m, IFLA_VTI_REMOTE, &t->remote.in6);
297 if (r < 0)
298 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
299
300 return r;
301 }
302
303 static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
304 Tunnel *t = IP6TNL(netdev);
305 uint8_t proto;
306 int r;
307
308 assert(netdev);
309 assert(m);
310 assert(t);
311 assert(t->family == AF_INET6);
312
313 if (link) {
314 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
315 if (r < 0)
316 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
317 }
318
319 r = sd_netlink_message_append_in6_addr(m, IFLA_IPTUN_LOCAL, &t->local.in6);
320 if (r < 0)
321 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
322
323 r = sd_netlink_message_append_in6_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in6);
324 if (r < 0)
325 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
326
327 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
328 if (r < 0)
329 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
330
331 if (t->ipv6_flowlabel != _NETDEV_IPV6_FLOWLABEL_INVALID) {
332 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_FLOWINFO, t->ipv6_flowlabel);
333 if (r < 0)
334 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLOWINFO attribute: %m");
335 }
336
337 if (t->copy_dscp)
338 t->flags |= IP6_TNL_F_RCV_DSCP_COPY;
339
340 if (t->allow_localremote != -1)
341 SET_FLAG(t->flags, IP6_TNL_F_ALLOW_LOCAL_REMOTE, t->allow_localremote);
342
343 if (t->encap_limit != IPV6_DEFAULT_TNL_ENCAP_LIMIT) {
344 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_ENCAP_LIMIT, t->encap_limit);
345 if (r < 0)
346 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_ENCAP_LIMIT attribute: %m");
347 }
348
349 r = sd_netlink_message_append_u32(m, IFLA_IPTUN_FLAGS, t->flags);
350 if (r < 0)
351 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLAGS attribute: %m");
352
353 switch (t->ip6tnl_mode) {
354 case NETDEV_IP6_TNL_MODE_IP6IP6:
355 proto = IPPROTO_IPV6;
356 break;
357 case NETDEV_IP6_TNL_MODE_IPIP6:
358 proto = IPPROTO_IPIP;
359 break;
360 case NETDEV_IP6_TNL_MODE_ANYIP6:
361 default:
362 proto = 0;
363 break;
364 }
365
366 r = sd_netlink_message_append_u8(m, IFLA_IPTUN_PROTO, proto);
367 if (r < 0)
368 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_MODE attribute: %m");
369
370 return r;
371 }
372
373 static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
374 Tunnel *t = NULL;
375
376 assert(netdev);
377 assert(filename);
378
379 switch (netdev->kind) {
380 case NETDEV_KIND_IPIP:
381 t = IPIP(netdev);
382 break;
383 case NETDEV_KIND_SIT:
384 t = SIT(netdev);
385 break;
386 case NETDEV_KIND_GRE:
387 t = GRE(netdev);
388 break;
389 case NETDEV_KIND_GRETAP:
390 t = GRETAP(netdev);
391 break;
392 case NETDEV_KIND_IP6GRE:
393 t = IP6GRE(netdev);
394 break;
395 case NETDEV_KIND_IP6GRETAP:
396 t = IP6GRETAP(netdev);
397 break;
398 case NETDEV_KIND_VTI:
399 t = VTI(netdev);
400 break;
401 case NETDEV_KIND_VTI6:
402 t = VTI6(netdev);
403 break;
404 case NETDEV_KIND_IP6TNL:
405 t = IP6TNL(netdev);
406 break;
407 default:
408 assert_not_reached("Invalid tunnel kind");
409 }
410
411 assert(t);
412
413 if (!IN_SET(t->family, AF_INET, AF_INET6, AF_UNSPEC)) {
414 log_netdev_error(netdev,
415 "Tunnel with invalid address family configured in %s. Ignoring", filename);
416 return -EINVAL;
417 }
418
419 if (netdev->kind == NETDEV_KIND_VTI &&
420 (t->family != AF_INET || in_addr_is_null(t->family, &t->local))) {
421 log_netdev_error(netdev,
422 "vti tunnel without a local IPv4 address configured in %s. Ignoring", filename);
423 return -EINVAL;
424 }
425
426 if (IN_SET(netdev->kind, NETDEV_KIND_VTI6, NETDEV_KIND_IP6TNL, NETDEV_KIND_IP6GRE) &&
427 (t->family != AF_INET6 || in_addr_is_null(t->family, &t->local))) {
428 log_netdev_error(netdev,
429 "vti6/ip6tnl/ip6gre tunnel without a local IPv6 address configured in %s. Ignoring", filename);
430 return -EINVAL;
431 }
432
433 if (netdev->kind == NETDEV_KIND_IP6TNL &&
434 t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID) {
435 log_netdev_error(netdev,
436 "ip6tnl without mode configured in %s. Ignoring", filename);
437 return -EINVAL;
438 }
439
440 return 0;
441 }
442
443 int config_parse_tunnel_address(const char *unit,
444 const char *filename,
445 unsigned line,
446 const char *section,
447 unsigned section_line,
448 const char *lvalue,
449 int ltype,
450 const char *rvalue,
451 void *data,
452 void *userdata) {
453 Tunnel *t = userdata;
454 union in_addr_union *addr = data, buffer;
455 int r, f;
456
457 assert(filename);
458 assert(lvalue);
459 assert(rvalue);
460 assert(data);
461
462 /* This is used to parse addresses on both local and remote ends of the tunnel.
463 * Address families must match.
464 *
465 * "any" is a special value which means that the address is unspecified.
466 */
467
468 if (streq(rvalue, "any")) {
469 *addr = IN_ADDR_NULL;
470
471 /* As a special case, if both the local and remote addresses are
472 * unspecified, also clear the address family.
473 */
474 if (t->family != AF_UNSPEC &&
475 in_addr_is_null(t->family, &t->local) &&
476 in_addr_is_null(t->family, &t->remote))
477 t->family = AF_UNSPEC;
478 return 0;
479 }
480
481 r = in_addr_from_string_auto(rvalue, &f, &buffer);
482 if (r < 0) {
483 log_syntax(unit, LOG_ERR, filename, line, r,
484 "Tunnel address \"%s\" invalid, ignoring assignment: %m", rvalue);
485 return 0;
486 }
487
488 if (t->family != AF_UNSPEC && t->family != f) {
489 log_syntax(unit, LOG_ERR, filename, line, 0,
490 "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
491 return 0;
492 }
493
494 t->family = f;
495 *addr = buffer;
496 return 0;
497 }
498
499 int config_parse_tunnel_key(const char *unit,
500 const char *filename,
501 unsigned line,
502 const char *section,
503 unsigned section_line,
504 const char *lvalue,
505 int ltype,
506 const char *rvalue,
507 void *data,
508 void *userdata) {
509 union in_addr_union buffer;
510 Tunnel *t = userdata;
511 uint32_t k;
512 int r;
513
514 assert(filename);
515 assert(lvalue);
516 assert(rvalue);
517 assert(data);
518
519 r = in_addr_from_string(AF_INET, rvalue, &buffer);
520 if (r < 0) {
521 r = safe_atou32(rvalue, &k);
522 if (r < 0) {
523 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse tunnel key ignoring assignment: %s", rvalue);
524 return 0;
525 }
526 } else
527 k = be32toh(buffer.in.s_addr);
528
529 if (streq(lvalue, "Key"))
530 t->key = k;
531 else if (streq(lvalue, "InputKey"))
532 t->ikey = k;
533 else
534 t->okey = k;
535
536 return 0;
537 }
538
539 int config_parse_ipv6_flowlabel(const char* unit,
540 const char *filename,
541 unsigned line,
542 const char *section,
543 unsigned section_line,
544 const char *lvalue,
545 int ltype,
546 const char *rvalue,
547 void *data,
548 void *userdata) {
549 IPv6FlowLabel *ipv6_flowlabel = data;
550 Tunnel *t = userdata;
551 int k = 0;
552 int r;
553
554 assert(filename);
555 assert(lvalue);
556 assert(rvalue);
557 assert(ipv6_flowlabel);
558
559 if (streq(rvalue, "inherit")) {
560 *ipv6_flowlabel = IP6_FLOWINFO_FLOWLABEL;
561 t->flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL;
562 } else {
563 r = config_parse_int(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &k, userdata);
564 if (r < 0)
565 return r;
566
567 if (k > 0xFFFFF)
568 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue);
569 else {
570 *ipv6_flowlabel = htobe32(k) & IP6_FLOWINFO_FLOWLABEL;
571 t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
572 }
573 }
574
575 return 0;
576 }
577
578 int config_parse_encap_limit(const char* unit,
579 const char *filename,
580 unsigned line,
581 const char *section,
582 unsigned section_line,
583 const char *lvalue,
584 int ltype,
585 const char *rvalue,
586 void *data,
587 void *userdata) {
588 Tunnel *t = userdata;
589 int k = 0;
590 int r;
591
592 assert(filename);
593 assert(lvalue);
594 assert(rvalue);
595
596 if (streq(rvalue, "none"))
597 t->flags |= IP6_TNL_F_IGN_ENCAP_LIMIT;
598 else {
599 r = safe_atoi(rvalue, &k);
600 if (r < 0) {
601 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Tunnel Encapsulation Limit option, ignoring: %s", rvalue);
602 return 0;
603 }
604
605 if (k > 255 || k < 0)
606 log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid Tunnel Encapsulation value, ignoring: %d", k);
607 else {
608 t->encap_limit = k;
609 t->flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
610 }
611 }
612
613 return 0;
614 }
615
616 static void ipip_init(NetDev *n) {
617 Tunnel *t = IPIP(n);
618
619 assert(n);
620 assert(t);
621
622 t->pmtudisc = true;
623 }
624
625 static void sit_init(NetDev *n) {
626 Tunnel *t = SIT(n);
627
628 assert(n);
629 assert(t);
630
631 t->pmtudisc = true;
632 }
633
634 static void vti_init(NetDev *n) {
635 Tunnel *t;
636
637 assert(n);
638
639 if (n->kind == NETDEV_KIND_VTI)
640 t = VTI(n);
641 else
642 t = VTI6(n);
643
644 assert(t);
645
646 t->pmtudisc = true;
647 }
648
649 static void gre_init(NetDev *n) {
650 Tunnel *t;
651
652 assert(n);
653
654 if (n->kind == NETDEV_KIND_GRE)
655 t = GRE(n);
656 else
657 t = GRETAP(n);
658
659 assert(t);
660
661 t->pmtudisc = true;
662 }
663
664 static void ip6gre_init(NetDev *n) {
665 Tunnel *t;
666
667 assert(n);
668
669 if (n->kind == NETDEV_KIND_IP6GRE)
670 t = IP6GRE(n);
671 else
672 t = IP6GRETAP(n);
673
674 assert(t);
675
676 t->ttl = DEFAULT_TNL_HOP_LIMIT;
677 }
678
679 static void ip6tnl_init(NetDev *n) {
680 Tunnel *t = IP6TNL(n);
681
682 assert(n);
683 assert(t);
684
685 t->ttl = DEFAULT_TNL_HOP_LIMIT;
686 t->encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
687 t->ip6tnl_mode = _NETDEV_IP6_TNL_MODE_INVALID;
688 t->ipv6_flowlabel = _NETDEV_IPV6_FLOWLABEL_INVALID;
689 t->allow_localremote = -1;
690 }
691
692 const NetDevVTable ipip_vtable = {
693 .object_size = sizeof(Tunnel),
694 .init = ipip_init,
695 .sections = "Match\0NetDev\0Tunnel\0",
696 .fill_message_create = netdev_ipip_fill_message_create,
697 .create_type = NETDEV_CREATE_STACKED,
698 .config_verify = netdev_tunnel_verify,
699 };
700
701 const NetDevVTable sit_vtable = {
702 .object_size = sizeof(Tunnel),
703 .init = sit_init,
704 .sections = "Match\0NetDev\0Tunnel\0",
705 .fill_message_create = netdev_sit_fill_message_create,
706 .create_type = NETDEV_CREATE_STACKED,
707 .config_verify = netdev_tunnel_verify,
708 };
709
710 const NetDevVTable vti_vtable = {
711 .object_size = sizeof(Tunnel),
712 .init = vti_init,
713 .sections = "Match\0NetDev\0Tunnel\0",
714 .fill_message_create = netdev_vti_fill_message_create,
715 .create_type = NETDEV_CREATE_STACKED,
716 .config_verify = netdev_tunnel_verify,
717 };
718
719 const NetDevVTable vti6_vtable = {
720 .object_size = sizeof(Tunnel),
721 .init = vti_init,
722 .sections = "Match\0NetDev\0Tunnel\0",
723 .fill_message_create = netdev_vti6_fill_message_create,
724 .create_type = NETDEV_CREATE_STACKED,
725 .config_verify = netdev_tunnel_verify,
726 };
727
728 const NetDevVTable gre_vtable = {
729 .object_size = sizeof(Tunnel),
730 .init = gre_init,
731 .sections = "Match\0NetDev\0Tunnel\0",
732 .fill_message_create = netdev_gre_fill_message_create,
733 .create_type = NETDEV_CREATE_STACKED,
734 .config_verify = netdev_tunnel_verify,
735 };
736
737 const NetDevVTable gretap_vtable = {
738 .object_size = sizeof(Tunnel),
739 .init = gre_init,
740 .sections = "Match\0NetDev\0Tunnel\0",
741 .fill_message_create = netdev_gre_fill_message_create,
742 .create_type = NETDEV_CREATE_STACKED,
743 .config_verify = netdev_tunnel_verify,
744 };
745
746 const NetDevVTable ip6gre_vtable = {
747 .object_size = sizeof(Tunnel),
748 .init = ip6gre_init,
749 .sections = "Match\0NetDev\0Tunnel\0",
750 .fill_message_create = netdev_ip6gre_fill_message_create,
751 .create_type = NETDEV_CREATE_STACKED,
752 .config_verify = netdev_tunnel_verify,
753 };
754
755 const NetDevVTable ip6gretap_vtable = {
756 .object_size = sizeof(Tunnel),
757 .init = ip6gre_init,
758 .sections = "Match\0NetDev\0Tunnel\0",
759 .fill_message_create = netdev_ip6gre_fill_message_create,
760 .create_type = NETDEV_CREATE_STACKED,
761 .config_verify = netdev_tunnel_verify,
762 };
763
764 const NetDevVTable ip6tnl_vtable = {
765 .object_size = sizeof(Tunnel),
766 .init = ip6tnl_init,
767 .sections = "Match\0NetDev\0Tunnel\0",
768 .fill_message_create = netdev_ip6tnl_fill_message_create,
769 .create_type = NETDEV_CREATE_STACKED,
770 .config_verify = netdev_tunnel_verify,
771 };