Linux Networking·7 min read·

VLANs on Linux: Tagging Interfaces with ip link

Create 802.1Q VLAN interfaces on Linux with ip link and use them with bridges for isolated virtual network segments.

NB

Netbay Engineering

Netbay Engineering

On this page

VLANs (Virtual Local Area Networks) allow you to carve a single physical network into multiple isolated Layer 2 segments. Each VLAN is identified by a numeric tag, and switches use that tag to forward frames only within the same VLAN. On Linux, you create VLAN interfaces on top of a physical NIC, and those interfaces behave like separate networks sharing the same hardware port. This is a foundational skill for anyone managing virtualized servers or complex network topologies.

one physical port, many tagged VLANs eth0 native VLAN (untagged) eth0.100 tag 100 eth0.200 tag 200 eth0.300 tag 300 trunk port to switch

Understanding 802.1Q VLANs

The 802.1Q standard inserts a 4-byte tag into each Ethernet frame. The tag contains a 12-bit VLAN identifier, so you can have up to 4094 usable VLANs. When a frame travels on a trunk port, it carries its VLAN tag. When it reaches an access port, the switch either adds a tag (ingress) or strips it (egress). On Linux, a VLAN interface does exactly what an access port or a tagged trunk connection does depending on how you configure it.

The relationship matters a lot on a VPS. If your provider exposes a single untagged NIC, you can still create tagged subinterfaces on top of it. The physical NIC carries the untagged native VLAN, and each VLAN interface you create carries a specific tag. This lets a single virtual port emulate multiple switch ports.

Creating VLAN Interfaces

The ip command creates VLAN interfaces with the link add subcommand. Here is the basic pattern.

bash
ip link add link eth0 name eth0.100 type vlan id 100
ip link set eth0.100 up
ip addr add 10.100.0.5/24 dev eth0.100

This creates an interface called eth0.100 that tags every outgoing frame with VLAN 100 and strips the tag from incoming frames. The interface holds its own IP address, so the host can participate in the 100 network while eth0 stays on the native VLAN.

You can see all your VLAN interfaces with ip link show type vlan and inspect the tag with vlan show.

bash
ip -d link show eth0.100
ip link show type vlan

The -d flag shows extended attributes including the VLAN ID registered with the interface. This is the fastest way to confirm which VLAN a tagged interface belongs to.

Combining VLANs with Bridges

The real power of VLAN tagging appears when you combine it with bridges. You can tag a bridge and then assign the bridge to VMs or containers, giving them access to a specific VLAN without giving them physical interface access.

bash
ip link add link eth0 name eth0.200 type vlan id 200
ip link add name br200 type bridge
ip link set eth0.200 master br200
ip link set vnet0 master br200
ip link set eth0.200 up
ip link set br200 up

Now any virtual machine connected through vnet0 sits in VLAN 200. Traffic from the VM is tagged when it leaves through eth0.200, and untagged VM traffic entering the bridge is tagged before leaving the physical port. This is exactly how hypervisor networks isolate tenants on shared infrastructure.

For a persistent configuration, define the VLAN and bridge in Netplan. The YAML below creates a tagged VLAN interface and attaches a bridge to it.

yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: false
  vlans:
    eth0.300:
      id: 300
      link: eth0
  bridges:
    br300:
      interfaces:
        - eth0.300
      addresses:
        - 10.300.0.1/24

With netplan apply this brings up a bridge that reaches the entire VLAN 300 subnet, and any container or VM attached to br300 joins that network automatically.

The Native VLAN Trap

Every Linux VLAN interface tags its traffic. There is no such thing as an untagged VLAN interface. The native VLAN is handled by the raw physical interface eth0, not by a tagged subinterface. This is a common source of confusion. If you create an eth0.1 on the native VLAN, your frames carry a tag the switch may not expect, and connectivity silently breaks.

Always confirm what the native VLAN is on your switch or provider infrastructure. On a typical VPS eth0 is native, and you only create tagged subinterfaces for VLANs you are explicitly granted. Running vlan filtering on a Linux bridge also lets you designate untagged ports, which gives you more control than simple tagged subinterfaces.

VLAN Routing Between Segments

VLANs isolate Layer 2, but they do not automatically route between each other. To reach a host in VLAN 100 from VLAN 200, you need a router. On Linux you can make the host itself the router by assigning IP addresses to each VLAN interface and enabling IP forwarding.

bash
sysctl -w net.ipv4.ip_forward=1
ip addr add 10.100.0.1/24 dev eth0.100
ip addr add 10.200.0.1/24 dev eth0.200
ip route add 10.200.0.0/24 dev eth0.200

Now the Linux host can forward packets between VLAN 100 and VLAN 200, acting as a software router. Combined with firewall rules, this is a complete inter-VLAN routing solution, all doable with standard tools and no proprietary drivers.

Troubleshooting VLAN Issues

When a VLAN interface does not pass traffic, the first step is to check the tag is actually applied. Use tcpdump to capture the frames and inspect the VLAN header.

bash
tcpdump -i eth0.100 -nn -e

The -e flag includes Ethernet-level headers in the output, so you can see the 802.1Q tag. If the tag is missing, the interface was never attached to the physical NIC properly, or the physical NIC lacks VLAN offload support and the kernel is stripping the tag in software. Check ethtool -k eth0 to see if vlan-tag-offload is on.

VLAN configuration is a powerful tool that lets you build production-grade network isolation on standard Linux tools. You can put these techniques to work on a Netbay VPS at netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance