mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
sctp: extract sctp_v6_err_handle function from sctp_v6_err
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>
This commit is contained in:
parent
237a6a2e31
commit
f6549bd37b
@ -122,17 +122,51 @@ static struct notifier_block sctp_inet6addr_notifier = {
|
|||||||
.notifier_call = sctp_inet6addr_event,
|
.notifier_call = sctp_inet6addr_event,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void sctp_v6_err_handle(struct sctp_transport *t, struct sk_buff *skb,
|
||||||
|
__u8 type, __u8 code, __u32 info)
|
||||||
|
{
|
||||||
|
struct sctp_association *asoc = t->asoc;
|
||||||
|
struct sock *sk = asoc->base.sk;
|
||||||
|
struct ipv6_pinfo *np;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case ICMPV6_PKT_TOOBIG:
|
||||||
|
if (ip6_sk_accept_pmtu(sk))
|
||||||
|
sctp_icmp_frag_needed(sk, asoc, t, info);
|
||||||
|
return;
|
||||||
|
case ICMPV6_PARAMPROB:
|
||||||
|
if (ICMPV6_UNK_NEXTHDR == code) {
|
||||||
|
sctp_icmp_proto_unreachable(sk, asoc, t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NDISC_REDIRECT:
|
||||||
|
sctp_icmp_redirect(sk, t, skb);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
np = inet6_sk(sk);
|
||||||
|
icmpv6_err_convert(type, code, &err);
|
||||||
|
if (!sock_owned_by_user(sk) && np->recverr) {
|
||||||
|
sk->sk_err = err;
|
||||||
|
sk->sk_error_report(sk);
|
||||||
|
} else {
|
||||||
|
sk->sk_err_soft = err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ICMP error handler. */
|
/* ICMP error handler. */
|
||||||
static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||||
u8 type, u8 code, int offset, __be32 info)
|
u8 type, u8 code, int offset, __be32 info)
|
||||||
{
|
{
|
||||||
struct sock *sk;
|
|
||||||
struct sctp_association *asoc;
|
|
||||||
struct sctp_transport *transport;
|
|
||||||
struct ipv6_pinfo *np;
|
|
||||||
__u16 saveip, savesctp;
|
|
||||||
int err, ret = 0;
|
|
||||||
struct net *net = dev_net(skb->dev);
|
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. */
|
/* Fix up skb to look at the embedded net header. */
|
||||||
saveip = skb->network_header;
|
saveip = skb->network_header;
|
||||||
@ -148,40 +182,10 @@ static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Warning: The sock lock is held. Remember to call
|
sctp_v6_err_handle(transport, skb, type, code, ntohl(info));
|
||||||
* sctp_err_finish!
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case ICMPV6_PKT_TOOBIG:
|
|
||||||
if (ip6_sk_accept_pmtu(sk))
|
|
||||||
sctp_icmp_frag_needed(sk, asoc, transport, ntohl(info));
|
|
||||||
goto out_unlock;
|
|
||||||
case ICMPV6_PARAMPROB:
|
|
||||||
if (ICMPV6_UNK_NEXTHDR == code) {
|
|
||||||
sctp_icmp_proto_unreachable(sk, asoc, transport);
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NDISC_REDIRECT:
|
|
||||||
sctp_icmp_redirect(sk, transport, skb);
|
|
||||||
goto out_unlock;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
np = inet6_sk(sk);
|
|
||||||
icmpv6_err_convert(type, code, &err);
|
|
||||||
if (!sock_owned_by_user(sk) && np->recverr) {
|
|
||||||
sk->sk_err = err;
|
|
||||||
sk->sk_error_report(sk);
|
|
||||||
} else { /* Only an error on timeout */
|
|
||||||
sk->sk_err_soft = err;
|
|
||||||
}
|
|
||||||
|
|
||||||
out_unlock:
|
|
||||||
sctp_err_finish(sk, transport);
|
sctp_err_finish(sk, transport);
|
||||||
return ret;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t)
|
static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t)
|
||||||
|
Loading…
Reference in New Issue
Block a user