1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <linux/can/netlink.h>
6 #include "networkd-can.h"
7 #include "networkd-link.h"
8 #include "networkd-network.h"
9 #include "networkd-setlink.h"
10 #include "parse-util.h"
11 #include "string-util.h"
13 #define CAN_TERMINATION_OHM_VALUE 120
15 int config_parse_can_bitrate(
20 unsigned section_line
,
36 r
= parse_size(rvalue
, 1000, &sz
);
38 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
39 "Failed to parse can bitrate '%s', ignoring: %m", rvalue
);
43 /* Linux uses __u32 for bitrates, so the value should not exceed that. */
44 if (sz
<= 0 || sz
> UINT32_MAX
) {
45 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
46 "Bit rate out of permitted range 1...4294967295");
55 int can_set_netlink_message(Link
*link
, sd_netlink_message
*m
) {
56 struct can_ctrlmode cm
= {};
60 assert(link
->network
);
63 r
= sd_netlink_message_set_flags(m
, NLM_F_REQUEST
| NLM_F_ACK
);
65 return log_link_debug_errno(link
, r
, "Could not set netlink flags: %m");
67 r
= sd_netlink_message_open_container(m
, IFLA_LINKINFO
);
69 return log_link_debug_errno(link
, r
, "Failed to open IFLA_LINKINFO container: %m");
71 r
= sd_netlink_message_open_container_union(m
, IFLA_INFO_DATA
, link
->kind
);
73 return log_link_debug_errno(link
, r
, "Could not open IFLA_INFO_DATA container: %m");
75 if (link
->network
->can_bitrate
> 0 || link
->network
->can_sample_point
> 0) {
76 struct can_bittiming bt
= {
77 .bitrate
= link
->network
->can_bitrate
,
78 .sample_point
= link
->network
->can_sample_point
,
81 log_link_debug(link
, "Setting bitrate = %d bit/s", bt
.bitrate
);
82 if (link
->network
->can_sample_point
> 0)
83 log_link_debug(link
, "Setting sample point = %d.%d%%", bt
.sample_point
/ 10, bt
.sample_point
% 10);
85 log_link_debug(link
, "Using default sample point");
87 r
= sd_netlink_message_append_data(m
, IFLA_CAN_BITTIMING
, &bt
, sizeof(bt
));
89 return log_link_debug_errno(link
, r
, "Could not append IFLA_CAN_BITTIMING attribute: %m");
92 if (link
->network
->can_data_bitrate
> 0 || link
->network
->can_data_sample_point
> 0) {
93 struct can_bittiming bt
= {
94 .bitrate
= link
->network
->can_data_bitrate
,
95 .sample_point
= link
->network
->can_data_sample_point
,
98 log_link_debug(link
, "Setting data bitrate = %d bit/s", bt
.bitrate
);
99 if (link
->network
->can_data_sample_point
> 0)
100 log_link_debug(link
, "Setting data sample point = %d.%d%%", bt
.sample_point
/ 10, bt
.sample_point
% 10);
102 log_link_debug(link
, "Using default data sample point");
104 r
= sd_netlink_message_append_data(m
, IFLA_CAN_DATA_BITTIMING
, &bt
, sizeof(bt
));
106 return log_link_debug_errno(link
, r
, "Could not append IFLA_CAN_DATA_BITTIMING attribute: %m");
109 if (link
->network
->can_restart_us
> 0) {
110 char time_string
[FORMAT_TIMESPAN_MAX
];
113 if (link
->network
->can_restart_us
== USEC_INFINITY
)
116 restart_ms
= DIV_ROUND_UP(link
->network
->can_restart_us
, USEC_PER_MSEC
);
118 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, restart_ms
* 1000, MSEC_PER_SEC
);
120 if (restart_ms
> UINT32_MAX
)
121 return log_link_debug_errno(link
, SYNTHETIC_ERRNO(ERANGE
), "restart timeout (%s) too big.", time_string
);
123 log_link_debug(link
, "Setting restart = %s", time_string
);
125 r
= sd_netlink_message_append_u32(m
, IFLA_CAN_RESTART_MS
, restart_ms
);
127 return log_link_debug_errno(link
, r
, "Could not append IFLA_CAN_RESTART_MS attribute: %m");
130 if (link
->network
->can_fd_mode
>= 0) {
131 cm
.mask
|= CAN_CTRLMODE_FD
;
132 SET_FLAG(cm
.flags
, CAN_CTRLMODE_FD
, link
->network
->can_fd_mode
);
133 log_link_debug(link
, "Setting FD mode to '%s'.", yes_no(link
->network
->can_fd_mode
));
136 if (link
->network
->can_non_iso
>= 0) {
137 cm
.mask
|= CAN_CTRLMODE_FD_NON_ISO
;
138 SET_FLAG(cm
.flags
, CAN_CTRLMODE_FD_NON_ISO
, link
->network
->can_non_iso
);
139 log_link_debug(link
, "Setting FD non-ISO mode to '%s'.", yes_no(link
->network
->can_non_iso
));
142 if (link
->network
->can_triple_sampling
>= 0) {
143 cm
.mask
|= CAN_CTRLMODE_3_SAMPLES
;
144 SET_FLAG(cm
.flags
, CAN_CTRLMODE_3_SAMPLES
, link
->network
->can_triple_sampling
);
145 log_link_debug(link
, "Setting triple-sampling to '%s'.", yes_no(link
->network
->can_triple_sampling
));
148 if (link
->network
->can_berr_reporting
>= 0) {
149 cm
.mask
|= CAN_CTRLMODE_BERR_REPORTING
;
150 SET_FLAG(cm
.flags
, CAN_CTRLMODE_BERR_REPORTING
, link
->network
->can_berr_reporting
);
151 log_link_debug(link
, "Setting bus error reporting to '%s'.", yes_no(link
->network
->can_berr_reporting
));
154 if (link
->network
->can_listen_only
>= 0) {
155 cm
.mask
|= CAN_CTRLMODE_LISTENONLY
;
156 SET_FLAG(cm
.flags
, CAN_CTRLMODE_LISTENONLY
, link
->network
->can_listen_only
);
157 log_link_debug(link
, "Setting listen-only mode to '%s'.", yes_no(link
->network
->can_listen_only
));
161 r
= sd_netlink_message_append_data(m
, IFLA_CAN_CTRLMODE
, &cm
, sizeof(cm
));
163 return log_link_debug_errno(link
, r
, "Could not append IFLA_CAN_CTRLMODE attribute: %m");
166 if (link
->network
->can_termination
>= 0) {
167 log_link_debug(link
, "Setting can-termination to '%s'.", yes_no(link
->network
->can_termination
));
169 r
= sd_netlink_message_append_u16(m
, IFLA_CAN_TERMINATION
,
170 link
->network
->can_termination
? CAN_TERMINATION_OHM_VALUE
: 0);
172 return log_link_debug_errno(link
, r
, "Could not append IFLA_CAN_TERMINATION attribute: %m");
175 r
= sd_netlink_message_close_container(m
);
177 return log_link_debug_errno(link
, r
, "Failed to close IFLA_INFO_DATA container: %m");
179 r
= sd_netlink_message_close_container(m
);
181 return log_link_debug_errno(link
, r
, "Failed to close IFLA_LINKINFO container: %m");