tc-cbs attaches Linux's Credit Based Shaper to a traffic class for Time Sensitive Networking, not general bandwidth limiting. You'll do that with tc and mqprio, then inspect the resulting qdisc.
Allow about 20 minutes for a planned change, plus time to calculate values for your actual link. You need the iproute2 package, a network interface with a traffic-class arrangement you understand, and administrator access for the change. The examples use eth0 as a placeholder, don't paste it unchanged into a production host.
Start with ordinary, read-only checks. This host has iproute2 version 6.1.0, package version 6.1.0-1ubuntu6.4. The local CBS manual page is dated 18 September 2017, so treat what's here as the installed interface's behaviour, not a promise about every future release:
$ tc -V
tc utility, iproute2-6.1.0, libbpf 1.3.0
$ tc qdisc show dev eth0
The second command shows the qdiscs currently attached to eth0. Record that output before changing anything, especially whether a root qdisc such as mqprio already exists and which class identifier maps to the traffic you intend to shape.
Checkpoint: You know the interface, the parent class, and how to restore the current qdisc configuration. If you don't, stop here, a traffic-control replacement can change packet scheduling immediately.
CBS needs idleslope, sendslope, hicredit and locredit. The slopes are in kilobits per second, the credit limits in bytes. CBS accumulates credit while packets wait and sends when credit is at least zero; with no waiting packet, credit returns to zero.
Choose an idle slope that represents the bandwidth for this class. The packet size calculation has to include everything: Ethernet headers, the frame check sequence, and physical-layer overhead such as the interpacket gap, preamble and start-of-frame delimiter. The manual's example treats a 284-byte payload as a 322-byte transmitted packet when there's no VLAN tag.
For a port transmit rate of port_transmit_rate, calculate:
sendslope = idleslope - port_transmit_rate
hicredit = max_interference_size * (idleslope / port_transmit_rate)
locredit = max_frame_size * (sendslope / port_transmit_rate)
The manual's representative values: an idle slope of 20,000 kilobits per second, a 1,000,000 kilobit-per-second port, a maximum interfering frame of 1,500 bytes, giving sendslope -980000, hicredit 30, and locredit -1470. Recalculate these for your own link, frame sizes, VLAN use and traffic classes. Don't copy them just because the interface happens to be called Ethernet.
CBS is normally installed below another qdisc that maps flows to traffic classes. The manual uses mqprio as its example. A complete parent setup might look like this:
# tc qdisc add dev eth0 handle 100: parent root mqprio num_tc 3 \
map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 \
queues 1@0 1@1 2@2 \
hw 0
This is an administrator command that changes live packet scheduling. It creates three traffic classes, maps priorities to them, assigns queue ranges, and requests software scheduling with hw 0. The parent class identifiers and queue layout have to match your NIC and your existing QoS design. If another root qdisc is already in use, don't add this on top of it.
Safety warning: Replacing a root qdisc can disrupt traffic and discard an existing shaping policy. Save the output of tc -s qdisc show dev eth0 and your host's network configuration first. There's no universal recovery command here, restore the exact qdisc definition your system used, don't just blindly delete the root qdisc.
In the manual's layout, traffic class number zero is reached through parent 100:4. The CBS command:
# tc qdisc replace dev eth0 parent 100:4 cbs \
locredit -1470 hicredit 30 sendslope -980000 idleslope 20000
replace when a qdisc may already sit there and you deliberately want CBS in that spot. If the parent identifier is wrong, tc fails rather than attaching CBS somewhere unintended.offload 1 asks CBS to try configuring the network interface so the controller runs the algorithm itself. The default is offload 0, use hardware offload only after checking the driver and device actually support it.Verify the live hierarchy and statistics:
$ tc -details qdisc show dev eth0
$ tc -s qdisc show dev eth0
Look for a CBS qdisc under the intended parent. Exact formatting and counters depend on iproute2 and the driver. A successful command and a visible qdisc prove attachment, nothing more, they don't prove your calculated rate or TSN latency target is correct.
Generate the class's expected traffic in a controlled test, then compare tc -s qdisc show dev eth0 before and after. Confirm the intended class's packet and byte counters increase, and check the application path separately, CBS only shapes packets that reach its qdisc.
Don't run an unrestricted high-rate test on a production link. Schedule it, watch link utilisation and application errors, and keep a second access path if you're touching the management interface. If the command fails, inspect the parent with tc -details class show dev eth0 and check the kernel and driver documentation for hardware queue limits.
Removing CBS is a service-affecting change. If you only need to remove the child qdisc, use the exact parent from your configuration:
# tc qdisc del dev eth0 parent 100:4
Recovery: This doesn't recreate the old shaping policy. Restore the saved parent and child definitions if the interface had a previous configuration. If a network manager, boot script or orchestration system owns the qdisc, make the persistent change there too, an ad-hoc tc command can disappear at the next reload.
If the link becomes unusable, use the out-of-band console or your documented recovery path. Deleting the root qdisc as a first reaction is a bad instinct, that can remove unrelated traffic classes and make diagnosis harder.
tc -details qdisc show and statistics confirm the live attachment and traffic path.