Subject: Distinction between ICMP unreachable codes 0 and 6?

From: Dennis Ferguson <[email-masked]>
Date: Wed, 22 Apr 2015 09:14:30 -0700

After many years I've found a reason to read RFC4443 with an eye for the
minutia and I can't quite figure out the intended distinction between ICMP
unreachable codes 0 and 6 from the text.  The definitions are

   Code           0 - No route to destination
                  [...]
                  6 - Reject route to destination

About code 0 it says this:

   If the reason for the failure to deliver is lack of a matching entry
   in the forwarding node's routing table, the Code field is set to 0.
   (This error can occur only in nodes that do not hold a "default
   route" in their routing tables.)

It says this about code 6

   If the reason for the failure to deliver is that the route to the
   destination is a reject route, the Code field is set to 6.  This may
   occur if the router has been configured to reject all the traffic for
   a specific prefix.

   Codes 5 and 6 are more informative subsets of code 1.

where code 1 is "administrative prohibition".

I have an implementation where the forwarding table always has a default
route (i.e. with a prefix of length 0), so every route lookup finds a
matching entry in the "forwarding node's routing table" but sometimes the
matching entry is what it would call a "reject route" in SNMP.  This seems
like a mere internal implementation quirk which should have no effect on
the ICMP errors it emits yet the text above, which is written in terms of
internal implementation mechanisms like "reject route" rather than the
semantics the error is intended to convey, seems to quite explicitly say
otherwise.

The related issue is that I think the parenthetical comment in the
code 0 description is incorrect, in that lack of a default route is not
the only way a router can determine it has no matching route to a destination.
A router which does a route aggregation, that is which originates a shorter
prefix summary route into routing while suppressing the advertisement of some
or all of the more specific matching prefixes it has routes to, is almost
always advertising reachability for destinations it knows it cannot reach and
must arrange its forwarding lookup so that destinations matching the aggregate
prefix it conjured up never match routes less specific than the aggregate.
I believe the unreachable code the router sends in this case should be the
same whether the router also has a default route or not and independent of
how the internal forwarding lookup is arranged to produce the error.
Moreover, when viewed this way a router with no default route (or a "reject"
default route) which originates a zero-length prefix into routing while
suppressing the advertisement of some or all more specific prefixes it has
routes for is in fact performing the extreme version of same aggregation
operation.  The error being reported, that it has no more specific route
to a destination matching the summary prefix, has the same meaning in
either case, I don't see why the length of the summary prefix should change
the error code it sends and in any case the error being reported is not
an "administrative prohibition" even if the internal implementation of
this involves something that is called a "reject route" when reported
via the forwarding MIB.  Ignoring routing transients, routers being
sent traffic for destinations they have no route to reach are always
the (perhaps implicit or static) origin of an aggregated summary prefix,
but the summary prefix is not necessarily a default route.

So I'm assuming that code 0 was intended to report the general case of
a router having no route to reach a destination, while code 6 is supposed to
be used to report the RFC4193 ULA border patrol error for which it seems
to have been invented.  If this is true then I think the code 0 description
would be better if it just repeated "no route to destination" without opining
about how that is determined, since it is more complicated than the comment in
the parentheses, while the code 6 specification would better avoid the term
"reject route" in favour of describing the circumstance that should cause
the code 6 error to be sent (given the definition of code 5, "Destination
address failed ingress/egress policy" might work).  As far as I can find
the only definition of "reject route" we had prior to RFC4193 and the
above is the route type in the RFC4292 forwarding table MIB and its
ancestors, which says this:

               reject(2) refers to a route that, if matched, discards
               the message as unreachable and returns a notification
               (e.g., ICMP error) to the message sender.  This is used
               in some protocols as a means of correctly aggregating
               routes.

Here matching a reject route results in a non-specific notification being
sent.  To know which notification it causes to be sent would require knowing
why the reject route is there, which the MIB doesn't represent and the existence
of the reject route by itself doesn't tell you.  The code 6 definition seems
to instead define the "why" to be the reject route itself, assigns semantics
to the "reject route" error (administrative prohibition) inconsistent with an
original reason reject routes were and are used, and appears to have the odd
consequence that the choice of representing my forwarding table as having no
default route or a reject default route should effect the unreachable code
sent for errors involving that even though this has no effect on the nature
of the error being reported or anything else.

It is, however, quite possible (and certainly wouldn't be the first time)
that I'm misunderstanding the utility of this, or that the reasons this is
fine were all hashed out before when I wasn't paying attention.  If so I
apologize, but I would appreciate it if someone could explain it to me.

Thanks,
Dennis Ferguson