Affected version
Rolling since vyos-1x commit 02471a8b8 ("ethtool: T3871: honor the unsupported-driver
denylist for flow-control too", 2026-08-06, part of PR #5350). The code is unchanged on
rolling HEAD as of 2026-11-11 (python/vyos/ethtool.py).
Seen on a self-built image from the rolling tree (2026.09.15), kernel 6.18.57,
Intel X710 (i40e out-of-tree driver 2.30.18, firmware 9.20 0x8000d8c5), bare metal.
Regression information
- Last known working: VyOS 2026.03 (circinus, kernel 6.6.128). The same disable-flow-control config on the same X710 ports passed verification and committed cleanly for months.
- First broken: any rolling build that contains 02471a8b8. (Builds between T4297, 2022, and T6083, 2024-03, behaved the same way; see Cause.)
Steps to reproduce
On any system with an i40e (or ice) port:
set interfaces ethernet eth0 disable-flow-control commit
[ interfaces ethernet eth0 ] Adapter does not support changing flow-control settings!
The driver supports changing pause parameters. On the same port, on the same image:
$ sudo ethtool -a eth0 Pause parameters for eth0: Autonegotiate: off RX: off TX: off
The driver accepts pause changes from ethtool -A (shown on an unused, unlinked X710 port):
$ sudo ethtool -A eth1 rx on tx on; echo "on rc=$?" on rc=0 $ sudo ethtool -A eth1 rx off tx off; echo "off rc=$?" off rc=0
The request reaches the driver's pause handler, which logs:
i40e 0000:02:00.1 eth1: Autoneg did not complete so changing settings may not res
(That port has no link, so the ethtool -a read-back stays off even after a 3
is what the driver message says. It shows the driver accepts and processes pause changes,
not the resulting state on a live link. Drivers that really can't change pause pa
return Operation not supported here, as in T3802.)
Before 02471a8b8, VyOS's own live probe (self._flow_control, from ethtool --json -a)
reported these ports as supporting flow control.
Impact on upgrade
A config that already has disable-flow-control on an i40e port fails verify()
boot config load. The whole interfaces ethernet ethX node is then missing from the running
config. Here that lost the hw-id, the offload settings and disable on an unus
the port came up admin-up. From the journal:
vyos-configd[1091]: Received message: {"type": "node", "last": false, "data": "VYlibexec/vyos/conf_mode/interfaces_ethernet.py"}
vyos-configd[1091]: [interfaces_ethernet] Adapter does not support changing flow-control settings!
vyos-configd[1091]: Sending reply: ERROR_COMMIT with output
vyos-configd[1091]: Received message: {"type": "node", "last": false, "data": "VYOS_TAGNODE_VALUE=eth1/usr/libexec/vyos/conf_mode/interfaces_ethernet.py"}
vyos-configd[1091]: [interfaces_ethernet] Adapter does not support changing flow-
vyos-configd[1091]: Sending reply: ERROR_COMMIT with outputThe only way to get the config to load again is to delete disable-flow-control.
drivers that works only by accident: without the node, EthernetIf.update() requ
on, and set_flow_control() skips that only because the driver is on the lis
list is fixed later, pause frames get enabled on everyone who removed the node to work around
this.
Cause
02471a8b8 made Ethtool.check_flow_control() return False for every driver in
_drivers_without_speed_duplex_flow:
_drivers_without_speed_duplex_flow = ['vmxnet3', 'virtio_net', 'xen_netfront',
'iavf', 'ice', 'i40e', 'hv_netvsc', 'veth', 'ixgbevf',
'tun', 'vif']History of i40e on that list:
- 2022, T4297 / PR #1245 (rVYOSONEX2894b5245431): iavf, ice and i40e were added, and the list was applied to both speed/duplex and flow control. The task is about speed/duplex on ice/ia reporter added i40e because its README has the same speed/duplex limitation and wrote "I have tested ice, but i can't test i40e easily". The only "Operation not support pause in that task is from the iavf VF.
- 2024, T6083 (rVYOSONEX5ee89f460966, JSON refactor): the list check was dropped from check_flow_control(), so i40e/ice fell back to the live probe and flow contro
- 2026, 02471a8b8: the check was re-added for flow control, with virtio_net as the motivation.
So the flow-control entry for i40e/ice was never based on evidence about those drivers.
They are on the list only because they can't force link speed/duplex. As physical
drivers they implement .set_pauseparam (i40e_set_pauseparam(), ice_set_pauseparam()),
so flow control can be changed. The commit message targets paravirtualized driver
(virtio_net and similar), which can read pause parameters but not set them. For t
change is correct. The VF drivers (iavf, ixgbevf) are also correctly excluded.
Proposed fix
Give flow-control its own list and leave i40e and ice out of it:
_drivers_without_flow_control = ['vmxnet3', 'virtio_net', 'xen_netfront', 'hv_netvsc', 'veth', 'tun', 'vif', 'iavf', 'ixgbevf'] def check_flow_control(self): if self.get_driver_name() in _drivers_without_flow_control: return False return bool(self._flow_control)
The live probe (self._flow_control) still applies to everything else, which was
behaviour before 02471a8b8. The paired smoketest change in the same commit would
same split.
Optional, in the spirit of T9228: where the driver can't change flow control, a warning in
verify_flow_control() instead of a ConfigError would make configs portable be
hardware and images instead of failing to load.
Note on compatibility: with this fix, i40e/ice ports that do NOT have disable-flow-control
set go back to VyOS's default of requesting pause on (autoneg/rx/tx on), as the
02471a8b8. Systems installed since then will see pause enabled on those ports after upgrading.