From b6c66c4324e7dd66a06a6a034204ae7d4e95c28c Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 12 Oct 2022 09:51:12 +0100 Subject: rxrpc: Use the core ICMP/ICMP6 parsers Make rxrpc_encap_rcv_err() pass the ICMP/ICMP6 skbuff to ip_icmp_error() or ipv6_icmp_error() as appropriate to do the parsing rather than trying to do it in rxrpc. This pushes an error report onto the UDP socket's error queue and calls ->sk_error_report() from which point rxrpc can pick it up. It would be preferable to steal the packet directly from ip*_icmp_error() rather than letting it get queued, but this is probably good enough. Also note that __udp4_lib_err() calls sk_error_report() twice in some cases. Signed-off-by: David Howells cc: Marc Dionne cc: linux-afs@lists.infradead.org --- net/rxrpc/local_object.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'net/rxrpc/local_object.c') diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c index 38ea98ff426b..e95e75e785fb 100644 --- a/net/rxrpc/local_object.c +++ b/net/rxrpc/local_object.c @@ -23,6 +23,19 @@ static void rxrpc_local_processor(struct work_struct *); static void rxrpc_local_rcu(struct rcu_head *); +/* + * Handle an ICMP/ICMP6 error turning up at the tunnel. Push it through the + * usual mechanism so that it gets parsed and presented through the UDP + * socket's error_report(). + */ +static void rxrpc_encap_err_rcv(struct sock *sk, struct sk_buff *skb, int err, + __be16 port, u32 info, u8 *payload) +{ + if (ip_hdr(skb)->version == IPVERSION) + return ip_icmp_error(sk, skb, err, port, info, payload); + return ipv6_icmp_error(sk, skb, err, port, info, payload); +} + /* * Compare a local to an address. Return -ve, 0 or +ve to indicate less than, * same or greater than. -- cgit