All in Context
It has been an established security practice that most, if not all, ICMP messages should be dropped at the firewall. Network reconnaissance and covert channels are two reasons that this is a recommended best practice. With IPv6 and ICMPv6 this changes. The IETF no longer recommends that an "overly aggressive" ICMP filtering policy be in place. ICMPv6 is necessary for the proper functioning of an IPv6 network. RFC 4890 has some excellent recommendations for selectively filtering ICMP traffic at the firewall level.In the next few posts I would like to look at some of the recommendations. First, I need to put these recommendations in context. I will be assuming the user is in a fairly common scenario. A stateful firewall is protecting a subnet of hosts. It is also acting as a router. Hosts behind the router will have both a link-local address (fe80::/10) and a global unicast address (2001:0db8::/32). The rules that I will cover are those that are traversing the firewall. That is traveling from the inside to the outside or vice versa.What to Allow
By way of review an ICMPv6 message has four fields; Type (1 byte), Code (1 byte), Checksum (2 bytes), and Message Body (variable). Error messages have a Type between 0-127. Informational messages have a Type between 128-255. Within each type there are various codes available. This allows for more granular information to be conveyed.
There are only four basic types of messages that should never be dropped when associated with an existing connection; Destination Unreachable, Packet Too Big, Time Exceeded, and Parameter Problem. We will look at each one.

The first type of messages are Destination Unreachable. There are six codes available for this type of ICMPv6 message. The RFC recommends that they all be allowed through when associated with associated connections. The diagram above is a type code three which is a code of Address Unreachable. Deep packet inspection might be necessary for the detection of covert messages. In the diagram above the unused portion is empty. It should contain as much of the packet that invoked the message as possible to help with debugging. However, there is no reason it could not contain other information such as below.

Packet Too Big messages must also be allowed through the firewall. In IPv6 it is up to the sender to create packet sizes that do not exceed the MTU of any of the links between the source and destination. Therefore, Type 2 ICMPv6 Error Messages should be allowed through the firewall. There is only one Code for these types of messages and it is set to 0.
In IPv6 the TTL header field has been replaced with the Hop Limit field. This makes more sense as the TTL was used to count hops anyway in IPv4. ICMPv6 error messages of Type 3 and Code 0 should be allowed through the firewall. There is a Code 1 for fragment reassembly time exceeded. This should not be allowed.
Finally, error messages of Type 3, Codes 1 (unrecognized next header type encountered) and 2 (unrecognized IPv6 option encountered) should be allowed through. The IPv6 implements the Next Header field in its header to identify the upper lay protocol, such as UDP or TCP, or to identify an extension header, such as a routing header or fragment header. If the host at the other end is unable to process one of these headers it could be possible that it might return a Code 1. ICMPv6 Type 3 and Code 2 applies to the Destination Options and Hop-by-Hop Options. Below is an example of a packet with the Next Header field set to 145. According to IANA this is still unassigned and unlikely to be implemented.

Some of the examples above could be used for probing a network to discover live hosts. With IPv6 this is unlikely to be effective because the address space is so large. However, a more granular policy per host might be in order if the administrator feels it is appropriate.