summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2018-11-08 06:19:21 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-08 20:13:08 -0500
commit32bbd8793f24b0d5beb1cdb33c45c75ad1140e4b (patch)
tree69b7c7f0348e063bd81215058130c1b1800410db
parentce7336610ca950cda131293def57a0178d860121 (diff)
net: Convert protocol error handlers from void to int
We'll need this to handle ICMP errors for tunnels without a sending socket (i.e. FoU and GUE). There, we might have to look up different types of IP tunnels, registered as network protocols, before we get a match, so we want this for the error handlers of IPPROTO_IPIP and IPPROTO_IPV6 in both inet_protos and inet6_protos. These error codes will be used in the next patch. For consistency, return sensible error codes in protocol error handlers whenever handlers can't handle errors because, even if valid, they don't match a protocol or any of its states. This has no effect on existing error handling paths. Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/icmp.h2
-rw-r--r--include/net/protocol.h9
-rw-r--r--include/net/sctp/sctp.h2
-rw-r--r--include/net/tcp.h2
-rw-r--r--include/net/udp.h2
-rw-r--r--net/dccp/ipv4.c13
-rw-r--r--net/dccp/ipv6.c13
-rw-r--r--net/ipv4/gre_demux.c9
-rw-r--r--net/ipv4/icmp.c6
-rw-r--r--net/ipv4/ip_gre.c48
-rw-r--r--net/ipv4/ipip.c14
-rw-r--r--net/ipv4/tcp_ipv4.c22
-rw-r--r--net/ipv4/tunnel4.c18
-rw-r--r--net/ipv4/udp.c10
-rw-r--r--net/ipv4/udp_impl.h2
-rw-r--r--net/ipv4/udplite.c4
-rw-r--r--net/ipv4/xfrm4_protocol.c18
-rw-r--r--net/ipv6/icmp.c4
-rw-r--r--net/ipv6/ip6_gre.c18
-rw-r--r--net/ipv6/tcp_ipv6.c13
-rw-r--r--net/ipv6/tunnel6.c12
-rw-r--r--net/ipv6/udp.c18
-rw-r--r--net/ipv6/udp_impl.h4
-rw-r--r--net/ipv6/udplite.c5
-rw-r--r--net/ipv6/xfrm6_protocol.c18
-rw-r--r--net/sctp/input.c5
-rw-r--r--net/sctp/ipv6.c7
27 files changed, 177 insertions, 121 deletions
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 3ef2743a8eec..6ac3a5bd0117 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -41,7 +41,7 @@ struct net;
41 41
42void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); 42void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info);
43int icmp_rcv(struct sk_buff *skb); 43int icmp_rcv(struct sk_buff *skb);
44void icmp_err(struct sk_buff *skb, u32 info); 44int icmp_err(struct sk_buff *skb, u32 info);
45int icmp_init(void); 45int icmp_init(void);
46void icmp_out_count(struct net *net, unsigned char type); 46void icmp_out_count(struct net *net, unsigned char type);
47 47
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 4fc75f7ae23b..92b3eaad6088 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -42,7 +42,10 @@ struct net_protocol {
42 int (*early_demux)(struct sk_buff *skb); 42 int (*early_demux)(struct sk_buff *skb);
43 int (*early_demux_handler)(struct sk_buff *skb); 43 int (*early_demux_handler)(struct sk_buff *skb);
44 int (*handler)(struct sk_buff *skb); 44 int (*handler)(struct sk_buff *skb);
45 void (*err_handler)(struct sk_buff *skb, u32 info); 45
46 /* This returns an error if we weren't able to handle the error. */
47 int (*err_handler)(struct sk_buff *skb, u32 info);
48
46 unsigned int no_policy:1, 49 unsigned int no_policy:1,
47 netns_ok:1, 50 netns_ok:1,
48 /* does the protocol do more stringent 51 /* does the protocol do more stringent
@@ -58,10 +61,12 @@ struct inet6_protocol {
58 void (*early_demux_handler)(struct sk_buff *skb); 61 void (*early_demux_handler)(struct sk_buff *skb);
59 int (*handler)(struct sk_buff *skb); 62 int (*handler)(struct sk_buff *skb);
60 63
61 void (*err_handler)(struct sk_buff *skb, 64 /* This returns an error if we weren't able to handle the error. */
65 int (*err_handler)(struct sk_buff *skb,
62 struct inet6_skb_parm *opt, 66 struct inet6_skb_parm *opt,
63 u8 type, u8 code, int offset, 67 u8 type, u8 code, int offset,
64 __be32 info); 68 __be32 info);
69
65 unsigned int flags; /* INET6_PROTO_xxx */ 70 unsigned int flags; /* INET6_PROTO_xxx */
66}; 71};
67 72
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 8c2caa370e0f..9a3b48a35e90 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -151,7 +151,7 @@ int sctp_primitive_RECONF(struct net *net, struct sctp_association *asoc,
151 * sctp/input.c 151 * sctp/input.c
152 */ 152 */
153int sctp_rcv(struct sk_buff *skb); 153int sctp_rcv(struct sk_buff *skb);
154void sctp_v4_err(struct sk_buff *skb, u32 info); 154int sctp_v4_err(struct sk_buff *skb, u32 info);
155void sctp_hash_endpoint(struct sctp_endpoint *); 155void sctp_hash_endpoint(struct sctp_endpoint *);
156void sctp_unhash_endpoint(struct sctp_endpoint *); 156void sctp_unhash_endpoint(struct sctp_endpoint *);
157struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *, 157struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *,
diff --git a/include/net/tcp.h b/include/net/tcp.h
index a18914d20486..4743836bed2e 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -313,7 +313,7 @@ extern struct proto tcp_prot;
313 313
314void tcp_tasklet_init(void); 314void tcp_tasklet_init(void);
315 315
316void tcp_v4_err(struct sk_buff *skb, u32); 316int tcp_v4_err(struct sk_buff *skb, u32);
317 317
318void tcp_shutdown(struct sock *sk, int how); 318void tcp_shutdown(struct sock *sk, int how);
319 319
diff --git a/include/net/udp.h b/include/net/udp.h
index eccca2325ee6..fd6d948755c8 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -283,7 +283,7 @@ bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst);
283int udp_get_port(struct sock *sk, unsigned short snum, 283int udp_get_port(struct sock *sk, unsigned short snum,
284 int (*saddr_cmp)(const struct sock *, 284 int (*saddr_cmp)(const struct sock *,
285 const struct sock *)); 285 const struct sock *));
286void udp_err(struct sk_buff *, u32); 286int udp_err(struct sk_buff *, u32);
287int udp_abort(struct sock *sk, int err); 287int udp_abort(struct sock *sk, int err);
288int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); 288int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
289int udp_push_pending_frames(struct sock *sk); 289int udp_push_pending_frames(struct sock *sk);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 8e08cea6f178..26a21d97b6b0 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -231,7 +231,7 @@ EXPORT_SYMBOL(dccp_req_err);
231 * check at all. A more general error queue to queue errors for later handling 231 * check at all. A more general error queue to queue errors for later handling
232 * is probably better. 232 * is probably better.
233 */ 233 */
234static void dccp_v4_err(struct sk_buff *skb, u32 info) 234static int dccp_v4_err(struct sk_buff *skb, u32 info)
235{ 235{
236 const struct iphdr *iph = (struct iphdr *)skb->data; 236 const struct iphdr *iph = (struct iphdr *)skb->data;
237 const u8 offset = iph->ihl << 2; 237 const u8 offset = iph->ihl << 2;
@@ -259,16 +259,18 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
259 inet_iif(skb), 0); 259 inet_iif(skb), 0);
260 if (!sk) { 260 if (!sk) {
261 __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); 261 __ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
262 return; 262 return -ENOENT;
263 } 263 }
264 264
265 if (sk->sk_state == DCCP_TIME_WAIT) { 265 if (sk->sk_state == DCCP_TIME_WAIT) {
266 inet_twsk_put(inet_twsk(sk)); 266 inet_twsk_put(inet_twsk(sk));
267 return; 267 return 0;
268 } 268 }
269 seq = dccp_hdr_seq(dh); 269 seq = dccp_hdr_seq(dh);
270 if (sk->sk_state == DCCP_NEW_SYN_RECV) 270 if (sk->sk_state == DCCP_NEW_SYN_RECV) {
271 return dccp_req_err(sk, seq); 271 dccp_req_err(sk, seq);
272 return 0;
273 }
272 274
273 bh_lock_sock(sk); 275 bh_lock_sock(sk);
274 /* If too many ICMPs get dropped on busy 276 /* If too many ICMPs get dropped on busy
@@ -357,6 +359,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
357out: 359out:
358 bh_unlock_sock(sk); 360 bh_unlock_sock(sk);
359 sock_put(sk); 361 sock_put(sk);
362 return 0;
360} 363}
361 364
362static inline __sum16 dccp_v4_csum_finish(struct sk_buff *skb, 365static inline __sum16 dccp_v4_csum_finish(struct sk_buff *skb,
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 6344f1b18a6a..d5740bad5b18 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -68,7 +68,7 @@ static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb)
68 68
69} 69}
70 70
71static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 71static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
72 u8 type, u8 code, int offset, __be32 info) 72 u8 type, u8 code, int offset, __be32 info)
73{ 73{
74 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; 74 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
@@ -96,16 +96,18 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
96 if (!sk) { 96 if (!sk) {
97 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), 97 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
98 ICMP6_MIB_INERRORS); 98 ICMP6_MIB_INERRORS);
99 return; 99 return -ENOENT;
100 } 100 }
101 101
102 if (sk->sk_state == DCCP_TIME_WAIT) { 102 if (sk->sk_state == DCCP_TIME_WAIT) {
103 inet_twsk_put(inet_twsk(sk)); 103 inet_twsk_put(inet_twsk(sk));
104 return; 104 return 0;
105 } 105 }
106 seq = dccp_hdr_seq(dh); 106 seq = dccp_hdr_seq(dh);
107 if (sk->sk_state == DCCP_NEW_SYN_RECV) 107 if (sk->sk_state == DCCP_NEW_SYN_RECV) {
108 return dccp_req_err(sk, seq); 108 dccp_req_err(sk, seq);
109 return 0;
110 }
109 111
110 bh_lock_sock(sk); 112 bh_lock_sock(sk);
111 if (sock_owned_by_user(sk)) 113 if (sock_owned_by_user(sk))
@@ -183,6 +185,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
183out: 185out:
184 bh_unlock_sock(sk); 186 bh_unlock_sock(sk);
185 sock_put(sk); 187 sock_put(sk);
188 return 0;
186} 189}
187 190
188 191
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c
index 7efe740c06eb..a4bf22ee3aed 100644
--- a/net/ipv4/gre_demux.c
+++ b/net/ipv4/gre_demux.c
@@ -151,20 +151,25 @@ drop:
151 return NET_RX_DROP; 151 return NET_RX_DROP;
152} 152}
153 153
154static void gre_err(struct sk_buff *skb, u32 info) 154static int gre_err(struct sk_buff *skb, u32 info)
155{ 155{
156 const struct gre_protocol *proto; 156 const struct gre_protocol *proto;
157 const struct iphdr *iph = (const struct iphdr *)skb->data; 157 const struct iphdr *iph = (const struct iphdr *)skb->data;
158 u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f; 158 u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
159 int err = 0;
159 160
160 if (ver >= GREPROTO_MAX) 161 if (ver >= GREPROTO_MAX)
161 return; 162 return -EINVAL;
162 163
163 rcu_read_lock(); 164 rcu_read_lock();
164 proto = rcu_dereference(gre_proto[ver]); 165 proto = rcu_dereference(gre_proto[ver]);
165 if (proto && proto->err_handler) 166 if (proto && proto->err_handler)
166 proto->err_handler(skb, info); 167 proto->err_handler(skb, info);
168 else
169 err = -EPROTONOSUPPORT;
167 rcu_read_unlock(); 170 rcu_read_unlock();
171
172 return err;
168} 173}
169 174
170static const struct net_protocol net_gre_protocol = { 175static const struct net_protocol net_gre_protocol = {
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index d832beed6e3a..065997f414e6 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -1079,7 +1079,7 @@ error:
1079 goto drop; 1079 goto drop;
1080} 1080}
1081 1081
1082void icmp_err(struct sk_buff *skb, u32 info) 1082int icmp_err(struct sk_buff *skb, u32 info)
1083{ 1083{
1084 struct iphdr *iph = (struct iphdr *)skb->data; 1084 struct iphdr *iph = (struct iphdr *)skb->data;
1085 int offset = iph->ihl<<2; 1085 int offset = iph->ihl<<2;
@@ -1094,13 +1094,15 @@ void icmp_err(struct sk_buff *skb, u32 info)
1094 */ 1094 */
1095 if (icmph->type != ICMP_ECHOREPLY) { 1095 if (icmph->type != ICMP_ECHOREPLY) {
1096 ping_err(skb, offset, info); 1096 ping_err(skb, offset, info);
1097 return; 1097 return 0;
1098 } 1098 }
1099 1099
1100 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) 1100 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
1101 ipv4_update_pmtu(skb, net, info, 0, IPPROTO_ICMP); 1101 ipv4_update_pmtu(skb, net, info, 0, IPPROTO_ICMP);
1102 else if (type == ICMP_REDIRECT) 1102 else if (type == ICMP_REDIRECT)
1103 ipv4_redirect(skb, net, 0, IPPROTO_ICMP); 1103 ipv4_redirect(skb, net, 0, IPPROTO_ICMP);
1104
1105 return 0;
1104} 1106}
1105 1107
1106/* 1108/*
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 2c67af644e64..76a9a5f7a40e 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -121,8 +121,8 @@ static unsigned int ipgre_net_id __read_mostly;
121static unsigned int gre_tap_net_id __read_mostly; 121static unsigned int gre_tap_net_id __read_mostly;
122static unsigned int erspan_net_id __read_mostly; 122static unsigned int erspan_net_id __read_mostly;
123 123
124static void ipgre_err(struct sk_buff *skb, u32 info, 124static int ipgre_err(struct sk_buff *skb, u32 info,
125 const struct tnl_ptk_info *tpi) 125 const struct tnl_ptk_info *tpi)
126{ 126{
127 127
128 /* All the routers (except for Linux) return only 128 /* All the routers (except for Linux) return only
@@ -146,17 +146,32 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
146 unsigned int data_len = 0; 146 unsigned int data_len = 0;
147 struct ip_tunnel *t; 147 struct ip_tunnel *t;
148 148
149 if (tpi->proto == htons(ETH_P_TEB))
150 itn = net_generic(net, gre_tap_net_id);
151 else if (tpi->proto == htons(ETH_P_ERSPAN) ||
152 tpi->proto == htons(ETH_P_ERSPAN2))
153 itn = net_generic(net, erspan_net_id);
154 else
155 itn = net_generic(net, ipgre_net_id);
156
157 iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
158 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
159 iph->daddr, iph->saddr, tpi->key);
160
161 if (!t)
162 return -ENOENT;
163
149 switch (type) { 164 switch (type) {
150 default: 165 default:
151 case ICMP_PARAMETERPROB: 166 case ICMP_PARAMETERPROB:
152 return; 167 return 0;
153 168
154 case ICMP_DEST_UNREACH: 169 case ICMP_DEST_UNREACH:
155 switch (code) { 170 switch (code) {
156 case ICMP_SR_FAILED: 171 case ICMP_SR_FAILED:
157 case ICMP_PORT_UNREACH: 172 case ICMP_PORT_UNREACH:
158 /* Impossible event. */ 173 /* Impossible event. */
159 return; 174 return 0;
160 default: 175 default:
161 /* All others are translated to HOST_UNREACH. 176 /* All others are translated to HOST_UNREACH.
162 rfc2003 contains "deep thoughts" about NET_UNREACH, 177 rfc2003 contains "deep thoughts" about NET_UNREACH,
@@ -168,7 +183,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
168 183
169 case ICMP_TIME_EXCEEDED: 184 case ICMP_TIME_EXCEEDED:
170 if (code != ICMP_EXC_TTL) 185 if (code != ICMP_EXC_TTL)
171 return; 186 return 0;
172 data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */ 187 data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */
173 break; 188 break;
174 189
@@ -176,40 +191,27 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
176 break; 191 break;
177 } 192 }
178 193
179 if (tpi->proto == htons(ETH_P_TEB))
180 itn = net_generic(net, gre_tap_net_id);
181 else if (tpi->proto == htons(ETH_P_ERSPAN) ||
182 tpi->proto == htons(ETH_P_ERSPAN2))
183 itn = net_generic(net, erspan_net_id);
184 else
185 itn = net_generic(net, ipgre_net_id);
186
187 iph = (const struct iphdr *)(icmp_hdr(skb) + 1);
188 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
189 iph->daddr, iph->saddr, tpi->key);
190
191 if (!t)
192 return;
193
194#if IS_ENABLED(CONFIG_IPV6) 194#if IS_ENABLED(CONFIG_IPV6)
195 if (tpi->proto == htons(ETH_P_IPV6) && 195 if (tpi->proto == htons(ETH_P_IPV6) &&
196 !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len, 196 !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len,
197 type, data_len)) 197 type, data_len))
198 return; 198 return 0;
199#endif 199#endif
200 200
201 if (t->parms.iph.daddr == 0 || 201 if (t->parms.iph.daddr == 0 ||
202 ipv4_is_multicast(t->parms.iph.daddr)) 202 ipv4_is_multicast(t->parms.iph.daddr))
203 return; 203 return 0;
204 204
205 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) 205 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
206 return; 206 return 0;
207 207
208 if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO)) 208 if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
209 t->err_count++; 209 t->err_count++;
210 else 210 else
211 t->err_count = 1; 211 t->err_count = 1;
212 t->err_time = jiffies; 212 t->err_time = jiffies;
213
214 return 0;
213} 215}
214 216
215static void gre_err(struct sk_buff *skb, u32 info) 217static void gre_err(struct sk_buff *skb, u32 info)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index e65287c27e3d..57c5dd283a2c 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -140,6 +140,13 @@ static int ipip_err(struct sk_buff *skb, u32 info)
140 struct ip_tunnel *t; 140 struct ip_tunnel *t;
141 int err = 0; 141 int err = 0;
142 142
143 t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
144 iph->daddr, iph->saddr, 0);
145 if (!t) {
146 err = -ENOENT;
147 goto out;
148 }
149
143 switch (type) { 150 switch (type) {
144 case ICMP_DEST_UNREACH: 151 case ICMP_DEST_UNREACH:
145 switch (code) { 152 switch (code) {
@@ -167,13 +174,6 @@ static int ipip_err(struct sk_buff *skb, u32 info)
167 goto out; 174 goto out;
168 } 175 }
169 176
170 t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
171 iph->daddr, iph->saddr, 0);
172 if (!t) {
173 err = -ENOENT;
174 goto out;
175 }
176
177 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { 177 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
178 ipv4_update_pmtu(skb, net, info, t->parms.link, iph->protocol); 178 ipv4_update_pmtu(skb, net, info, t->parms.link, iph->protocol);
179 goto out; 179 goto out;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index de47038afdf0..a336787d75e5 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -423,7 +423,7 @@ EXPORT_SYMBOL(tcp_req_err);
423 * 423 *
424 */ 424 */
425 425
426void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) 426int tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
427{ 427{
428 const struct iphdr *iph = (const struct iphdr *)icmp_skb->data; 428 const struct iphdr *iph = (const struct iphdr *)icmp_skb->data;
429 struct tcphdr *th = (struct tcphdr *)(icmp_skb->data + (iph->ihl << 2)); 429 struct tcphdr *th = (struct tcphdr *)(icmp_skb->data + (iph->ihl << 2));
@@ -446,20 +446,21 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
446 inet_iif(icmp_skb), 0); 446 inet_iif(icmp_skb), 0);
447 if (!sk) { 447 if (!sk) {
448 __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); 448 __ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
449 return; 449 return -ENOENT;
450 } 450 }
451 if (sk->sk_state == TCP_TIME_WAIT) { 451 if (sk->sk_state == TCP_TIME_WAIT) {
452 inet_twsk_put(inet_twsk(sk)); 452 inet_twsk_put(inet_twsk(sk));
453 return; 453 return 0;
454 } 454 }
455 seq = ntohl(th->seq); 455 seq = ntohl(th->seq);
456 if (sk->sk_state == TCP_NEW_SYN_RECV) 456 if (sk->sk_state == TCP_NEW_SYN_RECV) {
457 return tcp_req_err(sk, seq, 457 tcp_req_err(sk, seq, type == ICMP_PARAMETERPROB ||
458 type == ICMP_PARAMETERPROB || 458 type == ICMP_TIME_EXCEEDED ||
459 type == ICMP_TIME_EXCEEDED || 459 (type == ICMP_DEST_UNREACH &&
460 (type == ICMP_DEST_UNREACH && 460 (code == ICMP_NET_UNREACH ||
461 (code == ICMP_NET_UNREACH || 461 code == ICMP_HOST_UNREACH)));
462 code == ICMP_HOST_UNREACH))); 462 return 0;
463 }
463 464
464 bh_lock_sock(sk); 465 bh_lock_sock(sk);
465 /* If too many ICMPs get dropped on busy 466 /* If too many ICMPs get dropped on busy
@@ -613,6 +614,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
613out: 614out:
614 bh_unlock_sock(sk); 615 bh_unlock_sock(sk);
615 sock_put(sk); 616 sock_put(sk);
617 return 0;
616} 618}
617 619
618void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr) 620void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr)
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c
index c0630013c1ae..33bf8e9c8663 100644
--- a/net/ipv4/tunnel4.c
+++ b/net/ipv4/tunnel4.c
@@ -149,34 +149,40 @@ drop:
149} 149}
150#endif 150#endif
151 151
152static void tunnel4_err(struct sk_buff *skb, u32 info) 152static int tunnel4_err(struct sk_buff *skb, u32 info)
153{ 153{
154 struct xfrm_tunnel *handler; 154 struct xfrm_tunnel *handler;
155 155
156 for_each_tunnel_rcu(tunnel4_handlers, handler) 156 for_each_tunnel_rcu(tunnel4_handlers, handler)
157 if (!handler->err_handler(skb, info)) 157 if (!handler->err_handler(skb, info))
158 break; 158 return 0;
159
160 return -ENOENT;
159} 161}
160 162
161#if IS_ENABLED(CONFIG_IPV6) 163#if IS_ENABLED(CONFIG_IPV6)
162static void tunnel64_err(struct sk_buff *skb, u32 info) 164static int tunnel64_err(struct sk_buff *skb, u32 info)
163{ 165{
164 struct xfrm_tunnel *handler; 166 struct xfrm_tunnel *handler;
165 167
166 for_each_tunnel_rcu(tunnel64_handlers, handler) 168 for_each_tunnel_rcu(tunnel64_handlers, handler)
167 if (!handler->err_handler(skb, info)) 169 if (!handler->err_handler(skb, info))
168 break; 170 return 0;
171
172 return -ENOENT;
169} 173}
170#endif 174#endif
171 175
172#if IS_ENABLED(CONFIG_MPLS) 176#if IS_ENABLED(CONFIG_MPLS)
173static void tunnelmpls4_err(struct sk_buff *skb, u32 info) 177static int tunnelmpls4_err(struct sk_buff *skb, u32 info)
174{ 178{
175 struct xfrm_tunnel *handler; 179 struct xfrm_tunnel *handler;
176 180
177 for_each_tunnel_rcu(tunnelmpls4_handlers, handler) 181 for_each_tunnel_rcu(tunnelmpls4_handlers, handler)
178 if (!handler->err_handler(skb, info)) 182 if (!handler->err_handler(skb, info))
179 break; 183 return 0;
184
185 return -ENOENT;
180} 186}
181#endif 187#endif
182 188
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ce759b61f6cd..a505ee5eb92c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -650,7 +650,7 @@ static struct sock *__udp4_lib_err_encap(struct net *net,
650 * to find the appropriate port. 650 * to find the appropriate port.
651 */ 651 */
652 652
653void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) 653int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
654{ 654{
655 struct inet_sock *inet; 655 struct inet_sock *inet;
656 const struct iphdr *iph = (const struct iphdr *)skb->data; 656 const struct iphdr *iph = (const struct iphdr *)skb->data;
@@ -673,7 +673,7 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
673 673
674 if (!sk) { 674 if (!sk) {
675 __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); 675 __ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
676 return; 676 return -ENOENT;
677 } 677 }
678 tunnel = true; 678 tunnel = true;
679 } 679 }
@@ -731,12 +731,12 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
731 sk->sk_err = err; 731 sk->sk_err = err;
732 sk->sk_error_report(sk); 732 sk->sk_error_report(sk);
733out: 733out:
734 return; 734 return 0;
735} 735}
736 736
737void udp_err(struct sk_buff *skb, u32 info) 737int udp_err(struct sk_buff *skb, u32 info)
738{ 738{
739 __udp4_lib_err(skb, info, &udp_table); 739 return __udp4_lib_err(skb, info, &udp_table);
740} 740}
741 741
742/* 742/*
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
index e7d18b140287..322672655419 100644
--- a/net/ipv4/udp_impl.h
+++ b/net/ipv4/udp_impl.h
@@ -7,7 +7,7 @@
7#include <net/inet_common.h> 7#include <net/inet_common.h>
8 8
9int __udp4_lib_rcv(struct sk_buff *, struct udp_table *, int); 9int __udp4_lib_rcv(struct sk_buff *, struct udp_table *, int);
10void __udp4_lib_err(struct sk_buff *, u32, struct udp_table *); 10int __udp4_lib_err(struct sk_buff *, u32, struct udp_table *);
11 11
12int udp_v4_get_port(struct sock *sk, unsigned short snum); 12int udp_v4_get_port(struct sock *sk, unsigned short snum);
13 13
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index 8545457752fb..39c7f17d916f 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -25,9 +25,9 @@ static int udplite_rcv(struct sk_buff *skb)
25 return __udp4_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE); 25 return __udp4_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
26} 26}
27 27
28static void udplite_err(struct sk_buff *skb, u32 info) 28static int udplite_err(struct sk_buff *skb, u32 info)
29{ 29{
30 __udp4_lib_err(skb, info, &udplite_table); 30 return __udp4_lib_err(skb, info, &udplite_table);
31} 31}
32 32
33static const struct net_protocol udplite_protocol = { 33static const struct net_protocol udplite_protocol = {
diff --git a/net/ipv4/xfrm4_protocol.c b/net/ipv4/xfrm4_protocol.c
index 8dd0e6ab8606..35c54865dc42 100644
--- a/net/ipv4/xfrm4_protocol.c
+++ b/net/ipv4/xfrm4_protocol.c
@@ -106,13 +106,15 @@ static int xfrm4_esp_rcv(struct sk_buff *skb)
106 return 0; 106 return 0;
107} 107}
108 108
109static void xfrm4_esp_err(struct sk_buff *skb, u32 info) 109static int xfrm4_esp_err(struct sk_buff *skb, u32 info)
110{ 110{
111 struct xfrm4_protocol *handler; 111 struct xfrm4_protocol *handler;
112 112
113 for_each_protocol_rcu(esp4_handlers, handler) 113 for_each_protocol_rcu(esp4_handlers, handler)
114 if (!handler->err_handler(skb, info)) 114 if (!handler->err_handler(skb, info))
115 break; 115 return 0;
116
117 return -ENOENT;
116} 118}
117 119
118static int xfrm4_ah_rcv(struct sk_buff *skb) 120static int xfrm4_ah_rcv(struct sk_buff *skb)
@@ -132,13 +134,15 @@ static int xfrm4_ah_rcv(struct sk_buff *skb)
132 return 0; 134 return 0;
133} 135}
134 136
135static void xfrm4_ah_err(struct sk_buff *skb, u32 info) 137static int xfrm4_ah_err(struct sk_buff *skb, u32 info)
136{ 138{
137 struct xfrm4_protocol *handler; 139 struct xfrm4_protocol *handler;
138 140
139 for_each_protocol_rcu(ah4_handlers, handler) 141 for_each_protocol_rcu(ah4_handlers, handler)
140 if (!handler->err_handler(skb, info)) 142 if (!handler->err_handler(skb, info))
141 break; 143 return 0;
144
145 return -ENOENT;
142} 146}
143 147
144static int xfrm4_ipcomp_rcv(struct sk_buff *skb) 148static int xfrm4_ipcomp_rcv(struct sk_buff *skb)
@@ -158,13 +162,15 @@ static int xfrm4_ipcomp_rcv(struct sk_buff *skb)
158 return 0; 162 return 0;
159} 163}
160 164
161static void xfrm4_ipcomp_err(struct sk_buff *skb, u32 info) 165static int xfrm4_ipcomp_err(struct sk_buff *skb, u32 info)
162{ 166{
163 struct xfrm4_protocol *handler; 167 struct xfrm4_protocol *handler;
164 168
165 for_each_protocol_rcu(ipcomp4_handlers, handler) 169 for_each_protocol_rcu(ipcomp4_handlers, handler)
166 if (!handler->err_handler(skb, info)) 170 if (!handler->err_handler(skb, info))
167 break; 171 return 0;
172
173 return -ENOENT;
168} 174}
169 175
170static const struct net_protocol esp4_protocol = { 176static const struct net_protocol esp4_protocol = {
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index c9c53ade55c3..5d7aa2c2770c 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -84,7 +84,7 @@ static inline struct sock *icmpv6_sk(struct net *net)
84 return net->ipv6.icmp_sk[smp_processor_id()]; 84 return net->ipv6.icmp_sk[smp_processor_id()];
85} 85}
86 86
87static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 87static int icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
88 u8 type, u8 code, int offset, __be32 info) 88 u8 type, u8 code, int offset, __be32 info)
89{ 89{
90 /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */ 90 /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */
@@ -100,6 +100,8 @@ static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
100 if (!(type & ICMPV6_INFOMSG_MASK)) 100 if (!(type & ICMPV6_INFOMSG_MASK))
101 if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST) 101 if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
102 ping_err(skb, offset, ntohl(info)); 102 ping_err(skb, offset, ntohl(info));
103
104 return 0;
103} 105}
104 106
105static int icmpv6_rcv(struct sk_buff *skb); 107static int icmpv6_rcv(struct sk_buff *skb);
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 515adbdba1d2..81b69bcee714 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -423,7 +423,7 @@ static void ip6gre_tunnel_uninit(struct net_device *dev)
423} 423}
424 424
425 425
426static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 426static int ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
427 u8 type, u8 code, int offset, __be32 info) 427 u8 type, u8 code, int offset, __be32 info)
428{ 428{
429 struct net *net = dev_net(skb->dev); 429 struct net *net = dev_net(skb->dev);
@@ -433,13 +433,13 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
433 433
434 if (gre_parse_header(skb, &tpi, NULL, htons(ETH_P_IPV6), 434 if (gre_parse_header(skb, &tpi, NULL, htons(ETH_P_IPV6),
435 offset) < 0) 435 offset) < 0)
436 return; 436 return -EINVAL;
437 437
438 ipv6h = (const struct ipv6hdr *)skb->data; 438 ipv6h = (const struct ipv6hdr *)skb->data;
439 t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr, 439 t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
440 tpi.key, tpi.proto); 440 tpi.key, tpi.proto);
441 if (!t) 441 if (!t)
442 return; 442 return -ENOENT;
443 443
444 switch (type) { 444 switch (type) {
445 struct ipv6_tlv_tnl_enc_lim *tel; 445 struct ipv6_tlv_tnl_enc_lim *tel;
@@ -449,14 +449,14 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
449 t->parms.name); 449 t->parms.name);
450 if (code != ICMPV6_PORT_UNREACH) 450 if (code != ICMPV6_PORT_UNREACH)
451 break; 451 break;
452 return; 452 return 0;
453 case ICMPV6_TIME_EXCEED: 453 case ICMPV6_TIME_EXCEED:
454 if (code == ICMPV6_EXC_HOPLIMIT) { 454 if (code == ICMPV6_EXC_HOPLIMIT) {
455 net_dbg_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n", 455 net_dbg_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n",
456 t->parms.name); 456 t->parms.name);
457 break; 457 break;
458 } 458 }
459 return; 459 return 0;
460 case ICMPV6_PARAMPROB: 460 case ICMPV6_PARAMPROB:
461 teli = 0; 461 teli = 0;
462 if (code == ICMPV6_HDR_FIELD) 462 if (code == ICMPV6_HDR_FIELD)
@@ -472,14 +472,14 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
472 net_dbg_ratelimited("%s: Recipient unable to parse tunneled packet!\n", 472 net_dbg_ratelimited("%s: Recipient unable to parse tunneled packet!\n",
473 t->parms.name); 473 t->parms.name);
474 } 474 }
475 return; 475 return 0;
476 case ICMPV6_PKT_TOOBIG: 476 case ICMPV6_PKT_TOOBIG:
477 ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL)); 477 ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL));
478 return; 478 return 0;
479 case NDISC_REDIRECT: 479 case NDISC_REDIRECT:
480 ip6_redirect(skb, net, skb->dev->ifindex, 0, 480 ip6_redirect(skb, net, skb->dev->ifindex, 0,
481 sock_net_uid(net, NULL)); 481 sock_net_uid(net, NULL));
482 return; 482 return 0;
483 } 483 }
484 484
485 if (time_before(jiffies, t->err_time + IP6TUNNEL_ERR_TIMEO)) 485 if (time_before(jiffies, t->err_time + IP6TUNNEL_ERR_TIMEO))
@@ -487,6 +487,8 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
487 else 487 else
488 t->err_count = 1; 488 t->err_count = 1;
489 t->err_time = jiffies; 489 t->err_time = jiffies;
490
491 return 0;
490} 492}
491 493
492static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) 494static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 03e6b7a2bc53..a3f559162521 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -349,7 +349,7 @@ static void tcp_v6_mtu_reduced(struct sock *sk)
349 } 349 }
350} 350}
351 351
352static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 352static int tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
353 u8 type, u8 code, int offset, __be32 info) 353 u8 type, u8 code, int offset, __be32 info)
354{ 354{
355 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; 355 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
@@ -371,17 +371,19 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
371 if (!sk) { 371 if (!sk) {
372 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), 372 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
373 ICMP6_MIB_INERRORS); 373 ICMP6_MIB_INERRORS);
374 return; 374 return -ENOENT;
375 } 375 }
376 376
377 if (sk->sk_state == TCP_TIME_WAIT) { 377 if (sk->sk_state == TCP_TIME_WAIT) {
378 inet_twsk_put(inet_twsk(sk)); 378 inet_twsk_put(inet_twsk(sk));
379 return; 379 return 0;
380 } 380 }
381 seq = ntohl(th->seq); 381 seq = ntohl(th->seq);
382 fatal = icmpv6_err_convert(type, code, &err); 382 fatal = icmpv6_err_convert(type, code, &err);
383 if (sk->sk_state == TCP_NEW_SYN_RECV) 383 if (sk->sk_state == TCP_NEW_SYN_RECV) {
384 return tcp_req_err(sk, seq, fatal); 384 tcp_req_err(sk, seq, fatal);
385 return 0;
386 }
385 387
386 bh_lock_sock(sk); 388 bh_lock_sock(sk);
387 if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG) 389 if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG)
@@ -467,6 +469,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
467out: 469out:
468 bh_unlock_sock(sk); 470 bh_unlock_sock(sk);
469 sock_put(sk); 471 sock_put(sk);
472 return 0;
470} 473}
471 474
472 475
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index dae25cad05cd..1991dede7367 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -134,24 +134,28 @@ drop:
134 return 0; 134 return 0;
135} 135}
136 136
137static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 137static int tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
138 u8 type, u8 code, int offset, __be32 info) 138 u8 type, u8 code, int offset, __be32 info)
139{ 139{
140 struct xfrm6_tunnel *handler; 140 struct xfrm6_tunnel *handler;
141 141
142 for_each_tunnel_rcu(tunnel6_handlers, handler) 142 for_each_tunnel_rcu(tunnel6_handlers, handler)
143 if (!handler->err_handler(skb, opt, type, code, offset, info)) 143 if (!handler->err_handler(skb, opt, type, code, offset, info))
144 break; 144 return 0;
145
146 return -ENOENT;
145} 147}
146 148
147static void tunnel46_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 149static int tunnel46_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
148 u8 type, u8 code, int offset, __be32 info) 150 u8 type, u8 code, int offset, __be32 info)
149{ 151{
150 struct xfrm6_tunnel *handler; 152 struct xfrm6_tunnel *handler;
151 153
152 for_each_tunnel_rcu(tunnel46_handlers, handler) 154 for_each_tunnel_rcu(tunnel46_handlers, handler)
153 if (!handler->err_handler(skb, opt, type, code, offset, info)) 155 if (!handler->err_handler(skb, opt, type, code, offset, info))
154 break; 156 return 0;
157
158 return -ENOENT;
155} 159}
156 160
157static const struct inet6_protocol tunnel6_protocol = { 161static const struct inet6_protocol tunnel6_protocol = {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 1216c920f945..61316ec48b51 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -517,9 +517,9 @@ static struct sock *__udp6_lib_err_encap(struct net *net,
517 return sk; 517 return sk;
518} 518}
519 519
520void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 520int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
521 u8 type, u8 code, int offset, __be32 info, 521 u8 type, u8 code, int offset, __be32 info,
522 struct udp_table *udptable) 522 struct udp_table *udptable)
523{ 523{
524 struct ipv6_pinfo *np; 524 struct ipv6_pinfo *np;
525 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; 525 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
@@ -544,7 +544,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
544 if (!sk) { 544 if (!sk) {
545 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), 545 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
546 ICMP6_MIB_INERRORS); 546 ICMP6_MIB_INERRORS);
547 return; 547 return -ENOENT;
548 } 548 }
549 tunnel = true; 549 tunnel = true;
550 } 550 }
@@ -583,7 +583,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
583 sk->sk_err = err; 583 sk->sk_err = err;
584 sk->sk_error_report(sk); 584 sk->sk_error_report(sk);
585out: 585out:
586 return; 586 return 0;
587} 587}
588 588
589static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) 589static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
@@ -614,11 +614,11 @@ static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
614 return 0; 614 return 0;
615} 615}
616 616
617static __inline__ void udpv6_err(struct sk_buff *skb, 617static __inline__ int udpv6_err(struct sk_buff *skb,
618 struct inet6_skb_parm *opt, u8 type, 618 struct inet6_skb_parm *opt, u8 type,
619 u8 code, int offset, __be32 info) 619 u8 code, int offset, __be32 info)
620{ 620{
621 __udp6_lib_err(skb, opt, type, code, offset, info, &udp_table); 621 return __udp6_lib_err(skb, opt, type, code, offset, info, &udp_table);
622} 622}
623 623
624static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) 624static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 7903e21c178b..5730e6503cb4 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -9,8 +9,8 @@
9#include <net/transp_v6.h> 9#include <net/transp_v6.h>
10 10
11int __udp6_lib_rcv(struct sk_buff *, struct udp_table *, int); 11int __udp6_lib_rcv(struct sk_buff *, struct udp_table *, int);
12void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, u8, u8, int, 12int __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, u8, u8, int,
13 __be32, struct udp_table *); 13 __be32, struct udp_table *);
14 14
15int udp_v6_get_port(struct sock *sk, unsigned short snum); 15int udp_v6_get_port(struct sock *sk, unsigned short snum);
16 16
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 5000ad6878e6..a125aebc29e5 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -20,11 +20,12 @@ static int udplitev6_rcv(struct sk_buff *skb)
20 return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE); 20 return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
21} 21}
22 22
23static void udplitev6_err(struct sk_buff *skb, 23static int udplitev6_err(struct sk_buff *skb,
24 struct inet6_skb_parm *opt, 24 struct inet6_skb_parm *opt,
25 u8 type, u8 code, int offset, __be32 info) 25 u8 type, u8 code, int offset, __be32 info)
26{ 26{
27 __udp6_lib_err(skb, opt, type, code, offset, info, &udplite_table); 27 return __udp6_lib_err(skb, opt, type, code, offset, info,
28 &udplite_table);
28} 29}
29 30
30static const struct inet6_protocol udplitev6_protocol = { 31static const struct inet6_protocol udplitev6_protocol = {
diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
index b2dc8ce49378..cc979b702c89 100644
--- a/net/ipv6/xfrm6_protocol.c
+++ b/net/ipv6/xfrm6_protocol.c
@@ -80,14 +80,16 @@ static int xfrm6_esp_rcv(struct sk_buff *skb)
80 return 0; 80 return 0;
81} 81}
82 82
83static void xfrm6_esp_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 83static int xfrm6_esp_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
84 u8 type, u8 code, int offset, __be32 info) 84 u8 type, u8 code, int offset, __be32 info)
85{ 85{
86 struct xfrm6_protocol *handler; 86 struct xfrm6_protocol *handler;
87 87
88 for_each_protocol_rcu(esp6_handlers, handler) 88 for_each_protocol_rcu(esp6_handlers, handler)
89 if (!handler->err_handler(skb, opt, type, code, offset, info)) 89 if (!handler->err_handler(skb, opt, type, code, offset, info))
90 break; 90 return 0;
91
92 return -ENOENT;
91} 93}
92 94
93static int xfrm6_ah_rcv(struct sk_buff *skb) 95static int xfrm6_ah_rcv(struct sk_buff *skb)
@@ -107,14 +109,16 @@ static int xfrm6_ah_rcv(struct sk_buff *skb)
107 return 0; 109 return 0;
108} 110}
109 111
110static void xfrm6_ah_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 112static int xfrm6_ah_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
111 u8 type, u8 code, int offset, __be32 info) 113 u8 type, u8 code, int offset, __be32 info)
112{ 114{
113 struct xfrm6_protocol *handler; 115 struct xfrm6_protocol *handler;
114 116
115 for_each_protocol_rcu(ah6_handlers, handler) 117 for_each_protocol_rcu(ah6_handlers, handler)
116 if (!handler->err_handler(skb, opt, type, code, offset, info)) 118 if (!handler->err_handler(skb, opt, type, code, offset, info))
117 break; 119 return 0;
120
121 return -ENOENT;
118} 122}
119 123
120static int xfrm6_ipcomp_rcv(struct sk_buff *skb) 124static int xfrm6_ipcomp_rcv(struct sk_buff *skb)
@@ -134,14 +138,16 @@ static int xfrm6_ipcomp_rcv(struct sk_buff *skb)
134 return 0; 138 return 0;
135} 139}
136 140
137static void xfrm6_ipcomp_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 141static int xfrm6_ipcomp_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
138 u8 type, u8 code, int offset, __be32 info) 142 u8 type, u8 code, int offset, __be32 info)
139{ 143{
140 struct xfrm6_protocol *handler; 144 struct xfrm6_protocol *handler;
141 145
142 for_each_protocol_rcu(ipcomp6_handlers, handler) 146 for_each_protocol_rcu(ipcomp6_handlers, handler)
143 if (!handler->err_handler(skb, opt, type, code, offset, info)) 147 if (!handler->err_handler(skb, opt, type, code, offset, info))
144 break; 148 return 0;
149
150 return -ENOENT;
145} 151}
146 152
147static const struct inet6_protocol esp6_protocol = { 153static const struct inet6_protocol esp6_protocol = {
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 5c36a99882ed..7ab08a5b36dc 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -574,7 +574,7 @@ void sctp_err_finish(struct sock *sk, struct sctp_transport *t)
574 * is probably better. 574 * is probably better.
575 * 575 *
576 */ 576 */
577void sctp_v4_err(struct sk_buff *skb, __u32 info) 577int sctp_v4_err(struct sk_buff *skb, __u32 info)
578{ 578{
579 const struct iphdr *iph = (const struct iphdr *)skb->data; 579 const struct iphdr *iph = (const struct iphdr *)skb->data;
580 const int ihlen = iph->ihl * 4; 580 const int ihlen = iph->ihl * 4;
@@ -599,7 +599,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
599 skb->transport_header = savesctp; 599 skb->transport_header = savesctp;
600 if (!sk) { 600 if (!sk) {
601 __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); 601 __ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
602 return; 602 return -ENOENT;
603 } 603 }
604 /* Warning: The sock lock is held. Remember to call 604 /* Warning: The sock lock is held. Remember to call
605 * sctp_err_finish! 605 * sctp_err_finish!
@@ -653,6 +653,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
653 653
654out_unlock: 654out_unlock:
655 sctp_err_finish(sk, transport); 655 sctp_err_finish(sk, transport);
656 return 0;
656} 657}
657 658
658/* 659/*
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index fc6c5e4bffa5..6e27c62646e9 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -138,7 +138,7 @@ static struct notifier_block sctp_inet6addr_notifier = {
138}; 138};
139 139
140/* ICMP error handler. */ 140/* ICMP error handler. */
141static void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 141static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
142 u8 type, u8 code, int offset, __be32 info) 142 u8 type, u8 code, int offset, __be32 info)
143{ 143{
144 struct inet6_dev *idev; 144 struct inet6_dev *idev;
@@ -147,7 +147,7 @@ static void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
147 struct sctp_transport *transport; 147 struct sctp_transport *transport;
148 struct ipv6_pinfo *np; 148 struct ipv6_pinfo *np;
149 __u16 saveip, savesctp; 149 __u16 saveip, savesctp;
150 int err; 150 int err, ret = 0;
151 struct net *net = dev_net(skb->dev); 151 struct net *net = dev_net(skb->dev);
152 152
153 idev = in6_dev_get(skb->dev); 153 idev = in6_dev_get(skb->dev);
@@ -163,6 +163,7 @@ static void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
163 skb->transport_header = savesctp; 163 skb->transport_header = savesctp;
164 if (!sk) { 164 if (!sk) {
165 __ICMP6_INC_STATS(net, idev, ICMP6_MIB_INERRORS); 165 __ICMP6_INC_STATS(net, idev, ICMP6_MIB_INERRORS);
166 ret = -ENOENT;
166 goto out; 167 goto out;
167 } 168 }
168 169
@@ -202,6 +203,8 @@ out_unlock:
202out: 203out:
203 if (likely(idev != NULL)) 204 if (likely(idev != NULL))
204 in6_dev_put(idev); 205 in6_dev_put(idev);
206
207 return ret;
205} 208}
206 209
207static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) 210static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)