diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 542743aa5b3..68e54932049 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -2750,6 +2750,16 @@ IPv6Token=prefixstable:2002:da8:1::
the value of a received bit by majority rule. When unset, the kernel's default will be used.
+
+ BusErrorReporting=
+
+ Takes a boolean. When yes, reporting of CAN bus errors is activated
+ (those include single bit, frame format, and bit stuffing errors, unable to send dominant bit,
+ unable to send recessive bit, bus overload, active error announcement, error occurred on
+ transmission). When unset, the kernel's default will be used. Note: in case of a CAN bus with a
+ single CAN device, sending a CAN frame may result in a huge number of CAN bus errors.
+
+
ListenOnly=
diff --git a/src/network/networkd-can.c b/src/network/networkd-can.c
index 86103206981..c0018c306f9 100644
--- a/src/network/networkd-can.c
+++ b/src/network/networkd-can.c
@@ -174,14 +174,14 @@ static int link_set_can(Link *link) {
if (link->network->can_fd_mode >= 0) {
cm.mask |= CAN_CTRLMODE_FD;
- SET_FLAG(cm.flags, CAN_CTRLMODE_FD, link->network->can_fd_mode > 0);
- log_link_debug(link, "%sabling FD mode", link->network->can_fd_mode > 0 ? "En" : "Dis");
+ SET_FLAG(cm.flags, CAN_CTRLMODE_FD, link->network->can_fd_mode);
+ log_link_debug(link, "Setting FD mode to '%s'.", yes_no(link->network->can_fd_mode));
}
if (link->network->can_non_iso >= 0) {
cm.mask |= CAN_CTRLMODE_FD_NON_ISO;
- SET_FLAG(cm.flags, CAN_CTRLMODE_FD_NON_ISO, link->network->can_non_iso > 0);
- log_link_debug(link, "%sabling FD non-ISO mode", link->network->can_non_iso > 0 ? "En" : "Dis");
+ SET_FLAG(cm.flags, CAN_CTRLMODE_FD_NON_ISO, link->network->can_non_iso);
+ log_link_debug(link, "Setting FD non-ISO mode to '%s'.", yes_no(link->network->can_non_iso));
}
if (link->network->can_restart_us > 0) {
@@ -208,13 +208,19 @@ static int link_set_can(Link *link) {
if (link->network->can_triple_sampling >= 0) {
cm.mask |= CAN_CTRLMODE_3_SAMPLES;
SET_FLAG(cm.flags, CAN_CTRLMODE_3_SAMPLES, link->network->can_triple_sampling);
- log_link_debug(link, "%sabling triple-sampling", link->network->can_triple_sampling ? "En" : "Dis");
+ log_link_debug(link, "Setting triple-sampling to '%s'.", yes_no(link->network->can_triple_sampling));
+ }
+
+ if (link->network->can_berr_reporting >= 0) {
+ cm.mask |= CAN_CTRLMODE_BERR_REPORTING;
+ SET_FLAG(cm.flags, CAN_CTRLMODE_BERR_REPORTING, link->network->can_berr_reporting);
+ log_link_debug(link, "Setting bus error reporting to '%s'.", yes_no(link->network->can_berr_reporting));
}
if (link->network->can_listen_only >= 0) {
cm.mask |= CAN_CTRLMODE_LISTENONLY;
SET_FLAG(cm.flags, CAN_CTRLMODE_LISTENONLY, link->network->can_listen_only);
- log_link_debug(link, "%sabling listen-only mode", link->network->can_listen_only ? "En" : "Dis");
+ log_link_debug(link, "Setting listen-only mode to '%s'.", yes_no(link->network->can_listen_only));
}
if (cm.mask != 0) {
@@ -225,7 +231,7 @@ static int link_set_can(Link *link) {
if (link->network->can_termination >= 0) {
- log_link_debug(link, "%sabling can-termination", link->network->can_termination ? "En" : "Dis");
+ log_link_debug(link, "Setting can-termination to '%s'.", yes_no(link->network->can_termination));
r = sd_netlink_message_append_u16(m, IFLA_CAN_TERMINATION,
link->network->can_termination ? CAN_TERMINATION_OHM_VALUE : 0);
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 81878dcea1a..8b15548f6ff 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -321,6 +321,7 @@ CAN.FDMode, config_parse_tristate,
CAN.FDNonISO, config_parse_tristate, 0, offsetof(Network, can_non_iso)
CAN.RestartSec, config_parse_sec, 0, offsetof(Network, can_restart_us)
CAN.TripleSampling, config_parse_tristate, 0, offsetof(Network, can_triple_sampling)
+CAN.BusErrorReporting, config_parse_tristate, 0, offsetof(Network, can_berr_reporting)
CAN.Termination, config_parse_tristate, 0, offsetof(Network, can_termination)
CAN.ListenOnly, config_parse_tristate, 0, offsetof(Network, can_listen_only)
QDisc.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index f6e36f7080b..783f455a9fc 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -415,6 +415,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipv6_accept_ra_start_dhcp6_client = IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES,
.can_triple_sampling = -1,
+ .can_berr_reporting = -1,
.can_termination = -1,
.can_listen_only = -1,
.can_fd_mode = -1,
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 762dc971dbb..2b7dc4e94b3 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -231,6 +231,7 @@ struct Network {
unsigned can_data_sample_point;
usec_t can_restart_us;
int can_triple_sampling;
+ int can_berr_reporting;
int can_termination;
int can_listen_only;
int can_fd_mode;
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index c8435a0a847..797d81cdf84 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -247,6 +247,7 @@ FDMode=
FDNonISO=
RestartSec=
TripleSampling=
+BusErrorReporting=
Termination=
ListenOnly=
[Address]