Skip to content

Commit d830607

Browse files
lxindavem330
authored andcommitted
sctp: extract sctp_v4_err_handle function from sctp_v4_err
This patch is to extract sctp_v4_err_handle() from sctp_v4_err() to only handle the icmp err after the sock lookup, and it also makes the code clearer. sctp_v4_err_handle() will be used in sctp over udp's err handling in the following patch. Signed-off-by: Xin Long <[email protected]> Acked-by: Marcelo Ricardo Leitner <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f6549bd commit d830607

File tree

1 file changed

+49
-57
lines changed

1 file changed

+49
-57
lines changed

net/sctp/input.c

Lines changed: 49 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,49 @@ void sctp_err_finish(struct sock *sk, struct sctp_transport *t)
556556
sctp_transport_put(t);
557557
}
558558

559+
static void sctp_v4_err_handle(struct sctp_transport *t, struct sk_buff *skb,
560+
__u8 type, __u8 code, __u32 info)
561+
{
562+
struct sctp_association *asoc = t->asoc;
563+
struct sock *sk = asoc->base.sk;
564+
int err = 0;
565+
566+
switch (type) {
567+
case ICMP_PARAMETERPROB:
568+
err = EPROTO;
569+
break;
570+
case ICMP_DEST_UNREACH:
571+
if (code > NR_ICMP_UNREACH)
572+
return;
573+
if (code == ICMP_FRAG_NEEDED) {
574+
sctp_icmp_frag_needed(sk, asoc, t, SCTP_TRUNC4(info));
575+
return;
576+
}
577+
if (code == ICMP_PROT_UNREACH) {
578+
sctp_icmp_proto_unreachable(sk, asoc, t);
579+
return;
580+
}
581+
err = icmp_err_convert[code].errno;
582+
break;
583+
case ICMP_TIME_EXCEEDED:
584+
if (code == ICMP_EXC_FRAGTIME)
585+
return;
586+
587+
err = EHOSTUNREACH;
588+
break;
589+
case ICMP_REDIRECT:
590+
sctp_icmp_redirect(sk, t, skb);
591+
default:
592+
return;
593+
}
594+
if (!sock_owned_by_user(sk) && inet_sk(sk)->recverr) {
595+
sk->sk_err = err;
596+
sk->sk_error_report(sk);
597+
} else { /* Only an error on timeout */
598+
sk->sk_err_soft = err;
599+
}
600+
}
601+
559602
/*
560603
* This routine is called by the ICMP module when it gets some
561604
* sort of error condition. If err < 0 then the socket should
@@ -574,22 +617,19 @@ void sctp_err_finish(struct sock *sk, struct sctp_transport *t)
574617
int sctp_v4_err(struct sk_buff *skb, __u32 info)
575618
{
576619
const struct iphdr *iph = (const struct iphdr *)skb->data;
577-
const int ihlen = iph->ihl * 4;
578620
const int type = icmp_hdr(skb)->type;
579621
const int code = icmp_hdr(skb)->code;
580-
struct sock *sk;
581-
struct sctp_association *asoc = NULL;
622+
struct net *net = dev_net(skb->dev);
582623
struct sctp_transport *transport;
583-
struct inet_sock *inet;
624+
struct sctp_association *asoc;
584625
__u16 saveip, savesctp;
585-
int err;
586-
struct net *net = dev_net(skb->dev);
626+
struct sock *sk;
587627

588628
/* Fix up skb to look at the embedded net header. */
589629
saveip = skb->network_header;
590630
savesctp = skb->transport_header;
591631
skb_reset_network_header(skb);
592-
skb_set_transport_header(skb, ihlen);
632+
skb_set_transport_header(skb, iph->ihl * 4);
593633
sk = sctp_err_lookup(net, AF_INET, skb, sctp_hdr(skb), &asoc, &transport);
594634
/* Put back, the original values. */
595635
skb->network_header = saveip;
@@ -598,58 +638,10 @@ int sctp_v4_err(struct sk_buff *skb, __u32 info)
598638
__ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
599639
return -ENOENT;
600640
}
601-
/* Warning: The sock lock is held. Remember to call
602-
* sctp_err_finish!
603-
*/
604641

605-
switch (type) {
606-
case ICMP_PARAMETERPROB:
607-
err = EPROTO;
608-
break;
609-
case ICMP_DEST_UNREACH:
610-
if (code > NR_ICMP_UNREACH)
611-
goto out_unlock;
612-
613-
/* PMTU discovery (RFC1191) */
614-
if (ICMP_FRAG_NEEDED == code) {
615-
sctp_icmp_frag_needed(sk, asoc, transport,
616-
SCTP_TRUNC4(info));
617-
goto out_unlock;
618-
} else {
619-
if (ICMP_PROT_UNREACH == code) {
620-
sctp_icmp_proto_unreachable(sk, asoc,
621-
transport);
622-
goto out_unlock;
623-
}
624-
}
625-
err = icmp_err_convert[code].errno;
626-
break;
627-
case ICMP_TIME_EXCEEDED:
628-
/* Ignore any time exceeded errors due to fragment reassembly
629-
* timeouts.
630-
*/
631-
if (ICMP_EXC_FRAGTIME == code)
632-
goto out_unlock;
633-
634-
err = EHOSTUNREACH;
635-
break;
636-
case ICMP_REDIRECT:
637-
sctp_icmp_redirect(sk, transport, skb);
638-
/* Fall through to out_unlock. */
639-
default:
640-
goto out_unlock;
641-
}
642-
643-
inet = inet_sk(sk);
644-
if (!sock_owned_by_user(sk) && inet->recverr) {
645-
sk->sk_err = err;
646-
sk->sk_error_report(sk);
647-
} else { /* Only an error on timeout */
648-
sk->sk_err_soft = err;
649-
}
650-
651-
out_unlock:
642+
sctp_v4_err_handle(transport, skb, type, code, info);
652643
sctp_err_finish(sk, transport);
644+
653645
return 0;
654646
}
655647

0 commit comments

Comments
 (0)