ip6_input() takes the fast forwarding path only when
net.inet6.ip6.redirect is 0, because ip6_tryforward() cannot send
redirects. The default is 1, so an IPv6 router forwards every packet
through ip6_forward(), which among other things copies each packet in
case it has to answer with an ICMPv6 error. IPv4 had the same
restriction until 8ad114c082a1 added redirects to ip_tryforward().
Do the same for IPv6. When a packet leaves through the interface it
arrived on, keep a copy and pass it to icmp6_redirect_output() once
the packet is out. As in ip6_forward(), no redirect is sent when the
route came from a redirect or a packet filter rewrote the destination
or chose the next hop; as in ip_tryforward(), none when it rewrote the
source either. Packets forwarded to another interface pay for saving
the two addresses and an interface comparison. Then drop the redirect
condition from ip6_input().
The default configuration now gets what redirect=0 got: the route MTU
instead of the interface MTU for packet-too-big, no ICMPv6 unreachable
for an if_output() error, and no mac_netinet6_nd6_send() call.
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC ("Netgate")