]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: vrf: add support for enslaving devices to VRFs 3511/head
authorAndreas Rammhold <andreas@rammhold.de>
Sun, 12 Jun 2016 23:05:49 +0000 (01:05 +0200)
committerAndreas Rammhold <andreas@rammhold.de>
Wed, 15 Jun 2016 22:25:06 +0000 (00:25 +0200)
man/systemd.network.xml
src/network/networkd-link.c
src/network/networkd-netdev-vrf.c
src/network/networkd-netdev.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h

index ea98c821fab6413ba9701f9d8ec2e7e081c8b0e5..edf227c13466fe3eaac2545e43f8e51f59d9b8a4 100644 (file)
             <para>The name of the bond to add the link to.</para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term><varname>VRF=</varname></term>
+          <listitem>
+            <para>The name of the VRF to add the link to.</para>
+          </listitem>
+        </varlistentry>
         <varlistentry>
           <term><varname>VLAN=</varname></term>
           <listitem>
@@ -1276,6 +1282,17 @@ Name=bond1
 
 [Network]
 DHCP=yes
+</programlisting>
+    </example>
+
+    <example>
+      <title>/etc/systemd/network/25-vrf.network</title>
+      <para>Add the bond1 interface to the VRF master interface vrf-test. This will redirect routes generated on this interface to be within the routing table defined during VRF creation. Traffic won't be redirected towards the VRFs routing table unless specific ip-rules are added.</para>
+      <programlisting>[Match]
+Name=bond1
+
+[Network]
+VRF=vrf-test
 </programlisting>
     </example>
 
index 044f934e5ffb5523d060adaf6e297c8fe59652ed..18426851805666fb6326c6e341648cd197970221 100644 (file)
@@ -1600,7 +1600,7 @@ static int link_up(Link *link) {
                 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
 
         /* set it free if not enslaved with networkd */
-        if (!link->network->bridge && !link->network->bond) {
+        if (!link->network->bridge && !link->network->bond && !link->network->vrf) {
                 r = sd_netlink_message_append_u32(req, IFLA_MASTER, 0);
                 if (r < 0)
                         return log_link_error_errno(link, r, "Could not append IFLA_MASTER attribute: %m");
@@ -2055,6 +2055,7 @@ static int link_enter_join_netdev(Link *link) {
 
         if (!link->network->bridge &&
             !link->network->bond &&
+            !link->network->vrf &&
             hashmap_isempty(link->network->stacked_netdevs))
                 return link_joined(link);
 
@@ -2101,6 +2102,26 @@ static int link_enter_join_netdev(Link *link) {
                 link->enslaving++;
         }
 
+        if (link->network->vrf) {
+                log_struct(LOG_DEBUG,
+                           LOG_LINK_INTERFACE(link),
+                           LOG_NETDEV_INTERFACE(link->network->vrf),
+                           LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->vrf->ifname),
+                           NULL);
+                r = netdev_join(link->network->vrf, link, netdev_join_handler);
+                if (r < 0) {
+                        log_struct_errno(LOG_WARNING, r,
+                                         LOG_LINK_INTERFACE(link),
+                                         LOG_NETDEV_INTERFACE(link->network->vrf),
+                                         LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->vrf->ifname),
+                                         NULL);
+                        link_enter_failed(link);
+                        return r;
+                }
+
+                link->enslaving++;
+        }
+
         HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
 
                 log_struct(LOG_DEBUG,
index 8bbb0aecb1eacb887f8b47a33ce8763a5f38c81d..89bd142e8cf6a73589fefd71df90e49b4777cb3a 100644 (file)
@@ -44,7 +44,7 @@ static int netdev_vrf_fill_message_create(NetDev *netdev, Link *link, sd_netlink
 
 const NetDevVTable vrf_vtable = {
         .object_size = sizeof(Vrf),
-        .sections = "Match\0NetDev\0VRF\0",
+        .sections = "NetDev\0VRF\0",
         .fill_message_create = netdev_vrf_fill_message_create,
         .create_type = NETDEV_CREATE_MASTER,
 };
index b55d76a53c65564aff1674e4e28f22cdc968ccba..b192884fd95ce71e069e15c75f38bab3f6e6face 100644 (file)
@@ -202,7 +202,7 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_h
         assert(netdev->state == NETDEV_STATE_READY);
         assert(netdev->manager);
         assert(netdev->manager->rtnl);
-        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
+        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF));
         assert(link);
         assert(callback);
 
@@ -285,7 +285,7 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t call
         assert(netdev);
         assert(netdev->manager);
         assert(netdev->manager->rtnl);
-        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
+        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF));
 
         if (netdev->state == NETDEV_STATE_READY) {
                 r = netdev_enslave_ready(netdev, link, callback);
index 0b0aa58f673e2dabdd6be51df1417b294e56927b..affc0d00e9610c5f9c53122ec9587b805122e6c7 100644 (file)
@@ -37,6 +37,7 @@ Network.MACVTAP,                        config_parse_netdev,
 Network.IPVLAN,                         config_parse_netdev,                            0,                             0
 Network.VXLAN,                          config_parse_netdev,                            0,                             0
 Network.Tunnel,                         config_parse_tunnel,                            0,                             0
+Network.VRF,                            config_parse_netdev,                            0,                             0
 Network.DHCP,                           config_parse_dhcp,                              0,                             offsetof(Network, dhcp)
 Network.DHCPServer,                     config_parse_bool,                              0,                             offsetof(Network, dhcp_server)
 Network.LinkLocalAddressing,            config_parse_address_family_boolean,            0,                             offsetof(Network, link_local)
index 84bdf75b38e16271c771f1f7a0fb152d81fceef3..2b764d4f24de9d02b621554c9d540b1e32d072dd 100644 (file)
@@ -244,8 +244,8 @@ void network_free(Network *network) {
         strv_free(network->bind_carrier);
 
         netdev_unref(network->bridge);
-
         netdev_unref(network->bond);
+        netdev_unref(network->vrf);
 
         HASHMAP_FOREACH(netdev, network->stacked_netdevs, i) {
                 hashmap_remove(network->stacked_netdevs, netdev->ifname);
@@ -470,6 +470,10 @@ int config_parse_netdev(const char *unit,
         case NETDEV_KIND_BOND:
                 network->bond = netdev;
 
+                break;
+        case NETDEV_KIND_VRF:
+                network->vrf = netdev;
+
                 break;
         case NETDEV_KIND_VLAN:
         case NETDEV_KIND_MACVLAN:
index 38688cc4005c3c2ae42621ca23a846dfb66626bf..08ee939faa0702d733506255bbde783ff17f82d6 100644 (file)
@@ -104,6 +104,7 @@ struct Network {
 
         NetDev *bridge;
         NetDev *bond;
+        NetDev *vrf;
         Hashmap *stacked_netdevs;
 
         /* DHCP Client Support */