Home / Alt manpages / tc-bfifo(8)

  • tc-bfifo(8)
  • Admin command
  • linux

Bound a Linux Interface Queue with tc pfifo or bfifo

pfifo and bfifo are the plainest queues tc offers: no shaping, no priority, just a limit and a tail drop when it fills. This sets one on a Linux interface, lets you choose whether the limit counts packets or bytes, and verifies the result with traffic-control statistics. Allow about fifteen minutes, plus a maintenance window if the interface carries production traffic. The examples use iproute2 6.1.0-1ubuntu6.4, whose tc utility reports iproute2-6.1.0.

You need the iproute2 package and the name of an interface. Reading queue state is normally unprivileged. Replacing an interface's root qdisc needs elevated privileges and can change packet behaviour immediately, so do not experiment on a busy link without a recovery plan.

1. Check the installed command

Confirm the binary and package version before relying on defaults. This is read-only:

$ command -v tc
/usr/sbin/tc
$ tc -V
tc utility, iproute2-6.1.0, libbpf 1.3.0
$ dpkg-query -W -f='${Package} ${Version}\n' iproute2
iproute2 6.1.0-1ubuntu6.4

The installed tc-bfifo(8) and tc-pfifo(8) pages describe the same two qdiscs. pfifo limits the queue in packets. bfifo limits it in bytes. Both are unadorned FIFO queues with tail drop: when the queue is full, a new packet is not admitted. They do not shape or smooth traffic.

Checkpoint

Make sure you are changing the intended interface, not a similarly named bridge, VLAN or physical device:

$ ip -br link
$ ip link show dev IFACE

Replace IFACE with a real name such as eth0. Do not paste the placeholder literally.

2. Inspect the current qdisc and interface defaults

Record the current root qdisc before making a change:

$ tc qdisc show dev IFACE
$ ip -details link show dev IFACE

Look for the interface MTU and transmit queue length, shown as mtu and qlen. The manpage says that the default pfifo limit is the interface's txqueuelen. The default bfifo limit is that queue length multiplied by the interface MTU. These are defaults, not universal constants, so do not assume that a packet limit and byte limit represent the same amount of buffering.

Write the output somewhere safe if you are working remotely. If the existing root qdisc is a classful qdisc with child classes, replacing only the root can remove the hierarchy and disrupt traffic classification. In that case, stop and document the existing configuration before proceeding.

3. Choose a packet-limited queue

Use pfifo when a fixed number of packets is the useful boundary. This example sets a limit of 100 packets:

$ sudo tc qdisc replace dev IFACE root pfifo limit 100

replace needs root privileges because it changes the live interface. It also deliberately replaces the root qdisc, so it is not a harmless inspection command. The limit range in the installed manpage is 0 through UINT32_MAX packets. A small limit can increase drops under bursts; a large limit can add queueing delay. Pick a value from a measured requirement rather than copying 100 as a universal tuning value.

Verify the installed state:

$ tc qdisc show dev IFACE
qdisc pfifo ... dev IFACE limit 100p

The handle and other fields vary. The useful evidence is pfifo and a limit displayed with the packet suffix p.

4. Choose a byte-limited queue

Use bfifo when a byte ceiling is easier to reason about, for example when packet sizes vary widely. This example allows 65536 bytes:

$ sudo tc qdisc replace dev IFACE root bfifo limit 65536

The value is bytes, not packets. The queue counts link-layer header length when determining packet length, so the number of packets that fit will depend on the traffic. The installed manpage gives the same 0 through UINT32_MAX range for a byte limit.

Checkpoint

Confirm the qdisc now shows bfifo with the limit displayed in bytes, using the b suffix:

$ tc qdisc show dev IFACE
qdisc bfifo ... dev IFACE limit 65536b

If the output still names the old qdisc, check the interface name and the command's exit status. If tc reports that the device does not exist, the command did not change another interface by accident; correct the name and inspect again.

5. Read counters and backlog

Statistics are the reason to inspect the qdisc rather than infer its behaviour from an application's symptoms:

$ tc -s qdisc show dev IFACE
qdisc bfifo ... dev IFACE limit 65536b
 Sent ... bytes ... pkt (dropped 0, overlimits 0 ...)
 backlog 0b 0p ...

Exact counters depend on traffic and the iproute2 build. The Sent line reports bytes and packets sent. dropped counts packets rejected by the queue. A backlog line shows work still waiting. The manual explains that an unsent dropped packet can appear in braces and is not counted as sent. A FIFO queue does not slow packets down, so do not interpret zero overlimits as proof that no packets were dropped or that latency is good.

For a repeatable observation, capture two readings around the workload:

$ tc -s qdisc show dev IFACE
$ # run the known workload during the maintenance window
$ tc -s qdisc show dev IFACE

Do not generate traffic merely to force counters to move on a production link. A counter change is only useful when the workload and its expected impact are understood.

6. Restore the previous configuration

Changing a root qdisc is a live network change. If the original output showed a different root qdisc, restore the exact command used by your network manager or deployment configuration. Do not guess from a shortened display line. For a simple test on an interface whose original root was the kernel default, the usual restoration is:

$ sudo tc qdisc replace dev IFACE root noqueue

That is only appropriate when noqueue was the original root and the interface supports it. Recheck:

$ tc qdisc show dev IFACE

If NetworkManager, systemd-networkd, a container runtime or another service owns the qdisc, let that owner restore it or reapply its configuration. An ad hoc tc command can be overwritten at the next link restart. If the change caused a service disruption, revert promptly using the recorded configuration, then investigate with the statistics and system logs.

Common traps

  • Confusing units: pfifo limit 100 means 100 packets, while bfifo limit 100 means 100 bytes. There is no shared conversion that remains correct for mixed packet sizes.
  • Expecting shaping: these qdiscs only hold packets in FIFO order and tail-drop excess. They do not provide a rate, priority, fairness or delay target.
  • Replacing a hierarchy: root targets the interface root. It can discard an existing class and filter arrangement. Inspect first.
  • Assuming a clean counter means a clean link: a zero drop count covers the observed interval, not every workload or future burst.

Done means

  • Version and interface confirmed: you checked the installed iproute2 version and the target interface.
  • Baseline recorded: you noted the existing root qdisc, MTU and transmit queue length.
  • Right unit chosen: you picked pfifo for a packet limit or bfifo for a byte limit deliberately.
  • Change verified: tc qdisc show reports the intended qdisc and limit.
  • Statistics available: tc -s qdisc show is ready for drops, sent traffic and backlog.
  • Rollback possible: you can restore the previous root qdisc from a recorded, authoritative configuration.