sctp: extract sctp_v6_err_handle function from sctp_v6_err
authorXin Long <lucien.xin@gmail.com>
Tue, 22 Jun 2021 18:04:58 +0000 (14:04 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 22 Jun 2021 18:28:52 +0000 (11:28 -0700)
This patch is to extract sctp_v6_err_handle() from sctp_v6_err() to
only handle the icmp err after the sock lookup, and it also makes
the code clearer.

sctp_v6_err_handle() will be used in sctp over udp's err handling
in the following patch.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sctp/ipv6.c

index 50ed4de..6ad422f 100644 (file)
@@ -122,50 +122,28 @@ static struct notifier_block sctp_inet6addr_notifier = {
        .notifier_call = sctp_inet6addr_event,
 };
 
-/* ICMP error handler. */
-static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-                       u8 type, u8 code, int offset, __be32 info)
+static void sctp_v6_err_handle(struct sctp_transport *t, struct sk_buff *skb,
+                              __u8 type, __u8 code, __u32 info)
 {
-       struct sock *sk;
-       struct sctp_association *asoc;
-       struct sctp_transport *transport;
+       struct sctp_association *asoc = t->asoc;
+       struct sock *sk = asoc->base.sk;
        struct ipv6_pinfo *np;
-       __u16 saveip, savesctp;
-       int err, ret = 0;
-       struct net *net = dev_net(skb->dev);
-
-       /* Fix up skb to look at the embedded net header. */
-       saveip   = skb->network_header;
-       savesctp = skb->transport_header;
-       skb_reset_network_header(skb);
-       skb_set_transport_header(skb, offset);
-       sk = sctp_err_lookup(net, AF_INET6, skb, sctp_hdr(skb), &asoc, &transport);
-       /* Put back, the original pointers. */
-       skb->network_header   = saveip;
-       skb->transport_header = savesctp;
-       if (!sk) {
-               __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
-               return -ENOENT;
-       }
-
-       /* Warning:  The sock lock is held.  Remember to call
-        * sctp_err_finish!
-        */
+       int err = 0;
 
        switch (type) {
        case ICMPV6_PKT_TOOBIG:
                if (ip6_sk_accept_pmtu(sk))
-                       sctp_icmp_frag_needed(sk, asoc, transport, ntohl(info));
-               goto out_unlock;
+                       sctp_icmp_frag_needed(sk, asoc, t, info);
+               return;
        case ICMPV6_PARAMPROB:
                if (ICMPV6_UNK_NEXTHDR == code) {
-                       sctp_icmp_proto_unreachable(sk, asoc, transport);
-                       goto out_unlock;
+                       sctp_icmp_proto_unreachable(sk, asoc, t);
+                       return;
                }
                break;
        case NDISC_REDIRECT:
-               sctp_icmp_redirect(sk, transport, skb);
-               goto out_unlock;
+               sctp_icmp_redirect(sk, t, skb);
+               return;
        default:
                break;
        }
@@ -175,13 +153,39 @@ static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        if (!sock_owned_by_user(sk) && np->recverr) {
                sk->sk_err = err;
                sk->sk_error_report(sk);
-       } else {  /* Only an error on timeout */
+       } else {
                sk->sk_err_soft = err;
        }
+}
+
+/* ICMP error handler. */
+static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+                      u8 type, u8 code, int offset, __be32 info)
+{
+       struct net *net = dev_net(skb->dev);
+       struct sctp_transport *transport;
+       struct sctp_association *asoc;
+       __u16 saveip, savesctp;
+       struct sock *sk;
+
+       /* Fix up skb to look at the embedded net header. */
+       saveip   = skb->network_header;
+       savesctp = skb->transport_header;
+       skb_reset_network_header(skb);
+       skb_set_transport_header(skb, offset);
+       sk = sctp_err_lookup(net, AF_INET6, skb, sctp_hdr(skb), &asoc, &transport);
+       /* Put back, the original pointers. */
+       skb->network_header   = saveip;
+       skb->transport_header = savesctp;
+       if (!sk) {
+               __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
+               return -ENOENT;
+       }
 
-out_unlock:
+       sctp_v6_err_handle(transport, skb, type, code, ntohl(info));
        sctp_err_finish(sk, transport);
-       return ret;
+
+       return 0;
 }
 
 static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t)