Patch "l2tp: fix ICMP error handling for UDP-encap sockets" has been added to the 6.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    l2tp: fix ICMP error handling for UDP-encap sockets

to the 6.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     l2tp-fix-icmp-error-handling-for-udp-encap-sockets.patch
and it can be found in the queue-6.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit c296145e765e79487bf56b1e9c267a05c7a54e59
Author: Tom Parkin <tparkin@xxxxxxxxxxx>
Date:   Mon May 13 18:22:47 2024 +0100

    l2tp: fix ICMP error handling for UDP-encap sockets
    
    [ Upstream commit 6e828dc60e509b79ef09882264952f341cb58425 ]
    
    Since commit a36e185e8c85
    ("udp: Handle ICMP errors for tunnels with same destination port on both endpoints")
    UDP's handling of ICMP errors has allowed for UDP-encap tunnels to
    determine socket associations in scenarios where the UDP hash lookup
    could not.
    
    Subsequently, commit d26796ae58940
    ("udp: check udp sock encap_type in __udp_lib_err")
    subtly tweaked the approach such that UDP ICMP error handling would be
    skipped for any UDP socket which has encapsulation enabled.
    
    In the case of L2TP tunnel sockets using UDP-encap, this latter
    modification effectively broke ICMP error reporting for the L2TP
    control plane.
    
    To a degree this isn't catastrophic inasmuch as the L2TP control
    protocol defines a reliable transport on top of the underlying packet
    switching network which will eventually detect errors and time out.
    
    However, paying attention to the ICMP error reporting allows for more
    timely detection of errors in L2TP userspace, and aids in debugging
    connectivity issues.
    
    Reinstate ICMP error handling for UDP encap L2TP tunnels:
    
     * implement struct udp_tunnel_sock_cfg .encap_err_rcv in order to allow
       the L2TP code to handle ICMP errors;
    
     * only implement error-handling for tunnels which have a managed
       socket: unmanaged tunnels using a kernel socket have no userspace to
       report errors back to;
    
     * flag the error on the socket, which allows for userspace to get an
       error such as -ECONNREFUSED back from sendmsg/recvmsg;
    
     * pass the error into ip[v6]_icmp_error() which allows for userspace to
       get extended error information via. MSG_ERRQUEUE.
    
    Fixes: d26796ae5894 ("udp: check udp sock encap_type in __udp_lib_err")
    Signed-off-by: Tom Parkin <tparkin@xxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20240513172248.623261-1-tparkin@xxxxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 8d21ff25f1602..4a0fb8731eee9 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -887,22 +887,20 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
 	return 1;
 }
 
-/* UDP encapsulation receive handler. See net/ipv4/udp.c.
- * Return codes:
- * 0 : success.
- * <0: error
- * >0: skb should be passed up to userspace as UDP.
+/* UDP encapsulation receive and error receive handlers.
+ * See net/ipv4/udp.c for details.
+ *
+ * Note that these functions are called from inside an
+ * RCU-protected region, but without the socket being locked.
+ *
+ * Hence we use rcu_dereference_sk_user_data to access the
+ * tunnel data structure rather the usual l2tp_sk_to_tunnel
+ * accessor function.
  */
 int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 {
 	struct l2tp_tunnel *tunnel;
 
-	/* Note that this is called from the encap_rcv hook inside an
-	 * RCU-protected region, but without the socket being locked.
-	 * Hence we use rcu_dereference_sk_user_data to access the
-	 * tunnel data structure rather the usual l2tp_sk_to_tunnel
-	 * accessor function.
-	 */
 	tunnel = rcu_dereference_sk_user_data(sk);
 	if (!tunnel)
 		goto pass_up;
@@ -919,6 +917,29 @@ int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(l2tp_udp_encap_recv);
 
+static void l2tp_udp_encap_err_recv(struct sock *sk, struct sk_buff *skb, int err,
+				    __be16 port, u32 info, u8 *payload)
+{
+	struct l2tp_tunnel *tunnel;
+
+	tunnel = rcu_dereference_sk_user_data(sk);
+	if (!tunnel || tunnel->fd < 0)
+		return;
+
+	sk->sk_err = err;
+	sk_error_report(sk);
+
+	if (ip_hdr(skb)->version == IPVERSION) {
+		if (inet_test_bit(RECVERR, sk))
+			return ip_icmp_error(sk, skb, err, port, info, payload);
+#if IS_ENABLED(CONFIG_IPV6)
+	} else {
+		if (inet6_test_bit(RECVERR6, sk))
+			return ipv6_icmp_error(sk, skb, err, port, info, payload);
+#endif
+	}
+}
+
 /************************************************************************
  * Transmit handling
  ***********************************************************************/
@@ -1493,6 +1514,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
 			.sk_user_data = tunnel,
 			.encap_type = UDP_ENCAP_L2TPINUDP,
 			.encap_rcv = l2tp_udp_encap_recv,
+			.encap_err_rcv = l2tp_udp_encap_err_recv,
 			.encap_destroy = l2tp_udp_encap_destroy,
 		};
 




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux