david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[ipv6] Disambiguate received ICMPv6 errors

Originally-implemented-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2015-05-11 12:45:14 +01:00
parent bb6d7bebe9
commit 86aa959561
2 changed files with 90 additions and 2 deletions

View File

@ -40,6 +40,18 @@ struct icmpv6_handler {
/** Declare an ICMPv6 handler */
#define __icmpv6_handler __table_entry ( ICMPV6_HANDLERS, 01 )
/** ICMPv6 destination unreachable */
#define ICMPV6_DESTINATION_UNREACHABLE 1
/** ICMPv6 packet too big */
#define ICMPV6_PACKET_TOO_BIG 2
/** ICMPv6 time exceeded */
#define ICMPV6_TIME_EXCEEDED 3
/** ICMPv6 parameter problem */
#define ICMPV6_PARAMETER_PROBLEM 4
/** ICMPv6 echo request */
#define ICMPV6_ECHO_REQUEST 128

View File

@ -38,6 +38,65 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
/* Disambiguate the various error causes */
#define EHOSTUNREACH_ROUTE \
__einfo_error ( EINFO_EHOSTUNREACH_ROUTE )
#define EINFO_EHOSTUNREACH_ROUTE \
__einfo_uniqify ( EINFO_EHOSTUNREACH, 0, \
"No route to destination" )
#define EHOSTUNREACH_PROHIBITED \
__einfo_error ( EINFO_EHOSTUNREACH_PROHIBITED )
#define EINFO_EHOSTUNREACH_PROHIBITED \
__einfo_uniqify ( EINFO_EHOSTUNREACH, 1, \
"Communication administratively prohibited" )
#define EHOSTUNREACH_ADDRESS \
__einfo_error ( EINFO_EHOSTUNREACH_ADDRESS )
#define EINFO_EHOSTUNREACH_ADDRESS \
__einfo_uniqify ( EINFO_EHOSTUNREACH, 3, \
"Address unreachable" )
#define EHOSTUNREACH_PORT \
__einfo_error ( EINFO_EHOSTUNREACH_PORT )
#define EINFO_EHOSTUNREACH_PORT \
__einfo_uniqify ( EINFO_EHOSTUNREACH, 4, \
"Port unreachable" )
#define EHOSTUNREACH_CODE( code ) \
EUNIQ ( EINFO_EHOSTUNREACH, ( (code) & 0x1f ), \
EHOSTUNREACH_ROUTE, EHOSTUNREACH_PROHIBITED, \
EHOSTUNREACH_ADDRESS, EHOSTUNREACH_PORT )
#define ETIMEDOUT_HOP \
__einfo_error ( EINFO_ETIMEDOUT_HOP )
#define EINFO_ETIMEDOUT_HOP \
__einfo_uniqify ( EINFO_ETIMEDOUT, 0, \
"Hop limit exceeded in transit" )
#define ETIMEDOUT_REASSEMBLY \
__einfo_error ( EINFO_ETIMEDOUT_REASSEMBLY )
#define EINFO_ETIMEDOUT_REASSEMBLY \
__einfo_uniqify ( EINFO_ETIMEDOUT, 1, \
"Fragment reassembly time exceeded" )
#define ETIMEDOUT_CODE( code ) \
EUNIQ ( EINFO_ETIMEDOUT, ( (code) & 0x1f ), \
ETIMEDOUT_HOP, ETIMEDOUT_REASSEMBLY )
#define EPROTO_BAD_HEADER \
__einfo_error ( EINFO_EPROTO_BAD_HEADER )
#define EINFO_EPROTO_BAD_HEADER \
__einfo_uniqify ( EINFO_EPROTO, 0, \
"Erroneous header field" )
#define EPROTO_NEXT_HEADER \
__einfo_error ( EINFO_EPROTO_NEXT_HEADER )
#define EINFO_EPROTO_NEXT_HEADER \
__einfo_uniqify ( EINFO_EPROTO, 1, \
"Unrecognised next header type" )
#define EPROTO_OPTION \
__einfo_error ( EINFO_EPROTO_OPTION )
#define EINFO_EPROTO_OPTION \
__einfo_uniqify ( EINFO_EPROTO, 2, \
"Unrecognised IPv6 option" )
#define EPROTO_CODE( code ) \
EUNIQ ( EINFO_EPROTO, ( (code) & 0x1f ), \
EPROTO_BAD_HEADER, EPROTO_NEXT_HEADER, EPROTO_OPTION )
struct icmp_echo_protocol icmpv6_echo_protocol __icmp_echo_protocol;
/**
@ -148,8 +207,25 @@ static int icmpv6_rx ( struct io_buffer *iobuf, struct net_device *netdev,
/* Identify handler */
handler = icmpv6_handler ( icmp->type );
if ( ! handler ) {
DBGC ( netdev, "ICMPv6 unrecognised type %d\n", icmp->type );
rc = -ENOTSUP;
switch ( icmp->type ) {
case ICMPV6_DESTINATION_UNREACHABLE:
rc = -EHOSTUNREACH_CODE ( icmp->code );
break;
case ICMPV6_PACKET_TOO_BIG:
rc = -ERANGE;
break;
case ICMPV6_TIME_EXCEEDED:
rc = -ETIMEDOUT_CODE ( icmp->code );
break;
case ICMPV6_PARAMETER_PROBLEM:
rc = -EPROTO_CODE ( icmp->code );
break;
default:
DBGC ( netdev, "ICMPv6 unrecognised type %d code %d\n",
icmp->type, icmp->code );
rc = -ENOTSUP;
break;
};
goto done;
}