]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: can: add support for listen-only mode
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 16 Mar 2020 04:40:30 +0000 (13:40 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 16 Mar 2020 15:32:35 +0000 (00:32 +0900)
Closes #15129.

man/systemd.network.xml
src/network/networkd-can.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.h
test/fuzz/fuzz-network-parser/directives.network

index a174a1fb248246dc96c53b0414839b73cfa0aa69..8df79e08cd5ab6b0690c85e76d7788d98dfc0732 100644 (file)
             the value of a received bit by majority rule. When unset, the kernel's default will be used.</para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term><varname>ListenOnly=</varname></term>
+          <listitem>
+            <para>Takes a boolean. When <literal>yes</literal>, listen-only mode is enabled. When the
+            interface is in listen-only mode, the interface neither transmit CAN frames nor send ACK
+            bit. Listen-only mode is important to debug CAN networks without interfering with the
+            communication or acknowledge the CAN frame. When unset, the kernel's default will be used.
+            </para>
+          </listitem>
+        </varlistentry>
       </variablelist>
   </refsect1>
 
index c703f94f3ab6d052e54bbabf62c41e3d13abbdd5..18533843e30c9226078dc766432bf3ecf6f76faa 100644 (file)
@@ -71,6 +71,7 @@ static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
 
 static int link_set_can(Link *link) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
+        struct can_ctrlmode cm = {};
         int r;
 
         assert(link);
@@ -142,13 +143,18 @@ static int link_set_can(Link *link) {
         }
 
         if (link->network->can_triple_sampling >= 0) {
-                struct can_ctrlmode cm = {
-                        .mask = CAN_CTRLMODE_3_SAMPLES,
-                        .flags = link->network->can_triple_sampling ? CAN_CTRLMODE_3_SAMPLES : 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");
+        }
+
+        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");
+        }
 
+        if (cm.mask != 0) {
                 r = sd_netlink_message_append_data(m, IFLA_CAN_CTRLMODE, &cm, sizeof(cm));
                 if (r < 0)
                         return log_link_error_errno(link, r, "Could not append IFLA_CAN_CTRLMODE attribute: %m");
index e1b9b5687af5029003b5e3bdd0cacd4359513d75..d6259a41bff83e77c0dc51f35cec0a8c5f28ecf4 100644 (file)
@@ -256,6 +256,7 @@ CAN.SamplePoint,                             config_parse_permille,
 CAN.RestartSec,                              config_parse_sec,                                         0,                             offsetof(Network, can_restart_us)
 CAN.TripleSampling,                          config_parse_tristate,                                    0,                             offsetof(Network, can_triple_sampling)
 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
 QDisc.Handle,                                config_parse_qdisc_handle,                                _QDISC_KIND_INVALID,           0
 BFIFO.Parent,                                config_parse_qdisc_parent,                                QDISC_KIND_BFIFO,              0
index f8ecb1f687ba9ad0e132a3107f05998a1dc0b0a1..693f01838503d1d837007a975207efb6c6d326ca 100644 (file)
@@ -200,6 +200,7 @@ struct Network {
         usec_t can_restart_us;
         int can_triple_sampling;
         int can_termination;
+        int can_listen_only;
 
         AddressFamily ip_forward;
         bool ip_masquerade;
index a729adcc86f4fb630771e28cadc09ccc5e19fe5a..630abafdcf45851c166dcf26d0c95d03f0995721 100644 (file)
@@ -201,6 +201,7 @@ BitRate=
 RestartSec=
 TripleSampling=
 Termination=
+ListenOnly=
 [Address]
 DuplicateAddressDetection=
 AutoJoin=