Configure Linux ETS Traffic Classes with dcb ets

Get the bandwidth weights wrong in dcb ets set and the kernel will not stop you. Even though 33 + 33 + 34 must equal exactly 100 for the classes that use ETS, nothing checks your arithmetic for you. This guide gets you to a checked configuration: priorities mapped to traffic classes, a transmission selection algorithm chosen per class, and weights that actually add up. The examples use dcb from iproute2 6.1.0-1ubuntu6.4, as installed on Ubuntu here.

Allow about fifteen minutes for an interface you already understand, plus time to check the switch side too. You need iproute2, a DCB-capable network device, and permission to change its link settings. Reading help and showing settings are ordinary commands. Setting ETS is a privileged, service-disrupting operation: do it in a maintenance window, with an out-of-band route to the host kept open.

1. Check the installed syntax

Start with the local command rather than copying syntax from a different iproute2 release:

$ dcb ets help
Usage: dcb ets help

Usage: dcb ets show dev STRING
           [ willing ] [ ets-cap ] [ cbs ] [ tc-tsa ]
           [ reco-tc-tsa ] [ pg-bw ] [ tc-bw ] [ reco-tc-bw ]
           [ prio-tc ] [ reco-prio-tc ]

Usage: dcb ets set dev STRING
           [ willing { on | off } ]
           [ { tc-tsa | reco-tc-tsa } TSA-MAP ]
           [ { pg-bw | tc-bw | reco-tc-bw } BW-MAP ]
           [ { prio-tc | reco-prio-tc } PRIO-MAP ]

The map grammar is deliberately compact. Traffic classes and priorities are numbered 0 through 7. A map entry is a key, a colon, and a value, such as 2:ets, 2:25, or 5:1. The keyword all sets every key in one go, but later entries in the same command are what make your intended exceptions visible.

Checkpoint: record the interface name and version before making a change:

$ ip -br link
$ dcb -V
dcb utility, iproute2-6.1.0

2. Inspect the current ETS state

Replace INTERFACE with the exact device name. This is read-only and does not need sudo:

$ dcb ets show dev INTERFACE
willing off
ets-cap 8
cbs off
tc-tsa 0:strict 1:strict 2:strict 3:strict 4:strict 5:strict 6:strict 7:strict
tc-bw 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
prio-tc 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0

The exact lines and values are hardware-specific. An unsupported device can answer with something like Attribute read: Operation not supported; that tells you this interface does not expose ETS through the installed driver, it is not an invitation to force a write anyway.

Ask for selected fields when the full dump is more than you need:

$ dcb ets show dev INTERFACE prio-tc tc-tsa tc-bw

ets-cap reports how many ETS traffic classes the device supports. cbs reports whether the Credit Based Shaper algorithm is supported. The reco- fields are recommendation values from the peer-facing DCB configuration; the plain fields are what is actually configured locally.

3. Choose the priority-to-class map

A priority map decides which traffic class each packet priority lands in. The one-to-one map below is easy to inspect and works as a template, not as a universal policy:

$ sudo dcb ets set dev INTERFACE prio-tc \
    0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7

This changes the device immediately. It does not touch application traffic marking, switch queues, VLAN priorities, or a host firewall, and those all need to agree with your class plan separately. If several priorities should share one class, say so explicitly, for example 0:0 1:0 2:1 3:1.

Checkpoint: read back just the map and check every priority:

$ dcb ets show dev INTERFACE prio-tc
prio-tc 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7

4. Select ETS classes and allocate bandwidth

Mark the classes that use ETS with tc-tsa. The other algorithms available are strict, cbs, and vendor. Here classes 0, 1 and 2 share ETS, while classes 3 through 7 stay strict:

$ sudo dcb ets set dev INTERFACE \
    tc-tsa all:strict 0:ets 1:ets 2:ets \
    tc-bw all:0 0:33 1:33 2:34

For each traffic class, tc-bw is a percentage of available transmit bandwidth. Non-ETS classes must sit at zero. When at least one class uses ETS, the ETS weights must total exactly 100, no more, no less. In the example, 33 + 33 + 34 makes 100, so the command is internally consistent, and the kernel will not check your arithmetic for you if it is not.

Do not confuse tc-bw with pg-bw. The former assigns transmit bandwidth to traffic classes. The manpage describes pg-bw as receive-side bandwidth allocation for ETS ingress traffic classes, with the precise meaning left to hardware and driver. Set it only once you have confirmed how your device actually interprets it.

Checkpoint: verify the three related fields together:

$ dcb ets show dev INTERFACE tc-tsa tc-bw prio-tc
tc-tsa 0:ets 1:ets 2:ets 3:strict 4:strict 5:strict 6:strict 7:strict
tc-bw 0:33 1:33 2:34 3:0 4:0 5:0 6:0 7:0
prio-tc 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7

5. Decide whether willing mode belongs in the design

The willing flag controls whether the local host accepts configuration pushed by peer TLVs. It is a DCB negotiation choice, not a shortcut for keeping two arbitrary machines in sync. Leave it as it is unless your switch and host policy explicitly call for peer configuration:

$ dcb ets show dev INTERFACE willing
willing off

If that policy is documented, enable it with elevated privileges:

$ sudo dcb ets set dev INTERFACE willing on
$ dcb ets show dev INTERFACE willing
willing on

To undo just that change, set it back to off. To recover a broader experiment, rerun the saved pre-change commands or restore from your network management system. A link flap will not put old ETS values back for you.

6. Handle failures without guessing

A non-zero status means the operation failed. Check the interface, driver capability, and current state first:

$ printf 'status: %s\n' "$?"
status: 1
$ dcb ets show dev INTERFACE ets-cap cbs
$ ip -details link show dev INTERFACE

The common traps: an interface that is not DCB-capable, a class outside 0 through 7, a non-zero weight on a non-ETS class, or ETS weights that do not total 100. A device with no ETS classes at all may accept a total of zero, since no class is using ETS. Do not pile on sudo for a capability error; privilege cannot conjure hardware support that is not there.

Keep the switch and host definitions aligned. A successful dcb ets set proves the kernel accepted the request. It proves nothing about whether the peer switch shares the same priority map, whether traffic is actually marked as expected, or whether the resulting split matches what the application needs.

Done means