When remote side fails to create tun (e.g. tun device is already opened) it notifies the client with an SSH2_MSG_CHANNEL_OPEN_FAILURE message and channel is marked dead on client side. But because tun forward channel is not an interactive channel it has no cleanup callback and is kept in a Zombie state until ssh is manually terminated.
This makes "ssh -Nw" to not fail and exit in such situation even if ExitOnForwardFailure is set. This patch registers a cleanup callback to tun forward channel if ExitOnForwardFailure is set so that "ssh -Nw" exit directly when remote fails to established the tunnel correctly on its side. Index: usr.bin/ssh/clientloop.c =================================================================== RCS file: /cvs/src/usr.bin/ssh/clientloop.c,v retrieving revision 1.340 diff -u -p -r1.340 clientloop.c --- usr.bin/ssh/clientloop.c 2 Feb 2020 09:45:34 -0000 1.340 +++ usr.bin/ssh/clientloop.c 17 Feb 2020 15:42:59 -0000 @@ -1673,6 +1673,11 @@ client_request_tun_fwd(struct ssh *ssh, (r = sshpkt_send(ssh)) != 0) sshpkt_fatal(ssh, r, "%s: send reply", __func__); + if (options.exit_on_forward_failure) { + channel_register_cleanup(ssh, c->self, + client_channel_closed, 0); + } + return ifname; }