|
@@ -38,6 +38,65 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
38
|
38
|
*
|
39
|
39
|
*/
|
40
|
40
|
|
|
41
|
+/* Disambiguate the various error causes */
|
|
42
|
+#define EHOSTUNREACH_ROUTE \
|
|
43
|
+ __einfo_error ( EINFO_EHOSTUNREACH_ROUTE )
|
|
44
|
+#define EINFO_EHOSTUNREACH_ROUTE \
|
|
45
|
+ __einfo_uniqify ( EINFO_EHOSTUNREACH, 0, \
|
|
46
|
+ "No route to destination" )
|
|
47
|
+#define EHOSTUNREACH_PROHIBITED \
|
|
48
|
+ __einfo_error ( EINFO_EHOSTUNREACH_PROHIBITED )
|
|
49
|
+#define EINFO_EHOSTUNREACH_PROHIBITED \
|
|
50
|
+ __einfo_uniqify ( EINFO_EHOSTUNREACH, 1, \
|
|
51
|
+ "Communication administratively prohibited" )
|
|
52
|
+#define EHOSTUNREACH_ADDRESS \
|
|
53
|
+ __einfo_error ( EINFO_EHOSTUNREACH_ADDRESS )
|
|
54
|
+#define EINFO_EHOSTUNREACH_ADDRESS \
|
|
55
|
+ __einfo_uniqify ( EINFO_EHOSTUNREACH, 3, \
|
|
56
|
+ "Address unreachable" )
|
|
57
|
+#define EHOSTUNREACH_PORT \
|
|
58
|
+ __einfo_error ( EINFO_EHOSTUNREACH_PORT )
|
|
59
|
+#define EINFO_EHOSTUNREACH_PORT \
|
|
60
|
+ __einfo_uniqify ( EINFO_EHOSTUNREACH, 4, \
|
|
61
|
+ "Port unreachable" )
|
|
62
|
+#define EHOSTUNREACH_CODE( code ) \
|
|
63
|
+ EUNIQ ( EINFO_EHOSTUNREACH, ( (code) & 0x1f ), \
|
|
64
|
+ EHOSTUNREACH_ROUTE, EHOSTUNREACH_PROHIBITED, \
|
|
65
|
+ EHOSTUNREACH_ADDRESS, EHOSTUNREACH_PORT )
|
|
66
|
+
|
|
67
|
+#define ETIMEDOUT_HOP \
|
|
68
|
+ __einfo_error ( EINFO_ETIMEDOUT_HOP )
|
|
69
|
+#define EINFO_ETIMEDOUT_HOP \
|
|
70
|
+ __einfo_uniqify ( EINFO_ETIMEDOUT, 0, \
|
|
71
|
+ "Hop limit exceeded in transit" )
|
|
72
|
+#define ETIMEDOUT_REASSEMBLY \
|
|
73
|
+ __einfo_error ( EINFO_ETIMEDOUT_REASSEMBLY )
|
|
74
|
+#define EINFO_ETIMEDOUT_REASSEMBLY \
|
|
75
|
+ __einfo_uniqify ( EINFO_ETIMEDOUT, 1, \
|
|
76
|
+ "Fragment reassembly time exceeded" )
|
|
77
|
+#define ETIMEDOUT_CODE( code ) \
|
|
78
|
+ EUNIQ ( EINFO_ETIMEDOUT, ( (code) & 0x1f ), \
|
|
79
|
+ ETIMEDOUT_HOP, ETIMEDOUT_REASSEMBLY )
|
|
80
|
+
|
|
81
|
+#define EPROTO_BAD_HEADER \
|
|
82
|
+ __einfo_error ( EINFO_EPROTO_BAD_HEADER )
|
|
83
|
+#define EINFO_EPROTO_BAD_HEADER \
|
|
84
|
+ __einfo_uniqify ( EINFO_EPROTO, 0, \
|
|
85
|
+ "Erroneous header field" )
|
|
86
|
+#define EPROTO_NEXT_HEADER \
|
|
87
|
+ __einfo_error ( EINFO_EPROTO_NEXT_HEADER )
|
|
88
|
+#define EINFO_EPROTO_NEXT_HEADER \
|
|
89
|
+ __einfo_uniqify ( EINFO_EPROTO, 1, \
|
|
90
|
+ "Unrecognised next header type" )
|
|
91
|
+#define EPROTO_OPTION \
|
|
92
|
+ __einfo_error ( EINFO_EPROTO_OPTION )
|
|
93
|
+#define EINFO_EPROTO_OPTION \
|
|
94
|
+ __einfo_uniqify ( EINFO_EPROTO, 2, \
|
|
95
|
+ "Unrecognised IPv6 option" )
|
|
96
|
+#define EPROTO_CODE( code ) \
|
|
97
|
+ EUNIQ ( EINFO_EPROTO, ( (code) & 0x1f ), \
|
|
98
|
+ EPROTO_BAD_HEADER, EPROTO_NEXT_HEADER, EPROTO_OPTION )
|
|
99
|
+
|
41
|
100
|
struct icmp_echo_protocol icmpv6_echo_protocol __icmp_echo_protocol;
|
42
|
101
|
|
43
|
102
|
/**
|
|
@@ -148,8 +207,25 @@ static int icmpv6_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
148
|
207
|
/* Identify handler */
|
149
|
208
|
handler = icmpv6_handler ( icmp->type );
|
150
|
209
|
if ( ! handler ) {
|
151
|
|
- DBGC ( netdev, "ICMPv6 unrecognised type %d\n", icmp->type );
|
152
|
|
- rc = -ENOTSUP;
|
|
210
|
+ switch ( icmp->type ) {
|
|
211
|
+ case ICMPV6_DESTINATION_UNREACHABLE:
|
|
212
|
+ rc = -EHOSTUNREACH_CODE ( icmp->code );
|
|
213
|
+ break;
|
|
214
|
+ case ICMPV6_PACKET_TOO_BIG:
|
|
215
|
+ rc = -ERANGE;
|
|
216
|
+ break;
|
|
217
|
+ case ICMPV6_TIME_EXCEEDED:
|
|
218
|
+ rc = -ETIMEDOUT_CODE ( icmp->code );
|
|
219
|
+ break;
|
|
220
|
+ case ICMPV6_PARAMETER_PROBLEM:
|
|
221
|
+ rc = -EPROTO_CODE ( icmp->code );
|
|
222
|
+ break;
|
|
223
|
+ default:
|
|
224
|
+ DBGC ( netdev, "ICMPv6 unrecognised type %d code %d\n",
|
|
225
|
+ icmp->type, icmp->code );
|
|
226
|
+ rc = -ENOTSUP;
|
|
227
|
+ break;
|
|
228
|
+ };
|
153
|
229
|
goto done;
|
154
|
230
|
}
|
155
|
231
|
|