networkd: Tunnel add support to configure key for VTI/VTI6 (#3532)

fixes #3298
This commit is contained in:
Susant Sahani 2016-06-14 22:41:57 +05:30 committed by Lennart Poettering
parent 91bb59b4b1
commit 1d7100298c
4 changed files with 114 additions and 0 deletions

View file

@ -638,6 +638,33 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Key=</varname></term>
<listitem>
<para>The <varname>Key=</varname> parameter specifies the same key to use in
both directions (<varname>InputKey=</varname> and <varname>OutputKey=</varname>).
The <varname>Key=</varname> is either a number or an IPv4 address-like dotted quad.
It is used as mark-configured SAD/SPD entry as part of the lookup key (both in data
and control path) in ip xfrm (framework used to implement IPsec protocol).
See <ulink url="http://man7.org/linux/man-pages/man8/ip-xfrm.8.html">
ip-xfrm - transform configuration</ulink> for details. It is only used for VTI/VTI6
tunnels.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>InputKey=</varname></term>
<listitem>
<para>The <varname>InputKey=</varname> parameter specifies the key to use for input.
The format is same as <varname>Key=</varname>. It is only used for VTI/VTI6 tunnels.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>OutputKey=</varname></term>
<listitem>
<para>The <varname>OutputKey=</varname> parameter specifies the key to use for output.
The format is same as <varname>Key=</varname>. It is only used for VTI/VTI6 tunnels.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Mode=</varname></term>
<listitem>

View file

@ -42,6 +42,9 @@ Tunnel.Local, config_parse_tunnel_address, 0,
Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote)
Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos)
Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key)
Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey)
Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey)
Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc)
Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode)
Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, offsetof(Tunnel, ipv6_flowlabel)

View file

@ -200,6 +200,33 @@ static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netl
return r;
}
static int netdev_vti_fill_message_key(NetDev *netdev, Link *link, sd_netlink_message *m) {
Tunnel *t = VTI(netdev);
uint32_t ikey, okey;
int r;
assert(link);
assert(m);
assert(t);
if (t->key != 0)
ikey = okey = htobe32(t->key);
else {
ikey = htobe32(t->ikey);
okey = htobe32(t->okey);
}
r = sd_netlink_message_append_u32(m, IFLA_VTI_IKEY, ikey);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VTI_IKEY attribute: %m");
r = sd_netlink_message_append_u32(m, IFLA_VTI_OKEY, okey);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VTI_OKEY attribute: %m");
return 0;
}
static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
Tunnel *t = VTI(netdev);
int r;
@ -214,6 +241,10 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
r = netdev_vti_fill_message_key(netdev, link, m);
if (r < 0)
return r;
r = sd_netlink_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
@ -239,6 +270,10 @@ static int netdev_vti6_fill_message_create(NetDev *netdev, Link *link, sd_netlin
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
r = netdev_vti_fill_message_key(netdev, link, m);
if (r < 0)
return r;
r = sd_netlink_message_append_in6_addr(m, IFLA_VTI_LOCAL, &t->local.in6);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
@ -413,6 +448,46 @@ int config_parse_tunnel_address(const char *unit,
return 0;
}
int config_parse_tunnel_key(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
union in_addr_union buffer;
Tunnel *t = userdata;
uint32_t k;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = in_addr_from_string(AF_INET, rvalue, &buffer);
if (r < 0) {
r = safe_atou32(rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse tunnel key ignoring assignment: %s", rvalue);
return 0;
}
} else
k = be32toh(buffer.in.s_addr);
if (streq(lvalue, "Key"))
t->key = k;
else if (streq(lvalue, "InputKey"))
t->ikey = k;
else
t->okey = k;
return 0;
}
int config_parse_ipv6_flowlabel(const char* unit,
const char *filename,
unsigned line,

View file

@ -49,6 +49,10 @@ typedef struct Tunnel {
unsigned tos;
unsigned flags;
uint32_t key;
uint32_t ikey;
uint32_t okey;
union in_addr_union local;
union in_addr_union remote;
@ -108,3 +112,8 @@ int config_parse_encap_limit(const char *unit, const char *filename,
unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data,
void *userdata);
int config_parse_tunnel_key(const char *unit, const char *filename,
unsigned line, const char *section,
unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data,
void *userdata);