1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include <netinet/in.h>
6 #include <linux/if_tunnel.h>
7 #include <linux/ip6_tunnel.h>
9 #include "sd-netlink.h"
11 #include "conf-parser.h"
13 #include "netlink-util.h"
14 #include "networkd-link.h"
15 #include "netdev/tunnel.h"
16 #include "parse-util.h"
17 #include "string-table.h"
18 #include "string-util.h"
21 #define DEFAULT_TNL_HOP_LIMIT 64
22 #define IP6_FLOWINFO_FLOWLABEL htobe32(0x000FFFFF)
23 #define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0x40
25 static const char* const ip6tnl_mode_table
[_NETDEV_IP6_TNL_MODE_MAX
] = {
26 [NETDEV_IP6_TNL_MODE_IP6IP6
] = "ip6ip6",
27 [NETDEV_IP6_TNL_MODE_IPIP6
] = "ipip6",
28 [NETDEV_IP6_TNL_MODE_ANYIP6
] = "any",
31 DEFINE_STRING_TABLE_LOOKUP(ip6tnl_mode
, Ip6TnlMode
);
32 DEFINE_CONFIG_PARSE_ENUM(config_parse_ip6tnl_mode
, ip6tnl_mode
, Ip6TnlMode
, "Failed to parse ip6 tunnel Mode");
34 static int netdev_ipip_sit_fill_message_create(NetDev
*netdev
, Link
*link
, sd_netlink_message
*m
) {
40 if (netdev
->kind
== NETDEV_KIND_IPIP
)
47 assert(t
->family
== AF_INET
);
50 r
= sd_netlink_message_append_u32(m
, IFLA_IPTUN_LINK
, link
->ifindex
);
52 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_LINK attribute: %m");
55 r
= sd_netlink_message_append_in_addr(m
, IFLA_IPTUN_LOCAL
, &t
->local
.in
);
57 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
59 r
= sd_netlink_message_append_in_addr(m
, IFLA_IPTUN_REMOTE
, &t
->remote
.in
);
61 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
63 r
= sd_netlink_message_append_u8(m
, IFLA_IPTUN_TTL
, t
->ttl
);
65 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_TTL attribute: %m");
67 r
= sd_netlink_message_append_u8(m
, IFLA_IPTUN_PMTUDISC
, t
->pmtudisc
);
69 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_PMTUDISC attribute: %m");
72 r
= sd_netlink_message_append_u16(m
, IFLA_IPTUN_ENCAP_TYPE
, t
->fou_encap_type
);
74 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_ENCAP_TYPE attribute: %m");
76 r
= sd_netlink_message_append_u16(m
, IFLA_IPTUN_ENCAP_SPORT
, htobe16(t
->encap_src_port
));
78 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_ENCAP_SPORT attribute: %m");
80 r
= sd_netlink_message_append_u16(m
, IFLA_IPTUN_ENCAP_DPORT
, htobe16(t
->fou_destination_port
));
82 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_ENCAP_DPORT attribute: %m");
85 if (netdev
->kind
== NETDEV_KIND_SIT
) {
86 if (t
->sixrd_prefixlen
> 0) {
87 r
= sd_netlink_message_append_in6_addr(m
, IFLA_IPTUN_6RD_PREFIX
, &t
->sixrd_prefix
);
89 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_6RD_PREFIX attribute: %m");
91 /* u16 is deliberate here, even though we're passing a netmask that can never be >128. The kernel is
92 * expecting to receive the prefixlen as a u16.
94 r
= sd_netlink_message_append_u16(m
, IFLA_IPTUN_6RD_PREFIXLEN
, t
->sixrd_prefixlen
);
96 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_6RD_PREFIXLEN attribute: %m");
102 SET_FLAG(flags
, SIT_ISATAP
, t
->isatap
);
104 r
= sd_netlink_message_append_u16(m
, IFLA_IPTUN_FLAGS
, flags
);
106 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_FLAGS attribute: %m");
113 static int netdev_gre_erspan_fill_message_create(NetDev
*netdev
, Link
*link
, sd_netlink_message
*m
) {
124 switch (netdev
->kind
) {
125 case NETDEV_KIND_GRE
:
128 case NETDEV_KIND_ERSPAN
:
131 case NETDEV_KIND_GRETAP
:
135 assert_not_reached("invalid netdev kind");
139 assert(t
->family
== AF_INET
);
142 r
= sd_netlink_message_append_u32(m
, IFLA_GRE_LINK
, link
->ifindex
);
144 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_LINK attribute: %m");
147 if (netdev
->kind
== NETDEV_KIND_ERSPAN
) {
148 r
= sd_netlink_message_append_u32(m
, IFLA_GRE_ERSPAN_INDEX
, t
->erspan_index
);
150 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_ERSPAN_INDEX attribute: %m");
153 r
= sd_netlink_message_append_in_addr(m
, IFLA_GRE_LOCAL
, &t
->local
.in
);
155 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_LOCAL attribute: %m");
157 r
= sd_netlink_message_append_in_addr(m
, IFLA_GRE_REMOTE
, &t
->remote
.in
);
159 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_REMOTE attribute: %m");
161 r
= sd_netlink_message_append_u8(m
, IFLA_GRE_TTL
, t
->ttl
);
163 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_TTL attribute: %m");
165 r
= sd_netlink_message_append_u8(m
, IFLA_GRE_TOS
, t
->tos
);
167 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_TOS attribute: %m");
169 r
= sd_netlink_message_append_u8(m
, IFLA_GRE_PMTUDISC
, t
->pmtudisc
);
171 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_PMTUDISC attribute: %m");
174 ikey
= okey
= htobe32(t
->key
);
180 ikey
= htobe32(t
->ikey
);
185 okey
= htobe32(t
->okey
);
189 if (t
->gre_erspan_sequence
> 0) {
192 } else if (t
->gre_erspan_sequence
== 0) {
197 r
= sd_netlink_message_append_u32(m
, IFLA_GRE_IKEY
, ikey
);
199 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_IKEY attribute: %m");
201 r
= sd_netlink_message_append_u32(m
, IFLA_GRE_OKEY
, okey
);
203 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_OKEY attribute: %m");
205 r
= sd_netlink_message_append_u16(m
, IFLA_GRE_IFLAGS
, iflags
);
207 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_IFLAGS attribute: %m");
209 r
= sd_netlink_message_append_u16(m
, IFLA_GRE_OFLAGS
, oflags
);
211 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_OFLAGS, attribute: %m");
214 r
= sd_netlink_message_append_u16(m
, IFLA_GRE_ENCAP_TYPE
, t
->fou_encap_type
);
216 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_ENCAP_TYPE attribute: %m");
218 r
= sd_netlink_message_append_u16(m
, IFLA_GRE_ENCAP_SPORT
, htobe16(t
->encap_src_port
));
220 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_ENCAP_SPORT attribute: %m");
222 r
= sd_netlink_message_append_u16(m
, IFLA_GRE_ENCAP_DPORT
, htobe16(t
->fou_destination_port
));
224 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_ENCAP_DPORT attribute: %m");
230 static int netdev_ip6gre_fill_message_create(NetDev
*netdev
, Link
*link
, sd_netlink_message
*m
) {
236 if (netdev
->kind
== NETDEV_KIND_IP6GRE
)
239 t
= IP6GRETAP(netdev
);
242 assert(t
->family
== AF_INET6
);
246 r
= sd_netlink_message_append_u32(m
, IFLA_GRE_LINK
, link
->ifindex
);
248 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_LINK attribute: %m");
251 r
= sd_netlink_message_append_in6_addr(m
, IFLA_GRE_LOCAL
, &t
->local
.in6
);
253 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_LOCAL attribute: %m");
255 r
= sd_netlink_message_append_in6_addr(m
, IFLA_GRE_REMOTE
, &t
->remote
.in6
);
257 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_REMOTE attribute: %m");
259 r
= sd_netlink_message_append_u8(m
, IFLA_GRE_TTL
, t
->ttl
);
261 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_TTL attribute: %m");
263 if (t
->ipv6_flowlabel
!= _NETDEV_IPV6_FLOWLABEL_INVALID
) {
264 r
= sd_netlink_message_append_u32(m
, IFLA_GRE_FLOWINFO
, t
->ipv6_flowlabel
);
266 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_FLOWINFO attribute: %m");
269 r
= sd_netlink_message_append_u32(m
, IFLA_GRE_FLAGS
, t
->flags
);
271 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_GRE_FLAGS attribute: %m");
276 static int netdev_vti_fill_message_create(NetDev
*netdev
, Link
*link
, sd_netlink_message
*m
) {
284 if (netdev
->kind
== NETDEV_KIND_VTI
)
290 assert((netdev
->kind
== NETDEV_KIND_VTI
&& t
->family
== AF_INET
) ||
291 (netdev
->kind
== NETDEV_KIND_VTI6
&& t
->family
== AF_INET6
));
294 r
= sd_netlink_message_append_u32(m
, IFLA_VTI_LINK
, link
->ifindex
);
296 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VTI_LINK attribute: %m");
300 ikey
= okey
= htobe32(t
->key
);
302 ikey
= htobe32(t
->ikey
);
303 okey
= htobe32(t
->okey
);
306 r
= sd_netlink_message_append_u32(m
, IFLA_VTI_IKEY
, ikey
);
308 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VTI_IKEY attribute: %m");
310 r
= sd_netlink_message_append_u32(m
, IFLA_VTI_OKEY
, okey
);
312 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VTI_OKEY attribute: %m");
314 r
= netlink_message_append_in_addr_union(m
, IFLA_VTI_LOCAL
, t
->family
, &t
->local
);
316 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VTI_LOCAL attribute: %m");
318 r
= netlink_message_append_in_addr_union(m
, IFLA_VTI_REMOTE
, t
->family
, &t
->remote
);
320 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VTI_REMOTE attribute: %m");
325 static int netdev_ip6tnl_fill_message_create(NetDev
*netdev
, Link
*link
, sd_netlink_message
*m
) {
326 Tunnel
*t
= IP6TNL(netdev
);
333 assert(t
->family
== AF_INET6
);
336 r
= sd_netlink_message_append_u32(m
, IFLA_IPTUN_LINK
, link
->ifindex
);
338 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_LINK attribute: %m");
341 r
= sd_netlink_message_append_in6_addr(m
, IFLA_IPTUN_LOCAL
, &t
->local
.in6
);
343 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
345 r
= sd_netlink_message_append_in6_addr(m
, IFLA_IPTUN_REMOTE
, &t
->remote
.in6
);
347 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
349 r
= sd_netlink_message_append_u8(m
, IFLA_IPTUN_TTL
, t
->ttl
);
351 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_TTL attribute: %m");
353 if (t
->ipv6_flowlabel
!= _NETDEV_IPV6_FLOWLABEL_INVALID
) {
354 r
= sd_netlink_message_append_u32(m
, IFLA_IPTUN_FLOWINFO
, t
->ipv6_flowlabel
);
356 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_FLOWINFO attribute: %m");
360 t
->flags
|= IP6_TNL_F_RCV_DSCP_COPY
;
362 if (t
->allow_localremote
>= 0)
363 SET_FLAG(t
->flags
, IP6_TNL_F_ALLOW_LOCAL_REMOTE
, t
->allow_localremote
);
365 if (t
->encap_limit
!= IPV6_DEFAULT_TNL_ENCAP_LIMIT
) {
366 r
= sd_netlink_message_append_u8(m
, IFLA_IPTUN_ENCAP_LIMIT
, t
->encap_limit
);
368 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_ENCAP_LIMIT attribute: %m");
371 r
= sd_netlink_message_append_u32(m
, IFLA_IPTUN_FLAGS
, t
->flags
);
373 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_FLAGS attribute: %m");
375 switch (t
->ip6tnl_mode
) {
376 case NETDEV_IP6_TNL_MODE_IP6IP6
:
377 proto
= IPPROTO_IPV6
;
379 case NETDEV_IP6_TNL_MODE_IPIP6
:
380 proto
= IPPROTO_IPIP
;
382 case NETDEV_IP6_TNL_MODE_ANYIP6
:
388 r
= sd_netlink_message_append_u8(m
, IFLA_IPTUN_PROTO
, proto
);
390 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_IPTUN_PROTO attribute: %m");
395 static int netdev_tunnel_verify(NetDev
*netdev
, const char *filename
) {
401 switch (netdev
->kind
) {
402 case NETDEV_KIND_IPIP
:
405 case NETDEV_KIND_SIT
:
408 case NETDEV_KIND_GRE
:
411 case NETDEV_KIND_GRETAP
:
414 case NETDEV_KIND_IP6GRE
:
417 case NETDEV_KIND_IP6GRETAP
:
418 t
= IP6GRETAP(netdev
);
420 case NETDEV_KIND_VTI
:
423 case NETDEV_KIND_VTI6
:
426 case NETDEV_KIND_IP6TNL
:
429 case NETDEV_KIND_ERSPAN
:
433 assert_not_reached("Invalid tunnel kind");
438 if (IN_SET(netdev
->kind
, NETDEV_KIND_VTI
, NETDEV_KIND_IPIP
, NETDEV_KIND_SIT
, NETDEV_KIND_GRE
, NETDEV_KIND_GRETAP
) &&
439 t
->family
!= AF_INET
)
440 return log_netdev_error_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
),
441 "vti/ipip/sit/gre tunnel without a local/remote IPv4 address configured in %s. Ignoring", filename
);
443 if (IN_SET(netdev
->kind
, NETDEV_KIND_GRETAP
, NETDEV_KIND_ERSPAN
) &&
444 (t
->family
!= AF_INET
|| in_addr_is_null(t
->family
, &t
->remote
)))
445 return log_netdev_error_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
),
446 "gretap/erspan tunnel without a remote IPv4 address configured in %s. Ignoring", filename
);
448 if (IN_SET(netdev
->kind
, NETDEV_KIND_VTI6
, NETDEV_KIND_IP6TNL
, NETDEV_KIND_IP6GRE
, NETDEV_KIND_IP6GRETAP
) &&
449 t
->family
!= AF_INET6
)
450 return log_netdev_error_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
),
451 "vti6/ip6tnl/ip6gre tunnel without a local/remote IPv6 address configured in %s. Ignoring", filename
);
453 if (netdev
->kind
== NETDEV_KIND_IP6GRETAP
&&
454 (t
->family
!= AF_INET6
|| in_addr_is_null(t
->family
, &t
->remote
)))
455 return log_netdev_error_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
),
456 "ip6gretap tunnel without a remote IPv6 address configured in %s. Ignoring", filename
);
458 if (netdev
->kind
== NETDEV_KIND_IP6TNL
&&
459 t
->ip6tnl_mode
== _NETDEV_IP6_TNL_MODE_INVALID
)
460 return log_netdev_error_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
),
461 "ip6tnl without mode configured in %s. Ignoring", filename
);
463 if (t
->fou_tunnel
&& t
->fou_destination_port
<= 0)
464 return log_netdev_error_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
),
465 "FooOverUDP missing port configured in %s. Ignoring", filename
);
467 if (netdev
->kind
== NETDEV_KIND_ERSPAN
&& (t
->erspan_index
>= (1 << 20) || t
->erspan_index
== 0))
468 return log_netdev_error_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
), "Invalid erspan index %d. Ignoring", t
->erspan_index
);
473 int config_parse_tunnel_address(const char *unit
,
474 const char *filename
,
477 unsigned section_line
,
483 Tunnel
*t
= userdata
;
484 union in_addr_union
*addr
= data
, buffer
;
492 /* This is used to parse addresses on both local and remote ends of the tunnel.
493 * Address families must match.
495 * "any" is a special value which means that the address is unspecified.
498 if (streq(rvalue
, "any")) {
499 *addr
= IN_ADDR_NULL
;
501 /* As a special case, if both the local and remote addresses are
502 * unspecified, also clear the address family.
504 if (t
->family
!= AF_UNSPEC
&&
505 in_addr_is_null(t
->family
, &t
->local
) != 0 &&
506 in_addr_is_null(t
->family
, &t
->remote
) != 0)
507 t
->family
= AF_UNSPEC
;
511 r
= in_addr_from_string_auto(rvalue
, &f
, &buffer
);
513 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
514 "Tunnel address \"%s\" invalid, ignoring assignment: %m", rvalue
);
518 if (t
->family
!= AF_UNSPEC
&& t
->family
!= f
) {
519 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
520 "Tunnel addresses incompatible, ignoring assignment: %s", rvalue
);
529 int config_parse_tunnel_key(const char *unit
,
530 const char *filename
,
533 unsigned section_line
,
539 union in_addr_union buffer
;
540 Tunnel
*t
= userdata
;
549 r
= in_addr_from_string(AF_INET
, rvalue
, &buffer
);
551 r
= safe_atou32(rvalue
, &k
);
553 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse tunnel key ignoring assignment: %s", rvalue
);
557 k
= be32toh(buffer
.in
.s_addr
);
559 if (streq(lvalue
, "Key"))
561 else if (streq(lvalue
, "InputKey"))
569 int config_parse_ipv6_flowlabel(const char* unit
,
570 const char *filename
,
573 unsigned section_line
,
579 IPv6FlowLabel
*ipv6_flowlabel
= data
;
580 Tunnel
*t
= userdata
;
587 assert(ipv6_flowlabel
);
589 if (streq(rvalue
, "inherit")) {
590 *ipv6_flowlabel
= IP6_FLOWINFO_FLOWLABEL
;
591 t
->flags
|= IP6_TNL_F_USE_ORIG_FLOWLABEL
;
593 r
= config_parse_int(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &k
, userdata
);
598 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue
);
600 *ipv6_flowlabel
= htobe32(k
) & IP6_FLOWINFO_FLOWLABEL
;
601 t
->flags
&= ~IP6_TNL_F_USE_ORIG_FLOWLABEL
;
608 int config_parse_encap_limit(const char* unit
,
609 const char *filename
,
612 unsigned section_line
,
618 Tunnel
*t
= userdata
;
626 if (streq(rvalue
, "none"))
627 t
->flags
|= IP6_TNL_F_IGN_ENCAP_LIMIT
;
629 r
= safe_atoi(rvalue
, &k
);
631 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse Tunnel Encapsulation Limit option, ignoring: %s", rvalue
);
635 if (k
> 255 || k
< 0)
636 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Invalid Tunnel Encapsulation value, ignoring: %d", k
);
639 t
->flags
&= ~IP6_TNL_F_IGN_ENCAP_LIMIT
;
646 int config_parse_6rd_prefix(const char* unit
,
647 const char *filename
,
650 unsigned section_line
,
656 Tunnel
*t
= userdata
;
662 union in_addr_union p
;
666 r
= in_addr_prefix_from_string(rvalue
, AF_INET6
, &p
, &l
);
668 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse 6rd prefix \"%s\", ignoring: %m", rvalue
);
672 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "6rd prefix length of \"%s\" must be greater than zero, ignoring", rvalue
);
676 t
->sixrd_prefix
= p
.in6
;
677 t
->sixrd_prefixlen
= l
;
682 static void ipip_sit_init(NetDev
*n
) {
688 case NETDEV_KIND_IPIP
:
691 case NETDEV_KIND_SIT
:
695 assert_not_reached("invalid netdev kind");
701 t
->fou_encap_type
= FOU_ENCAP_DIRECT
;
705 static void vti_init(NetDev
*n
) {
710 if (n
->kind
== NETDEV_KIND_VTI
)
720 static void gre_erspan_init(NetDev
*n
) {
726 case NETDEV_KIND_GRE
:
729 case NETDEV_KIND_ERSPAN
:
732 case NETDEV_KIND_GRETAP
:
736 assert_not_reached("invalid netdev kind");
742 t
->gre_erspan_sequence
= -1;
743 t
->fou_encap_type
= FOU_ENCAP_DIRECT
;
746 static void ip6gre_init(NetDev
*n
) {
751 if (n
->kind
== NETDEV_KIND_IP6GRE
)
758 t
->ttl
= DEFAULT_TNL_HOP_LIMIT
;
761 static void ip6tnl_init(NetDev
*n
) {
762 Tunnel
*t
= IP6TNL(n
);
767 t
->ttl
= DEFAULT_TNL_HOP_LIMIT
;
768 t
->encap_limit
= IPV6_DEFAULT_TNL_ENCAP_LIMIT
;
769 t
->ip6tnl_mode
= _NETDEV_IP6_TNL_MODE_INVALID
;
770 t
->ipv6_flowlabel
= _NETDEV_IPV6_FLOWLABEL_INVALID
;
771 t
->allow_localremote
= -1;
774 const NetDevVTable ipip_vtable
= {
775 .object_size
= sizeof(Tunnel
),
776 .init
= ipip_sit_init
,
777 .sections
= "Match\0NetDev\0Tunnel\0",
778 .fill_message_create
= netdev_ipip_sit_fill_message_create
,
779 .create_type
= NETDEV_CREATE_STACKED
,
780 .config_verify
= netdev_tunnel_verify
,
783 const NetDevVTable sit_vtable
= {
784 .object_size
= sizeof(Tunnel
),
785 .init
= ipip_sit_init
,
786 .sections
= "Match\0NetDev\0Tunnel\0",
787 .fill_message_create
= netdev_ipip_sit_fill_message_create
,
788 .create_type
= NETDEV_CREATE_STACKED
,
789 .config_verify
= netdev_tunnel_verify
,
792 const NetDevVTable vti_vtable
= {
793 .object_size
= sizeof(Tunnel
),
795 .sections
= "Match\0NetDev\0Tunnel\0",
796 .fill_message_create
= netdev_vti_fill_message_create
,
797 .create_type
= NETDEV_CREATE_STACKED
,
798 .config_verify
= netdev_tunnel_verify
,
801 const NetDevVTable vti6_vtable
= {
802 .object_size
= sizeof(Tunnel
),
804 .sections
= "Match\0NetDev\0Tunnel\0",
805 .fill_message_create
= netdev_vti_fill_message_create
,
806 .create_type
= NETDEV_CREATE_STACKED
,
807 .config_verify
= netdev_tunnel_verify
,
810 const NetDevVTable gre_vtable
= {
811 .object_size
= sizeof(Tunnel
),
812 .init
= gre_erspan_init
,
813 .sections
= "Match\0NetDev\0Tunnel\0",
814 .fill_message_create
= netdev_gre_erspan_fill_message_create
,
815 .create_type
= NETDEV_CREATE_STACKED
,
816 .config_verify
= netdev_tunnel_verify
,
819 const NetDevVTable gretap_vtable
= {
820 .object_size
= sizeof(Tunnel
),
821 .init
= gre_erspan_init
,
822 .sections
= "Match\0NetDev\0Tunnel\0",
823 .fill_message_create
= netdev_gre_erspan_fill_message_create
,
824 .create_type
= NETDEV_CREATE_STACKED
,
825 .config_verify
= netdev_tunnel_verify
,
828 const NetDevVTable ip6gre_vtable
= {
829 .object_size
= sizeof(Tunnel
),
831 .sections
= "Match\0NetDev\0Tunnel\0",
832 .fill_message_create
= netdev_ip6gre_fill_message_create
,
833 .create_type
= NETDEV_CREATE_STACKED
,
834 .config_verify
= netdev_tunnel_verify
,
837 const NetDevVTable ip6gretap_vtable
= {
838 .object_size
= sizeof(Tunnel
),
840 .sections
= "Match\0NetDev\0Tunnel\0",
841 .fill_message_create
= netdev_ip6gre_fill_message_create
,
842 .create_type
= NETDEV_CREATE_STACKED
,
843 .config_verify
= netdev_tunnel_verify
,
846 const NetDevVTable ip6tnl_vtable
= {
847 .object_size
= sizeof(Tunnel
),
849 .sections
= "Match\0NetDev\0Tunnel\0",
850 .fill_message_create
= netdev_ip6tnl_fill_message_create
,
851 .create_type
= NETDEV_CREATE_STACKED
,
852 .config_verify
= netdev_tunnel_verify
,
855 const NetDevVTable erspan_vtable
= {
856 .object_size
= sizeof(Tunnel
),
857 .init
= gre_erspan_init
,
858 .sections
= "Match\0NetDev\0Tunnel\0",
859 .fill_message_create
= netdev_gre_erspan_fill_message_create
,
860 .create_type
= NETDEV_CREATE_STACKED
,
861 .config_verify
= netdev_tunnel_verify
,