<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>
[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>
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");
if (!link->network->bridge &&
!link->network->bond &&
+ !link->network->vrf &&
hashmap_isempty(link->network->stacked_netdevs))
return link_joined(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,
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,
};
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);
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);
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)
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);
case NETDEV_KIND_BOND:
network->bond = netdev;
+ break;
+ case NETDEV_KIND_VRF:
+ network->vrf = netdev;
+
break;
case NETDEV_KIND_VLAN:
case NETDEV_KIND_MACVLAN:
NetDev *bridge;
NetDev *bond;
+ NetDev *vrf;
Hashmap *stacked_netdevs;
/* DHCP Client Support */