]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: Tunnel add support to configure key for VTI/VTI6 (#3532)
authorSusant Sahani <ssahani@users.noreply.github.com>
Tue, 14 Jun 2016 17:11:57 +0000 (22:41 +0530)
committerLennart Poettering <lennart@poettering.net>
Tue, 14 Jun 2016 17:11:57 +0000 (19:11 +0200)
fixes #3298

man/systemd.netdev.xml
src/network/networkd-netdev-gperf.gperf
src/network/networkd-netdev-tunnel.c
src/network/networkd-netdev-tunnel.h

index cde5d659492b028e063e5aec241fee39dbb89214..3cc58ca854d566537deadceea0c7732bb6f024fd 100644 (file)
         </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>
index a9512cd77b6f0c438517baf0f2d8a63db1a5baf4..bf93b0d9fa07fbc8758d624c54bff7381f9f55b6 100644 (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)
index 7aaa041ba36093c639bd42195348779b72563654..58dec36c9adbc19b61ad0aab90a6bd5861f199e9 100644 (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,
index 7d31e7b68702c2c443bc28b4f4f656f98628db94..32a46bd82f6c16024265e680f0cdbdab7aa072de 100644 (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);