]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
can: isotp: fix support for transmission of SF without flow control
authorOliver Hartkopp <socketcan@hartkopp.net>
Mon, 21 Aug 2023 14:45:46 +0000 (16:45 +0200)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 30 Oct 2023 11:00:25 +0000 (12:00 +0100)
BugLink: https://bugs.launchpad.net/bugs/2039742
[ Upstream commit 0bfe71159230bab79ee230225ae12ffecbb69f3e ]

The original implementation had a very simple handling for single frame
transmissions as it just sent the single frame without a timeout handling.

With the new echo frame handling the echo frame was also introduced for
single frames but the former exception ('simple without timers') has been
maintained by accident. This leads to a 1 second timeout when closing the
socket and to an -ECOMM error when CAN_ISOTP_WAIT_TX_DONE is selected.

As the echo handling is always active (also for single frames) remove the
wrong extra condition for single frames.

Fixes: 9f39d36530e5 ("can: isotp: add support for transmission without flow control")
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://lore.kernel.org/r/20230821144547.6658-2-socketcan@hartkopp.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
net/can/isotp.c

index b3c2a49b189cc57c2feb6a709127278209f517c1..8c97f4061ffd731b5b5c25c038cec44efdb01134 100644 (file)
@@ -175,12 +175,6 @@ static bool isotp_register_rxid(struct isotp_sock *so)
        return (isotp_bc_flags(so) == 0);
 }
 
-static bool isotp_register_txecho(struct isotp_sock *so)
-{
-       /* all modes but SF_BROADCAST register for tx echo skbs */
-       return (isotp_bc_flags(so) != CAN_ISOTP_SF_BROADCAST);
-}
-
 static enum hrtimer_restart isotp_rx_timer_handler(struct hrtimer *hrtimer)
 {
        struct isotp_sock *so = container_of(hrtimer, struct isotp_sock,
@@ -1176,7 +1170,7 @@ static int isotp_release(struct socket *sock)
        lock_sock(sk);
 
        /* remove current filters & unregister */
-       if (so->bound && isotp_register_txecho(so)) {
+       if (so->bound) {
                if (so->ifindex) {
                        struct net_device *dev;
 
@@ -1293,14 +1287,12 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
                can_rx_register(net, dev, rx_id, SINGLE_MASK(rx_id),
                                isotp_rcv, sk, "isotp", sk);
 
-       if (isotp_register_txecho(so)) {
-               /* no consecutive frame echo skb in flight */
-               so->cfecho = 0;
+       /* no consecutive frame echo skb in flight */
+       so->cfecho = 0;
 
-               /* register for echo skb's */
-               can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id),
-                               isotp_rcv_echo, sk, "isotpe", sk);
-       }
+       /* register for echo skb's */
+       can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id),
+                       isotp_rcv_echo, sk, "isotpe", sk);
 
        dev_put(dev);
 
@@ -1521,7 +1513,7 @@ static void isotp_notify(struct isotp_sock *so, unsigned long msg,
        case NETDEV_UNREGISTER:
                lock_sock(sk);
                /* remove current filters & unregister */
-               if (so->bound && isotp_register_txecho(so)) {
+               if (so->bound) {
                        if (isotp_register_rxid(so))
                                can_rx_unregister(dev_net(dev), dev, so->rxid,
                                                  SINGLE_MASK(so->rxid),