networkd: support 6rd tunnel netdev setup.
authorDavid Anderson <dave@natulte.net>
Wed, 7 Nov 2018 05:27:09 +0000 (21:27 -0800)
committerDavid Anderson <dave@natulte.net>
Sat, 10 Nov 2018 01:56:33 +0000 (17:56 -0800)
man/systemd.netdev.xml
src/network/netdev/netdev-gperf.gperf
src/network/netdev/tunnel.c
src/network/netdev/tunnel.h

index 11baf3c..3a60b99 100644 (file)
           <para>Accepts the same key as <literal>[FooOverUDP]</literal></para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><varname>IPv6RapidDeploymentPrefix=</varname></term>
+        <listitem>
+          <para>Reconfigure the tunnel for <ulink url="https://tools.ietf.org/html/rfc5569">IPv6 Rapid
+          Deployment</ulink>, also known as 6rd. The value is an ISP-specific IPv6 prefix with a non-zero length. Only
+          applicable to SIT tunnels.</para>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
@@ -1520,6 +1528,18 @@ Remote=10.65.223.239</programlisting>
     </example>
 
     <example>
+      <title>/etc/systemd/network/25-6rd.netdev</title>
+      <programlisting>[NetDev]
+Name=6rd-tun
+Kind=sit
+MTUBytes=1480
+
+[Tunnel]
+Local=10.65.223.238
+IPv6RapidDeploymentPrefix=2602::/24</programlisting>
+    </example>
+
+    <example>
       <title>/etc/systemd/network/25-gre.netdev</title>
       <programlisting>[NetDev]
 Name=gre-tun
index 61d73e1..be7f004 100644 (file)
@@ -70,6 +70,7 @@ Tunnel.FooOverUDP,                 config_parse_bool,                    0,
 Tunnel.FOUDestinationPort,         config_parse_ip_port,                 0,                             offsetof(Tunnel, fou_destination_port)
 Tunnel.FOUSourcePort,              config_parse_ip_port,                 0,                             offsetof(Tunnel, encap_src_port)
 Tunnel.Encapsulation,              config_parse_fou_encap_type,          0,                             offsetof(Tunnel, fou_encap_type)
+Tunnel.IPv6RapidDeploymentPrefix,  config_parse_6rd_prefix,              0,                             0
 FooOverUDP.Protocol,               config_parse_uint8,                   0,                             offsetof(FouTunnel, fou_protocol)
 FooOverUDP.Encapsulation,          config_parse_fou_encap_type,          0,                             offsetof(FouTunnel, fou_encap_type)
 FooOverUDP.Port,                   config_parse_ip_port,                 0,                             offsetof(FouTunnel, port)
index 826c708..3464d8b 100644 (file)
@@ -114,6 +114,18 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink
         if (r < 0)
                 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_PMTUDISC attribute: %m");
 
+        if (t->sixrd_prefixlen > 0) {
+                r = sd_netlink_message_append_in6_addr(m, IFLA_IPTUN_6RD_PREFIX, &t->sixrd_prefix);
+                if (r < 0)
+                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_6RD_PREFIX attribute: %m");
+                /* u16 is deliberate here, even though we're passing a netmask that can never be >128. The kernel is
+                 * expecting to receive the prefixlen as a u16.
+                 */
+                r = sd_netlink_message_append_u16(m, IFLA_IPTUN_6RD_PREFIXLEN, t->sixrd_prefixlen);
+                if (r < 0)
+                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_6RD_PREFIXLEN attribute: %m");
+        }
+
         return r;
 }
 
@@ -617,6 +629,42 @@ int config_parse_encap_limit(const char* unit,
         return 0;
 }
 
+int config_parse_6rd_prefix(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) {
+        Tunnel *t = userdata;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        union in_addr_union p;
+        uint8_t l;
+        int r;
+
+        r = in_addr_prefix_from_string(rvalue, AF_INET6, &p, &l);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse 6rd prefix \"%s\", ignoring: %m", rvalue);
+                return 0;
+        }
+        if (l == 0) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "6rd prefix length of \"%s\" must be greater than zero, ignoring", rvalue);
+                return 0;
+        }
+
+        t->sixrd_prefix = p.in6;
+        t->sixrd_prefixlen = l;
+
+        return 0;
+}
+
 static void ipip_init(NetDev *n) {
         Tunnel *t = IPIP(n);
 
index 40ddb1c..24721e8 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "in-addr-util.h"
 
+#include "conf-parser.h"
 #include "netdev/netdev.h"
 #include "netdev/fou-tunnel.h"
 
@@ -50,6 +51,9 @@ typedef struct Tunnel {
 
         uint16_t encap_src_port;
         uint16_t fou_destination_port;
+
+        struct in6_addr sixrd_prefix;
+        uint8_t sixrd_prefixlen;
 } Tunnel;
 
 DEFINE_NETDEV_CAST(IPIP, Tunnel);
@@ -108,3 +112,5 @@ int config_parse_tunnel_key(const char *unit, const char *filename,
                             unsigned section_line, const char *lvalue,
                             int ltype, const char *rvalue, void *data,
                             void *userdata);
+
+CONFIG_PARSER_PROTOTYPE(config_parse_6rd_prefix);