Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
rxrpc
ar-error.c
Go to the documentation of this file.
1
/* Error message handling (ICMP)
2
*
3
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells (
[email protected]
)
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version
9
* 2 of the License, or (at your option) any later version.
10
*/
11
12
#include <linux/module.h>
13
#include <linux/net.h>
14
#include <
linux/skbuff.h
>
15
#include <linux/errqueue.h>
16
#include <linux/udp.h>
17
#include <linux/in.h>
18
#include <linux/in6.h>
19
#include <linux/icmp.h>
20
#include <
net/sock.h
>
21
#include <
net/af_rxrpc.h
>
22
#include <
net/ip.h
>
23
#include "
ar-internal.h
"
24
25
/*
26
* handle an error received on the local endpoint
27
*/
28
void
rxrpc_UDP_error_report
(
struct
sock
*
sk
)
29
{
30
struct
sock_exterr_skb
*
serr
;
31
struct
rxrpc_transport
*
trans
;
32
struct
rxrpc_local
*local = sk->
sk_user_data
;
33
struct
rxrpc_peer
*peer;
34
struct
sk_buff
*
skb
;
35
__be32
addr
;
36
__be16
port
;
37
38
_enter
(
"%p{%d}"
, sk, local->
debug_id
);
39
40
skb =
skb_dequeue
(&sk->
sk_error_queue
);
41
if
(!skb) {
42
_leave
(
"UDP socket errqueue empty"
);
43
return
;
44
}
45
46
rxrpc_new_skb
(skb);
47
48
serr =
SKB_EXT_ERR
(skb);
49
addr = *(
__be32
*)(skb_network_header(skb) + serr->
addr_offset
);
50
port = serr->
port
;
51
52
_net
(
"Rx UDP Error from %pI4:%hu"
, &addr,
ntohs
(port));
53
_debug
(
"Msg l:%d d:%d"
, skb->
len
, skb->
data_len
);
54
55
peer =
rxrpc_find_peer
(local, addr, port);
56
if
(IS_ERR(peer)) {
57
rxrpc_free_skb
(skb);
58
_leave
(
" [no peer]"
);
59
return
;
60
}
61
62
trans =
rxrpc_find_transport
(local, peer);
63
if
(!trans) {
64
rxrpc_put_peer
(peer);
65
rxrpc_free_skb
(skb);
66
_leave
(
" [no trans]"
);
67
return
;
68
}
69
70
if
(serr->
ee
.ee_origin ==
SO_EE_ORIGIN_ICMP
&&
71
serr->
ee
.ee_type ==
ICMP_DEST_UNREACH
&&
72
serr->
ee
.ee_code ==
ICMP_FRAG_NEEDED
73
) {
74
u32
mtu = serr->
ee
.ee_info;
75
76
_net
(
"Rx Received ICMP Fragmentation Needed (%d)"
, mtu);
77
78
/* wind down the local interface MTU */
79
if
(mtu > 0 && peer->
if_mtu
== 65535 && mtu < peer->if_mtu) {
80
peer->
if_mtu
= mtu;
81
_net
(
"I/F MTU %u"
, mtu);
82
}
83
84
if
(mtu == 0) {
85
/* they didn't give us a size, estimate one */
86
if
(mtu > 1500) {
87
mtu >>= 1;
88
if
(mtu < 1500)
89
mtu = 1500;
90
}
else
{
91
mtu -= 100;
92
if
(mtu < peer->hdrsize)
93
mtu = peer->
hdrsize
+ 4;
94
}
95
}
96
97
if
(mtu < peer->mtu) {
98
spin_lock_bh(&peer->
lock
);
99
peer->
mtu
= mtu;
100
peer->
maxdata
= peer->
mtu
- peer->
hdrsize
;
101
spin_unlock_bh(&peer->
lock
);
102
_net
(
"Net MTU %u (maxdata %u)"
,
103
peer->
mtu
, peer->
maxdata
);
104
}
105
}
106
107
rxrpc_put_peer
(peer);
108
109
/* pass the transport ref to error_handler to release */
110
skb_queue_tail
(&trans->
error_queue
, skb);
111
rxrpc_queue_work
(&trans->
error_handler
);
112
113
/* reset and regenerate socket error */
114
spin_lock_bh(&sk->
sk_error_queue
.lock);
115
sk->
sk_err
= 0;
116
skb = skb_peek(&sk->
sk_error_queue
);
117
if
(skb) {
118
sk->
sk_err
=
SKB_EXT_ERR
(skb)->ee.ee_errno;
119
spin_unlock_bh(&sk->
sk_error_queue
.lock);
120
sk->
sk_error_report
(sk);
121
}
else
{
122
spin_unlock_bh(&sk->
sk_error_queue
.lock);
123
}
124
125
_leave
(
""
);
126
}
127
128
/*
129
* deal with UDP error messages
130
*/
131
void
rxrpc_UDP_error_handler
(
struct
work_struct
*
work
)
132
{
133
struct
sock_extended_err
*ee;
134
struct
sock_exterr_skb
*
serr
;
135
struct
rxrpc_transport
*
trans
=
136
container_of
(work,
struct
rxrpc_transport
,
error_handler
);
137
struct
sk_buff
*
skb
;
138
int
err
;
139
140
_enter
(
""
);
141
142
skb =
skb_dequeue
(&trans->
error_queue
);
143
if
(!skb)
144
return
;
145
146
serr =
SKB_EXT_ERR
(skb);
147
ee = &serr->
ee
;
148
149
_net
(
"Rx Error o=%d t=%d c=%d e=%d"
,
150
ee->
ee_origin
, ee->
ee_type
, ee->
ee_code
, ee->
ee_errno
);
151
152
err = ee->
ee_errno
;
153
154
switch
(ee->
ee_origin
) {
155
case
SO_EE_ORIGIN_ICMP
:
156
switch
(ee->
ee_type
) {
157
case
ICMP_DEST_UNREACH
:
158
switch
(ee->
ee_code
) {
159
case
ICMP_NET_UNREACH
:
160
_net
(
"Rx Received ICMP Network Unreachable"
);
161
err =
ENETUNREACH
;
162
break
;
163
case
ICMP_HOST_UNREACH
:
164
_net
(
"Rx Received ICMP Host Unreachable"
);
165
err =
EHOSTUNREACH
;
166
break
;
167
case
ICMP_PORT_UNREACH
:
168
_net
(
"Rx Received ICMP Port Unreachable"
);
169
err =
ECONNREFUSED
;
170
break
;
171
case
ICMP_FRAG_NEEDED
:
172
_net
(
"Rx Received ICMP Fragmentation Needed (%d)"
,
173
ee->
ee_info
);
174
err = 0;
/* dealt with elsewhere */
175
break
;
176
case
ICMP_NET_UNKNOWN
:
177
_net
(
"Rx Received ICMP Unknown Network"
);
178
err =
ENETUNREACH
;
179
break
;
180
case
ICMP_HOST_UNKNOWN
:
181
_net
(
"Rx Received ICMP Unknown Host"
);
182
err =
EHOSTUNREACH
;
183
break
;
184
default
:
185
_net
(
"Rx Received ICMP DestUnreach code=%u"
,
186
ee->
ee_code
);
187
break
;
188
}
189
break
;
190
191
case
ICMP_TIME_EXCEEDED
:
192
_net
(
"Rx Received ICMP TTL Exceeded"
);
193
break
;
194
195
default
:
196
_proto
(
"Rx Received ICMP error { type=%u code=%u }"
,
197
ee->
ee_type
, ee->
ee_code
);
198
break
;
199
}
200
break
;
201
202
case
SO_EE_ORIGIN_LOCAL
:
203
_proto
(
"Rx Received local error { error=%d }"
,
204
ee->
ee_errno
);
205
break
;
206
207
case
SO_EE_ORIGIN_NONE
:
208
case
SO_EE_ORIGIN_ICMP6
:
209
default
:
210
_proto
(
"Rx Received error report { orig=%u }"
,
211
ee->
ee_origin
);
212
break
;
213
}
214
215
/* terminate all the affected calls if there's an unrecoverable
216
* error */
217
if
(err) {
218
struct
rxrpc_call
*call, *_n;
219
220
_debug
(
"ISSUE ERROR %d"
, err);
221
222
spin_lock_bh(&trans->
peer
->lock);
223
trans->
peer
->net_error =
err
;
224
225
list_for_each_entry_safe
(call, _n, &trans->
peer
->error_targets,
226
error_link
) {
227
write_lock
(&call->
state_lock
);
228
if
(call->
state
!=
RXRPC_CALL_COMPLETE
&&
229
call->
state
<
RXRPC_CALL_NETWORK_ERROR
) {
230
call->
state
=
RXRPC_CALL_NETWORK_ERROR
;
231
set_bit
(
RXRPC_CALL_RCVD_ERROR
, &call->
events
);
232
rxrpc_queue_call
(call);
233
}
234
write_unlock
(&call->
state_lock
);
235
list_del_init(&call->
error_link
);
236
}
237
238
spin_unlock_bh(&trans->
peer
->lock);
239
}
240
241
if
(!skb_queue_empty(&trans->
error_queue
))
242
rxrpc_queue_work
(&trans->
error_handler
);
243
244
rxrpc_free_skb
(skb);
245
rxrpc_put_transport
(trans);
246
_leave
(
""
);
247
}
Generated on Thu Jan 10 2013 15:01:39 for Linux Kernel by
1.8.2