Configuring Bonded Interfaces and VLANs Together on RHEL 9

bonded interfaces VLANs RHEL 9

Learn how to configure a bonded interface with VLAN tagging on RHEL 9: a step‑by‑step guide using nmcli and nmstatectl, architectural best practices, troubleshooting tips, and examples.

Table of Contents

🔈Introduction

In modern data centers, combining interface bonding (link aggregation or redundancy) with 802.1Q VLAN tagging is a common requirement. In RHEL 9, you can create a bond of physical NICs and then tag VLANs on top of that bond (or, less commonly, bond inside VLANs, though that setup is generally discouraged). This post walks you through the recommended patterns, CLI examples, pitfalls, and verification steps — so you can reliably deploy redundant, trunked network setups.


✅ Design Patterns & Best Practices

Before diving into commands, it’s useful to understand the architectural choices and what Red Hat supports.

👉 Common deployment topologies

  • Bond → VLANs
    You create a bond interface (e.g. bond0) aggregating two or more NICs. Then you create VLAN subinterfaces on that bond: bond0.10, bond0.20, etc. This is the most widely used and supported pattern.
  • VLANs → Bond (less recommended)
    You create VLAN devices on physical NICs, then bond those VLAN interfaces. This is generally unsupported or discouraged because it complicates failover semantics and may violate Red Hat’s support boundaries.
  • Bridge + Bond + VLAN
    If you also need a bridge (e.g. for virtual machines), you can interpose a bridge between bond and VLANs. For example: bond0br0 (bridge) → br0.10 or bridge VLAN-aware. This is more complex and has additional configuration implications.
💡 Key Red Hat caveat: if you place VLANs on bond interfaces, make sure the bond is not using fail_over_mac=follow, because VLAN subinterfaces can’t adapt their MAC easily. Also, the physical switch ports must be configured as trunks passing all required VLANs (or tagged appropriately) based on the bond mode.
PatternSupported / Recommended?ProsRisks / Drawbacks
Bond → VLANs✅ StandardClean, simple, predictable failoverNone if properly configured
VLANs → Bond⚠️ Not supportedTheoretically symmetrical taggingSupport issues, MAC/failover problems
Bond + Bridge + VLAN⚠️ ConditionalUseful for VM networksMore complexity, bridging pitfalls
💡 NOTE: In almost all cases, Bond → VLAN is the recommended pattern on RHEL 9.

▶️ Step‑by‑Step: Bond + VLAN using nmcli

Below is a sample workflow using NetworkManager’s nmcli, the preferred method in RHEL 9. (Avoid legacy ifcfg files when possible, since keyfile / NM is the modern approach.)

✅ Create the bond interface

				
					nmcli connection add type bond con-name bond0 ifname bond0 bond.options "mode=802.3ad,miimon=100, lacp-rate=fast"
				
			

This creates a bond named bond0 in 802.3ad (LACP) mode. You could also choose active-backup, balance-xor, balance-alb, etc. Add member interfaces:

				
					nmcli connection add type ethernet con-name slave-eth1 ifname enp1s0 master bond0
				
			
				
					nmcli connection add type ethernet con-name slave-eth2 ifname enp1s0 master bond0
				
			

Enable auto‑connect:

				
					nmcli connection modify bond0 connection.autoconnect-ports yes
				
			
				
					nmcli connection modify slave-eth1 connection.autoconnect yes
				
			
				
					nmcli connection modify slave-eth2 connection.autoconnect yes
				
			

Bring up the bond (this starts slaves as needed):

				
					nmcli connection up bond0
				
			

You can verify:

				
					cat /proc/net/bonding/bond0
				
			

✅ Create VLAN(s) on the bond

Let’s say you need VLAN 10 and VLAN 20. Using nmcli, you do:

				
					nmcli connection add type vlan con-name vlan10 ifname bond0.10 dev bond0 \
  vlan.id 10 ipv4.method manual ipv4.addresses 10.10.10.10/24 \
  ipv4.gateway 10.10.10.1
				
			
				
					nmcli connection add type vlan con-name vlan20 ifname bond0.20 dev bond0 \
  vlan.id 20 ipv4.method manual ipv4.addresses 10.10.20.10/24 \
  ipv4.gateway 10.10.20.1
				
			

Or, if you prefer DHCP:

				
					nmcli connection add type vlan con-name vlan10 ifname bond0.10 dev bond0 \
  vlan.id 10 ipv4.method auto
				
			

After adding, bring them up:

				
					nmcli connection up vlan10
				
			
				
					nmcli connection up vlan20
				
			

✅ Verification & troubleshooting

  • Check link and state:
				
					ip -d link show bond0.10
				
			
  • Ensure VLAN tags are active:
				
					bridge vlan show
				
			
  • Inspect nmcli list:
				
					nmcli connection show --active
				
			
  • Use cat /proc/net/bonding/bond0 to confirm bonding behavior.

If VLAN subinterfaces are down, one common cause is the bond not being active or slaves not linked. Another is the switch mismatch (e.g. switch using untagged or mismatched VLANs).


▶️ Alternative: Using nmstatectl (YAML-driven)

For automation or declarative setups, nmstatectl is a powerful tool. Red Hat documentation includes examples of defining a bond and VLANs in YAML and applying via nmstatectl apply. Example snippet:

				
					interfaces:
  - name: enp1s0
    type: ethernet
  - name: enp2s0
    type: ethernet

