@@ -122,50 +122,28 @@ static struct notifier_block sctp_inet6addr_notifier = {
122122 .notifier_call = sctp_inet6addr_event ,
123123};
124124
125- /* ICMP error handler. */
126- static int sctp_v6_err (struct sk_buff * skb , struct inet6_skb_parm * opt ,
127- u8 type , u8 code , int offset , __be32 info )
125+ static void sctp_v6_err_handle (struct sctp_transport * t , struct sk_buff * skb ,
126+ __u8 type , __u8 code , __u32 info )
128127{
129- struct sock * sk ;
130- struct sctp_association * asoc ;
131- struct sctp_transport * transport ;
128+ struct sctp_association * asoc = t -> asoc ;
129+ struct sock * sk = asoc -> base .sk ;
132130 struct ipv6_pinfo * np ;
133- __u16 saveip , savesctp ;
134- int err , ret = 0 ;
135- struct net * net = dev_net (skb -> dev );
136-
137- /* Fix up skb to look at the embedded net header. */
138- saveip = skb -> network_header ;
139- savesctp = skb -> transport_header ;
140- skb_reset_network_header (skb );
141- skb_set_transport_header (skb , offset );
142- sk = sctp_err_lookup (net , AF_INET6 , skb , sctp_hdr (skb ), & asoc , & transport );
143- /* Put back, the original pointers. */
144- skb -> network_header = saveip ;
145- skb -> transport_header = savesctp ;
146- if (!sk ) {
147- __ICMP6_INC_STATS (net , __in6_dev_get (skb -> dev ), ICMP6_MIB_INERRORS );
148- return - ENOENT ;
149- }
150-
151- /* Warning: The sock lock is held. Remember to call
152- * sctp_err_finish!
153- */
131+ int err = 0 ;
154132
155133 switch (type ) {
156134 case ICMPV6_PKT_TOOBIG :
157135 if (ip6_sk_accept_pmtu (sk ))
158- sctp_icmp_frag_needed (sk , asoc , transport , ntohl ( info ) );
159- goto out_unlock ;
136+ sctp_icmp_frag_needed (sk , asoc , t , info );
137+ return ;
160138 case ICMPV6_PARAMPROB :
161139 if (ICMPV6_UNK_NEXTHDR == code ) {
162- sctp_icmp_proto_unreachable (sk , asoc , transport );
163- goto out_unlock ;
140+ sctp_icmp_proto_unreachable (sk , asoc , t );
141+ return ;
164142 }
165143 break ;
166144 case NDISC_REDIRECT :
167- sctp_icmp_redirect (sk , transport , skb );
168- goto out_unlock ;
145+ sctp_icmp_redirect (sk , t , skb );
146+ return ;
169147 default :
170148 break ;
171149 }
@@ -175,13 +153,39 @@ static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
175153 if (!sock_owned_by_user (sk ) && np -> recverr ) {
176154 sk -> sk_err = err ;
177155 sk -> sk_error_report (sk );
178- } else { /* Only an error on timeout */
156+ } else {
179157 sk -> sk_err_soft = err ;
180158 }
159+ }
160+
161+ /* ICMP error handler. */
162+ static int sctp_v6_err (struct sk_buff * skb , struct inet6_skb_parm * opt ,
163+ u8 type , u8 code , int offset , __be32 info )
164+ {
165+ struct net * net = dev_net (skb -> dev );
166+ struct sctp_transport * transport ;
167+ struct sctp_association * asoc ;
168+ __u16 saveip , savesctp ;
169+ struct sock * sk ;
170+
171+ /* Fix up skb to look at the embedded net header. */
172+ saveip = skb -> network_header ;
173+ savesctp = skb -> transport_header ;
174+ skb_reset_network_header (skb );
175+ skb_set_transport_header (skb , offset );
176+ sk = sctp_err_lookup (net , AF_INET6 , skb , sctp_hdr (skb ), & asoc , & transport );
177+ /* Put back, the original pointers. */
178+ skb -> network_header = saveip ;
179+ skb -> transport_header = savesctp ;
180+ if (!sk ) {
181+ __ICMP6_INC_STATS (net , __in6_dev_get (skb -> dev ), ICMP6_MIB_INERRORS );
182+ return - ENOENT ;
183+ }
181184
182- out_unlock :
185+ sctp_v6_err_handle ( transport , skb , type , code , ntohl ( info ));
183186 sctp_err_finish (sk , transport );
184- return ret ;
187+
188+ return 0 ;
185189}
186190
187191static int sctp_v6_xmit (struct sk_buff * skb , struct sctp_transport * t )
0 commit comments