Browse Source

[ipv6] Disambiguate received ICMPv6 errors

Originally-implemented-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
86aa959561
2 changed files with 90 additions and 2 deletions
  1. 12
    0
      src/include/ipxe/icmpv6.h
  2. 78
    2
      src/net/icmpv6.c

+ 12
- 0
src/include/ipxe/icmpv6.h View File

@@ -40,6 +40,18 @@ struct icmpv6_handler {
40 40
 /** Declare an ICMPv6 handler */
41 41
 #define __icmpv6_handler __table_entry ( ICMPV6_HANDLERS, 01 )
42 42
 
43
+/** ICMPv6 destination unreachable */
44
+#define ICMPV6_DESTINATION_UNREACHABLE 1
45
+
46
+/** ICMPv6 packet too big */
47
+#define ICMPV6_PACKET_TOO_BIG 2
48
+
49
+/** ICMPv6 time exceeded */
50
+#define ICMPV6_TIME_EXCEEDED 3
51
+
52
+/** ICMPv6 parameter problem */
53
+#define ICMPV6_PARAMETER_PROBLEM 4
54
+
43 55
 /** ICMPv6 echo request */
44 56
 #define ICMPV6_ECHO_REQUEST 128
45 57
 

+ 78
- 2
src/net/icmpv6.c View File

@@ -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
 

Loading…
Cancel
Save