bonds:
  - name: bond0
    options:
      mode: 802.3ad
      miimon: 100
    ports: [enp1s0, enp2s0]

vlans:
  - name: bond0.10
    id: 10
    device: bond0
    ipv4:
      address:
        - 10.10.10.10/24
      gateway: 10.10.10.1
  - name: bond0.20
    id: 20
    device: bond0
    ipv4:
      address:
        - 10.10.20.10/24
      gateway: 10.10.20.1
				
			

Then:

				
					nmstatectl apply config.yaml
				
			

If something fails, nmstatectl attempts rollback to maintain stability.


▶️ Legacy / Keyfile fallback (ifcfg-style)

Though RHEL 9 encourages NM keyfiles over legacy ifcfg- scripts, you may still find examples. Use caution, as some constructs may be deprecated or unsupported in future. Example files:

📁 /etc/sysconfig/network-scripts/ifcfg-bond0

				
					DEVICE=bond0
NAME=bond0
TYPE=Bond
ONBOOT=yes
BOOTPROTO=none
BONDING_OPTS="mode=802.3ad miimon=100 lacp_rate=fast"
				
			

📁 /etc/sysconfig/network-scripts/ifcfg-bond0.10

				
					DEVICE=bond0.10
VLAN=yes
TYPE=Vlan
PHYSDEV=bond0
VLAN_ID=10
ONBOOT=yes
BOOTPROTO=static
IPADDR=10.10.10.10
PREFIX=24
GATEWAY=10.10.10.1
				
			

After creating these, run:

				
					nmcli connection reload
				
			
				
					nmcli connection up bond0
				
			
				
					nmcli connection up bond0.10
				
			
💡 NOTE: Using fail_over_mac=follow or certain VLAN-on-slave constructs may break in practice.

🧰 Common Pitfalls & Troubleshooting

IssueSymptomProbable CauseRemedy
VLAN interface lowerlayerdownVLAN subinterface not UPBond not active / slaves downCheck bond status, link LEDs, switch trunk config
No LACP trafficBond shows only one member activeSwitch not configured for LACP or mismatchConfigure switch ports in LACP, ensure same mode
MAC address changes / VLAN issuesVLAN interfaces lose connectivityfail_over_mac=follow or improper MAC behaviorUse default bonding MAC mode, avoid follow
Unsupported “VLANs → bond”Lack of support or unpredictable behaviorThis mode is not recommended in RHELRearchitect to “bond → VLAN” topology
Keyfile vs legacy conflictsDuplicate configs or race conditionsHaving both keyfile and ifcfg filesUse only one method (preferably NM keyfile approach)

🔌 Switch-side configuration

  • If using 802.3ad mode (LACP), ensure switch ports are in a matching link aggregation group (trunk).
  • Ensure switch allows all VLANs you need (tagged).
  • For active-backup mode, switch ports do not need special LACP settings.
  • Avoid mixing tagged and untagged (native VLAN) unless by design.

🔄 Example Complete Walkthrough

Let’s assume the following:

  • Physical NICs: enp3s0, enp4s0
  • VLANs needed: 100, 200, 300
  • IPs: 10.0.100.10/24, 10.0.200.10/24, 10.0.300.10/24
  • Gateway: 10.0.X.1 for each VLAN

Commands (nmcli style as the root user):

				
					nmcli connection add type bond con-name bond0 ifname bond0 bond.options "mode=802.3ad,miimon=100"
nmcli connection add type ethernet con-name slave1 ifname enp3s0 master bond0
nmcli connection add type ethernet con-name slave2 ifname enp4s0 master bond0
nmcli connection modify bond0 connection.autoconnect-ports yes

for vlan in 100 200 300; do
  nmcli connection add type vlan \
    con-name vlan${vlan} ifname bond0.${vlan} dev bond0 vlan.id ${vlan} \
    ipv4.method manual ipv4.addresses 10.0.${vlan}.10/24 ipv4.gateway 10.0.${vlan}.1
done

nmcli connection up bond0
for vlan in 100 200 300; do
  nmcli connection up vlan${vlan}
done
				
			

Then verify:

				
					ip -d link show bond0.100
				
			
				
					bridge vlan show
				
			
				
					cat /proc/net/bonding/bond0
				
			
				
					nmcli connection show --active
				
			

You should see the bond active, slaves joined, VLAN tags in place, and IPs assigned accordingly.


🏁 Summary & Recommendations

To ensure a stable and supported network configuration in RHEL 9, combining bonded interfaces with VLAN tagging should follow best practices. Whether you’re deploying for high availability, throughput, or virtual environments, adhering to the recommended topology and tools will reduce complexity and improve long-term maintainability.

  • Always favor Bond → VLAN as your topology.
  • Use nmcli (or nmstatectl) rather than legacy ifcfg scripts.
  • Make sure the physical switch is configured appropriately (LACP, trunking, VLANs).
  • Avoid unsupported or borderline features like bonding VLAN interfaces on slaves or using fail_over_mac=follow.
  • Use testing and verification (via bridge, ip -d, and /proc/net/bonding/…) to confirm behavior.
  • Automate with nmstatectl or RHEL system roles if deploying at scale. 

With these steps, you can confidently implement redundant, tagged, and performant network setups on RHEL 9.

Did you find this article helpful? Your feedback is invaluable to us! Feel free to share this post with those who may benefit, and let us know your thoughts in the comments section below.


📕 Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *