Skip to content

Commit

Permalink
l2tp: fix ICMP error handling for UDP-encap sockets
Browse files Browse the repository at this point in the history
Since commit a36e185
("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 d26796a
("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: d26796a ("udp: check udp sock encap_type in __udp_lib_err")
Signed-off-by: Tom Parkin <tparkin@katalix.com>
Reviewed-by: James Chapman <jchapman@katalix.com>
Signed-off-by: NipaLocal <nipa@local>
  • Loading branch information
tomparkin authored and NipaLocal committed May 2, 2024
1 parent 6147044 commit 1efb8d5
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions net/l2tp/l2tp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,28 @@ 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 = l2tp_sk_to_tunnel(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
***********************************************************************/
Expand Down Expand Up @@ -1493,6 +1515,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,
};

Expand Down

0 comments on commit 1efb8d5

Please sign in to comment.