https://wiki.archlinux.org/api.php?action=feedcontributions&user=Leophys&feedformat=atomArchWiki - User contributions [en]2024-03-29T01:13:37ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=VLAN&diff=483312VLAN2017-07-29T23:05:17Z<p>Leophys: Corrected wrong unit extension .netdev -> .network after "You'll have to have associated .network files for each .netdev to handle addressing and ..."</p>
<hr />
<div>[[Category:Networking]]<br />
[[ja:VLAN]]<br />
[[ru:VLAN]]<br />
[[zh-hans:VLAN]]<br />
{{Related articles start}}<br />
{{Related|Network Configuration}}<br />
{{Related|systemd-networkd}}<br />
{{Related|Netctl}}<br />
{{Related articles end}}<br />
<br />
Virtual LANs give you the ability to sub-divide a LAN. Linux can accept '''VLAN''' tagged traffic and presents each '''VLAN ID''' as a different network interface (eg: {{ic|eth0.100}} for '''VLAN ID''' {{ic|100}})<br />
<br />
This article explains how to configure a VLAN using {{Pkg|iproute2}} and [[systemd-networkd]] or [[netctl]].<br />
<br />
==Configuration==<br />
Previously Arch Linux used the {{ic|vconfig}} command to setup VLANs. This had been superseded by the {{ic|ip}} command. Make sure you have {{Pkg|iproute2}} installed.<br />
<br />
In the following examples, lets assume the '''interface''' is {{ic|eth0}}, the assigned '''name''' is {{ic|eth0.100}} and the '''vlan id''' is {{ic|100}}.<br />
===Create the VLAN device===<br />
<br />
Add the VLAN with the following command:<br />
<br />
# ip link add link eth0 name eth0.100 type vlan id 100<br />
<br />
Run {{ic|ip link}} to confirm that it has been created. <br />
<br />
This interface behaves like a normal interface. All traffic routed to it will go through the master interface (in this example, {{ic|eth0}}) but with a VLAN tag. Only VLAN aware devices can accept them if configured correctly else the traffic is dropped. <br />
<br />
Using a '''name''' like {{ic|eth0.100}} is just convention and not enforced; you can alternatively use {{ic|eth0_100}} or something descriptive like {{ic|IPTV}}. To see the VLAN ID on an interface, in case you used an unconventional name:<br />
<br />
# ip -d link show eth0.100<br />
<br />
The {{ic|-d}} flag shows full details on an interface:<br />
<br />
# ip -d addr show<br />
4: eno1.100@eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default <br />
link/ether 96:4a:9c:84:36:51 brd ff:ff:ff:ff:ff:ff promiscuity 0 <br />
'''vlan protocol 802.1Q id 100 <REORDER_HDR>''' <br />
inet6 fe80::944a:9cff:fe84:3651/64 scope link <br />
valid_lft forever preferred_lft forever<br />
<br />
===Add an IP===<br />
Now add an IPv4 address to the just created vlan link, and activate the link:<br />
{{bc|<br />
# ip addr add 192.168.100.1/24 brd 192.168.100.255 dev eth0.100<br />
# ip link set dev eth0.100 up<br />
}}<br />
===Turning down the device===<br />
To cleanly shutdown the setting before you remove the link, you can do:<br />
{{bc|# ip link set dev eth0.100 down}}<br />
===Removing the device===<br />
Removing a VLAN interface is significantly less convoluted<br />
{{bc|# ip link delete eth0.100}}<br />
<br />
=== Starting at boot ===<br />
<br />
==== systemd-networkd single interface ====<br />
<br />
Use the following configuration files (Remember that systemd config files are case sensitive!):<br />
<br />
{{hc|/etc/systemd/network/''eno1''.network|<nowiki><br />
[Match]<br />
Name=eno1<br />
<br />
[Network]<br />
DHCP=ipv4<br />
;these are arbitrary names, but must match the *.netdev and *.network files<br />
VLAN=eno1.100<br />
VLAN=eno1.200<br />
</nowiki>}}<br />
<br />
{{hc|/etc/systemd/network/''eno1.100''.netdev|<nowiki><br />
[NetDev]<br />
Name=eno1.100<br />
Kind=vlan<br />
<br />
[VLAN]<br />
Id=100<br />
</nowiki>}}<br />
<br />
{{hc|/etc/systemd/network/''eno1.200''.netdev|<nowiki><br />
[NetDev]<br />
Name=eno1.200<br />
Kind=vlan<br />
<br />
[VLAN]<br />
Id=200<br />
</nowiki>}}<br />
<br />
You'll have to have associated .network files for each .netdev to handle addressing and routing. For example, to set the eno1.100 interface with a static IP and the eno1.200 interface with DHCP (but ignoring the supplied default route), use:<br />
<br />
{{hc|/etc/systemd/network/''eno1.100''.network|<nowiki><br />
[Match]<br />
Name=eno1.100<br />
<br />
[Network]<br />
DHCP=no<br />
Address=192.168.0.25/24<br />
</nowiki>}}<br />
<br />
{{hc|/etc/systemd/network/''eno1.200''.network|<nowiki><br />
[Match]<br />
Name=eno1.200<br />
<br />
[Network]<br />
DHCP=yes<br />
<br />
[DHCP]<br />
UseRoutes=false<br />
</nowiki>}}<br />
<br />
Then [[enable]] {{ic|systemd-networkd.service}}. See [[systemd-networkd]] for details.<br />
<br />
==== systemd-networkd bonded interface ====<br />
<br />
Similar to above, you're just going to stack more of the concepts in place. You'll want to ensure that you've got a bond set up in your switch and also make sure its a trunk with tagged vlans corresponding to what you create below. Convention would be to create a bond interface with the name {{ic|bond0}}, however there is a known issue where the {{ic|bonding}} module, when loaded, creates a bond device of the name {{ic|bond0}} which systemd then refuses to configure (as systemd tries to respectfully leave alone any device it did not create). <br />
<br />
{{Tip|To prevent the {{ic|bonding}} module to create an initial {{ic|bond0}} interface, set the {{ic|max_bonds}} option of the bonding module to {{ic|0}} (default value is {{ic|1}}):<br />
{{hc|/etc/modprobe.d/bonding.conf|2=options bonding max_bonds=0}}<br />
See [[Kernel modules#Setting module options]] and [https://www.kernel.org/doc/Documentation/networking/bonding.txt Linux Ethernet Bonding Driver HOWTO (Kernel Documentation)]for details.}}<br />
<br />
For the purposes of this write up, we are going to use {{ic|''bondname''}} and you can make the choice yourself.<br />
<br />
First, we create the bond device:<br />
<br />
{{hc|/etc/systemd/network/''bondname''.netdev|2=<br />
[NetDev]<br />
Name=''bondname''<br />
Kind=bond<br />
<br />
[Bond]<br />
Mode=802.3ad<br />
LACPTransmitRate=fast<br />
}}<br />
<br />
Now create a .network directive that references the vlans and interface carriers. In this case we'll use the convention for a dual port fiber module:<br />
<br />
{{hc|/etc/systemd/network/''bondname''.network|2=<br />
[Match]<br />
Name=''bondname''<br />
<br />
[Network]<br />
VLAN=vlan10<br />
VLAN=vlan20<br />
VLAN=vlan30<br />
BindCarrier=''enp3s0f0 enp3s0f1''<br />
}}<br />
<br />
We're using the vlan<number> naming convention here, you can use something else but realize that this is a named reference so you'll have to have a corresponding set of files with the same name.<br />
<br />
We'll now set up the physical network interfaces:<br />
<br />
{{hc|/etc/systemd/network/''enp3s0f0''.network|2=<br />
[Match]<br />
Name=''enp3s0f0''<br />
<br />
[Network]<br />
Bond=''bondname''<br />
}}<br />
<br />
{{hc|/etc/systemd/network/''enp3s0f1''.network|2=<br />
[Match]<br />
Name=''enp3s0f1''<br />
<br />
[Network]<br />
Bond=''bondname''<br />
}}<br />
<br />
At this time you could reboot, and likely should, because the bonded interface is created at boot time. Restarting systemd-networkd will consume changes from these files typically, but device creation seems to occur at startup.<br />
<br />
We will now set up the VLANs. You should be aware that having multiple VLANs can result in a situation where your machine has multiple default routes, so you'll need to specify a Destination directive in the network directives to ensure that only one VLAN is being used for a default route. In this case we'll use the VLAN with an ID of 10 as our default route.<br />
<br />
{{hc|/etc/systemd/network/''vlan10''.netdev|2=<br />
[NetDev]<br />
Name=vlan10<br />
Kind=vlan<br />
<br />
[VLAN]<br />
Id=10<br />
}}<br />
<br />
Now create the associated network directive to set an address:<br />
<br />
{{hc|/etc/systemd/network/''vlan10''.network|2=<br />
[Match]<br />
Name=vlan10<br />
<br />
[Network]<br />
VLAN=vlan10<br />
<br />
[Address]<br />
Address=10.10.10.2/24<br />
<br />
[Route]<br />
Destination=0.0.0.0/0<br />
Gateway=10.10.10.1<br />
}}<br />
<br />
We'll create a similar pair of files for the VLAN with an ID of 20:<br />
<br />
{{hc|/etc/systemd/network/''vlan20''.netdev|2=<br />
[NetDev]<br />
Name=vlan20<br />
Kind=vlan<br />
<br />
[VLAN]<br />
Id=20<br />
}}<br />
<br />
<br />
{{hc|/etc/systemd/network/''vlan20''.network|2=<br />
[Match]<br />
Name=vlan20<br />
<br />
[Network]<br />
VLAN=vlan20<br />
<br />
[Address]<br />
Address=10.10.20.2/24<br />
<br />
[Route]<br />
Destination=10.10.20.0/24<br />
Gateway=10.10.20.1<br />
}}<br />
<br />
And again for the VLAN with an ID of 30:<br />
<br />
{{hc|/etc/systemd/network/''vlan30''.netdev|2=<br />
[NetDev]<br />
Name=vlan30<br />
Kind=vlan<br />
<br />
[VLAN]<br />
Id=30<br />
}}<br />
<br />
{{hc|/etc/systemd/network/''vlan30''.network|2=<br />
[Match]<br />
Name=vlan30<br />
<br />
[Network]<br />
VLAN=vlan30<br />
<br />
[Address]<br />
Address=10.10.30.2/24<br />
<br />
[Route]<br />
Destination=10.10.30.0/24<br />
Gateway=10.10.30.1<br />
}}<br />
<br />
Note that the Destination on {{ic|vlan10}} is set to {{ic|0.0.0.0/0}}, which will match all outbound, becoming the default route.<br />
<br />
==== netctl ====<br />
<br />
You can use [[netctl]] for this purpose, see the self-explanatory example profiles in {{ic|/etc/netctl/examples/vlan-{dhcp,static} }}.<br />
<br />
==Troubleshooting==<br />
===udev renames the virtual devices===<br />
An annoyance is that [[udev]] may try to rename virtual devices as they are added, thus ignoring the '''name''' configured for them (in this case {{ic|eth0.100}}).<br />
<br />
For instance, if the following commands are issued: <br />
{{bc|<br />
# ip link add link eth0 name eth0.100 type vlan id 100<br />
# ip link show <br />
}}<br />
This could generate the following output: <br />
{{bc|<nowiki><br />
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN <br />
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00<br />
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000<br />
link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff<br />
3: rename1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state DOWN <br />
link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff<br />
</nowiki>}}<br />
'''udev''' has ignored the configured virtual interface name {{ic|eth0.100}} and autonamed it '''rename1'''.<br />
<br />
The solution is to edit {{ic|/etc/udev/rules.d/network_persistent.rules}} and append '''DRIVERS=="?*"''' to the end of the physical interface's configuration line.<br />
<br />
For example, for the interface '''aa:bb:cc:dd:ee:ff''' (eth0): <br />
{{hc|/etc/udev/rules.d/network_persistent.rules|<nowiki><br />
SUBSYSTEM=="net", ATTR{address}=="aa:bb:cc:dd:ee:ff", NAME="eth0", DRIVERS=="?*"<br />
</nowiki>}}<br />
<br />
A reboot should mean that VLANs configure correctly with the names assigned to them.</div>Leophys