Commit f6549bd3 authored by Xin Long's avatar Xin Long Committed by David S. Miller

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: default avatarXin Long <lucien.xin@gmail.com>
Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 237a6a2e
...@@ -122,50 +122,28 @@ static struct notifier_block sctp_inet6addr_notifier = { ...@@ -122,50 +122,28 @@ static struct notifier_block sctp_inet6addr_notifier = {
.notifier_call = sctp_inet6addr_event, .notifier_call = sctp_inet6addr_event,
}; };
/* ICMP error handler. */ static void sctp_v6_err_handle(struct sctp_transport *t, struct sk_buff *skb,
static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, __u8 type, __u8 code, __u32 info)
u8 type, u8 code, int offset, __be32 info)
{ {
struct sock *sk; struct sctp_association *asoc = t->asoc;
struct sctp_association *asoc; struct sock *sk = asoc->base.sk;
struct sctp_transport *transport;
struct ipv6_pinfo *np; struct ipv6_pinfo *np;
__u16 saveip, savesctp; int err = 0;
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!
*/
switch (type) { switch (type) {
case ICMPV6_PKT_TOOBIG: case ICMPV6_PKT_TOOBIG:
if (ip6_sk_accept_pmtu(sk)) if (ip6_sk_accept_pmtu(sk))
sctp_icmp_frag_needed(sk, asoc, transport, ntohl(info)); sctp_icmp_frag_needed(sk, asoc, t, info);
goto out_unlock; return;
case ICMPV6_PARAMPROB: case ICMPV6_PARAMPROB:
if (ICMPV6_UNK_NEXTHDR == code) { if (ICMPV6_UNK_NEXTHDR == code) {
sctp_icmp_proto_unreachable(sk, asoc, transport); sctp_icmp_proto_unreachable(sk, asoc, t);
goto out_unlock; return;
} }
break; break;
case NDISC_REDIRECT: case NDISC_REDIRECT:
sctp_icmp_redirect(sk, transport, skb); sctp_icmp_redirect(sk, t, skb);
goto out_unlock; return;
default: default:
break; break;
} }
...@@ -175,13 +153,39 @@ static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -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) { if (!sock_owned_by_user(sk) && np->recverr) {
sk->sk_err = err; sk->sk_err = err;
sk->sk_error_report(sk); sk->sk_error_report(sk);
} else { /* Only an error on timeout */ } else {
sk->sk_err_soft = err; 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); 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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment