<varlistentry>
<term><varname>Mode=</varname></term>
<listitem>
- <para>An <literal>ip6tnl</literal> tunnel can be in one of three
- modes
- <literal>ip6ip6</literal> for IPv6 over IPv6,
- <literal>ipip6</literal> for IPv4 over IPv6 or
- <literal>any</literal> for either.
- </para>
+ <para>Specifies the tunnel mode. Acceptable values depend on the tunnel kind.</para>
+
+ <table>
+ <title>Supported tunnel modes</title>
+
+ <tgroup cols='3'>
+ <colspec colname='kind' />
+ <colspec colname='mode' />
+ <colspec colname='explanation' />
+ <thead>
+ <row>
+ <entry>Kind</entry>
+ <entry>Mode</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry morerows="2"><literal>ip6tnl</literal></entry>
+ <entry><literal>ipip6</literal></entry>
+ <entry>IPv4 over IPv6</entry>
+ </row>
+ <row>
+ <entry><literal>ip6ip6</literal></entry>
+ <entry>IPv6 over IPv6</entry>
+ </row>
+ <row>
+ <entry><literal>any</literal></entry>
+ <entry>both IPv4 and IPv6 over IPv6 (default)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
<xi:include href="version-info.xml" xpointer="v219"/>
</listitem>
Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey)
Tunnel.DiscoverPathMTU, config_parse_tristate, 0, offsetof(Tunnel, pmtudisc)
Tunnel.IgnoreDontFragment, config_parse_bool, 0, offsetof(Tunnel, ignore_df)
-Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode)
+Tunnel.Mode, config_parse_tunnel_mode, 0, offsetof(Tunnel, mode)
Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, 0
Tunnel.CopyDSCP, config_parse_bool, 0, offsetof(Tunnel, copy_dscp)
Tunnel.EncapsulationLimit, config_parse_encap_limit, 0, 0
#define IP6_FLOWINFO_FLOWLABEL htobe32(0x000FFFFF)
#define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0x40
-static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = {
- [NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6",
- [NETDEV_IP6_TNL_MODE_IPIP6] = "ipip6",
- [NETDEV_IP6_TNL_MODE_ANYIP6] = "any",
+#define HASH_KEY SD_ID128_MAKE(74,c4,de,12,f3,d9,41,34,bb,3d,c1,a4,42,93,50,87)
+
+static const uint8_t tunnel_mode_to_proto[_TUNNEL_MODE_MAX] = {
+ [TUNNEL_MODE_ANY] = 0,
+ [TUNNEL_MODE_IPIP6] = IPPROTO_IPIP,
+ [TUNNEL_MODE_IP6IP6] = IPPROTO_IPV6,
};
-DEFINE_STRING_TABLE_LOOKUP(ip6tnl_mode, Ip6TnlMode);
-DEFINE_CONFIG_PARSE_ENUM(config_parse_ip6tnl_mode, ip6tnl_mode, Ip6TnlMode);
+static const char* const tunnel_mode_table[_TUNNEL_MODE_MAX] = {
+ [TUNNEL_MODE_ANY] = "any",
+ [TUNNEL_MODE_IPIP6] = "ipip6",
+ [TUNNEL_MODE_IP6IP6] = "ip6ip6",
+};
-#define HASH_KEY SD_ID128_MAKE(74,c4,de,12,f3,d9,41,34,bb,3d,c1,a4,42,93,50,87)
+DEFINE_STRING_TABLE_LOOKUP(tunnel_mode, TunnelMode);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_tunnel_mode, tunnel_mode, TunnelMode);
static int dhcp4_pd_create_6rd_tunnel_name(Link *link) {
_cleanup_free_ char *ifname_alloc = NULL;
assert(m);
union in_addr_union local;
- uint8_t proto;
Tunnel *t = IP6TNL(netdev);
int r;
- switch (t->ip6tnl_mode) {
- case NETDEV_IP6_TNL_MODE_IP6IP6:
- proto = IPPROTO_IPV6;
- break;
- case NETDEV_IP6_TNL_MODE_IPIP6:
- proto = IPPROTO_IPIP;
- break;
- case NETDEV_IP6_TNL_MODE_ANYIP6:
- default:
- proto = 0;
+ if (t->mode >= 0) {
+ r = sd_netlink_message_append_u8(m, IFLA_IPTUN_PROTO, tunnel_mode_to_proto[t->mode]);
+ if (r < 0)
+ return r;
}
- r = sd_netlink_message_append_u8(m, IFLA_IPTUN_PROTO, proto);
- if (r < 0)
- return r;
-
if (t->external) {
r = sd_netlink_message_append_flag(m, IFLA_IPTUN_COLLECT_METADATA);
if (r < 0)
Tunnel *t = ASSERT_PTR(TUNNEL(netdev));
- if (netdev->kind == NETDEV_KIND_IP6TNL &&
- t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID)
- return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
- "ip6tnl without mode configured in %s. Ignoring", filename);
-
if (t->external) {
if (IN_SET(netdev->kind, NETDEV_KIND_VTI, NETDEV_KIND_VTI6))
log_netdev_debug(netdev, "vti/vti6 tunnel do not support external mode, ignoring.");
"IgnoreDontFragment= cannot be enabled when DiscoverPathMTU= is enabled");
if (t->pmtudisc < 0)
t->pmtudisc = !t->ignore_df;
+
+ if (t->mode >= 0)
+ switch (netdev->kind) {
+ case NETDEV_KIND_IP6TNL:
+ if (!IN_SET(t->mode, TUNNEL_MODE_ANY, TUNNEL_MODE_IPIP6, TUNNEL_MODE_IP6IP6))
+ return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
+ "Specified unsupported tunnel mode %s, ignoring.",
+ tunnel_mode_to_string(t->mode));
+ break;
+ default:
+ return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
+ "%s tunnel does not support Mode= setting, ignoring: %s",
+ netdev_kind_to_string(netdev->kind),
+ tunnel_mode_to_string(t->mode));
+ }
+
return 0;
}
t->isatap = -1;
t->gre_erspan_sequence = -1;
t->encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
- t->ip6tnl_mode = _NETDEV_IP6_TNL_MODE_INVALID;
+ t->mode = _TUNNEL_MODE_INVALID;
t->ipv6_flowlabel = _NETDEV_IPV6_FLOWLABEL_INVALID;
t->allow_localremote = -1;
t->erspan_version = 1;
#include "netdev.h"
#include "networkd-link.h"
-typedef enum Ip6TnlMode {
- NETDEV_IP6_TNL_MODE_IP6IP6,
- NETDEV_IP6_TNL_MODE_IPIP6,
- NETDEV_IP6_TNL_MODE_ANYIP6,
- _NETDEV_IP6_TNL_MODE_MAX,
- _NETDEV_IP6_TNL_MODE_INVALID = -EINVAL,
-} Ip6TnlMode;
+/* For IFLA_IPTUN_PROTO attribute */
+typedef enum TunnelMode {
+ TUNNEL_MODE_ANY, /* 0, "any" */
+ TUNNEL_MODE_IPIP6, /* IPPROTO_IPIP, "ipip6", for ip6tnl */
+ TUNNEL_MODE_IP6IP6, /* IPPROTO_IPV6, "ip6ip6", for ip6tnl */
+ _TUNNEL_MODE_MAX,
+ _TUNNEL_MODE_INVALID = -EINVAL,
+} TunnelMode;
typedef enum IPv6FlowLabel {
NETDEV_IPV6_FLOWLABEL_INHERIT = 0xFFFFF + 1,
union in_addr_union local;
union in_addr_union remote;
- Ip6TnlMode ip6tnl_mode;
+ TunnelMode mode;
FooOverUDPEncapType fou_encap_type;
int pmtudisc;
extern const NetDevVTable ip6tnl_vtable;
extern const NetDevVTable erspan_vtable;
-const char* ip6tnl_mode_to_string(Ip6TnlMode d) _const_;
-Ip6TnlMode ip6tnl_mode_from_string(const char *d) _pure_;
+const char* tunnel_mode_to_string(TunnelMode d) _const_;
+TunnelMode tunnel_mode_from_string(const char *d) _pure_;
-CONFIG_PARSER_PROTOTYPE(config_parse_ip6tnl_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_tunnel_mode);
CONFIG_PARSER_PROTOTYPE(config_parse_tunnel_local_address);
CONFIG_PARSER_PROTOTYPE(config_parse_tunnel_remote_address);
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_flowlabel);
test_table_sparse(DHCP6MessageType, dhcp6_message_type, DHCP6_MESSAGE_TYPE); /* enum starts from 1 */
test_table(UseDomains, use_domains, USE_DOMAINS);
test_table(Duplex, duplex, DUP);
- test_table(Ip6TnlMode, ip6tnl_mode, NETDEV_IP6_TNL_MODE);
+ test_table(TunnelMode, tunnel_mode, TUNNEL_MODE);
test_table(IPv6PrivacyExtensions, ipv6_privacy_extensions, IPV6_PRIVACY_EXTENSIONS);
test_table(IPVlanFlags, ipvlan_flags, NETDEV_IPVLAN_FLAGS);
test_table(LinkOperationalState, link_operstate, LINK_OPERSTATE);