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