diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index ee4356ac3d..d72533b162 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -735,29 +735,33 @@
RxBufferSize=
- Takes an integer. Specifies the maximum number of pending packets in the NIC receive buffer.
- When unset, the kernel's default will be used.
+ Takes an integer or max. Specifies the maximum number of pending packets
+ in the NIC receive buffer. When unset, the kernel's default will be used. If set to
+ max, the hardware's advertised maximum size will be used.
RxMiniBufferSize=
- Takes an integer. Specifies the maximum number of pending packets in the NIC mini receive buffer.
- When unset, the kernel's default will be used.
+ Takes an integer or max. Specifies the maximum number of pending packets
+ in the NIC mini receive buffer. When unset, the kernel's default will be used. If set to
+ max, the hardware's advertised maximum size will be used.
RxJumboBufferSize=
- Takes an integer. Specifies the maximum number of pending packets in the NIC jumbo receive buffer.
- When unset, the kernel's default will be used.
+ Takes an integer or max. Specifies the maximum number of pending packets
+ in the NIC jumbo receive buffer. When unset, the kernel's default will be used. If set to
+ max, the hardware's advertised maximum size will be used.
TxBufferSize=
- Takes an integer. Specifies the maximum number of pending packets in the NIC transmit buffer.
- When unset, the kernel's default will be used.
+ Takes an integer or max. Specifies the maximum number of pending packets
+ in the NIC transmit buffer. When unset, the kernel's default will be used. If set to
+ max, the hardware's advertised maximum size will be used.
diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
index 4ca90615f3..4e81e027b2 100644
--- a/src/shared/ethtool-util.c
+++ b/src/shared/ethtool-util.c
@@ -399,16 +399,24 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
return -errno;
if (ring->rx_pending_set)
- UPDATE(ecmd.rx_pending, ring->rx_pending, need_update);
+ UPDATE(ecmd.rx_pending,
+ ring->rx_pending == 0 ? ecmd.rx_max_pending : ring->rx_pending,
+ need_update);
if (ring->rx_mini_pending_set)
- UPDATE(ecmd.rx_mini_pending, ring->rx_mini_pending, need_update);
+ UPDATE(ecmd.rx_mini_pending,
+ ring->rx_mini_pending == 0 ? ecmd.rx_mini_max_pending : ring->rx_mini_pending,
+ need_update);
if (ring->rx_jumbo_pending_set)
- UPDATE(ecmd.rx_jumbo_pending, ring->rx_jumbo_pending, need_update);
+ UPDATE(ecmd.rx_jumbo_pending,
+ ring->rx_jumbo_pending == 0 ? ecmd.rx_jumbo_max_pending : ring->rx_jumbo_pending,
+ need_update);
if (ring->tx_pending_set)
- UPDATE(ecmd.tx_pending, ring->tx_pending, need_update);
+ UPDATE(ecmd.tx_pending,
+ ring->tx_pending == 0 ? ecmd.tx_max_pending : ring->tx_pending,
+ need_update);
if (!need_update)
return 0;
@@ -1047,16 +1055,20 @@ int config_parse_nic_buffer_size(
assert(rvalue);
assert(data);
- r = safe_atou32(rvalue, &k);
- if (r < 0) {
- log_syntax(unit, LOG_WARNING, filename, line, r,
- "Failed to parse interface buffer value, ignoring: %s", rvalue);
- return 0;
- }
- if (k < 1) {
- log_syntax(unit, LOG_WARNING, filename, line, 0,
- "Invalid %s= value, ignoring: %s", lvalue, rvalue);
- return 0;
+ if (streq(rvalue, "max"))
+ k = 0;
+ else {
+ r = safe_atou32(rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Failed to parse interface buffer value, ignoring: %s", rvalue);
+ return 0;
+ }
+ if (k < 1) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Invalid %s= value, ignoring: %s", lvalue, rvalue);
+ return 0;
+ }
}
if (streq(lvalue, "RxBufferSize")) {
diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h
index f0fc40b059..f392a1cf42 100644
--- a/src/shared/ethtool-util.h
+++ b/src/shared/ethtool-util.h
@@ -70,6 +70,8 @@ typedef struct netdev_channels {
} netdev_channels;
typedef struct netdev_ring_param {
+ /* For any of the 4 following settings, a value of 0 indicates the hardware advertised maximum should
+ * be used. */
uint32_t rx_pending;
uint32_t rx_mini_pending;
uint32_t rx_jumbo_pending;