+ if ((rt->rt_flags & (RTF_BLACKHOLE|RTF_REJECT)) == 0)
+#endif
+ {
+ printf("ip6_forward: outgoing interface is loopback. "
+ "src %s, dst %s, nxt %d, rcvif %s, outif %s\n",
+ ip6_sprintf(&ip6->ip6_src),
+ ip6_sprintf(&ip6->ip6_dst),
+ ip6->ip6_nxt, if_name(m->m_pkthdr.rcvif),
+ if_name(rt->rt_ifp));
+ }
+
+ /* we can just use rcvif in forwarding. */
+ origifp = rcvifp = m->m_pkthdr.rcvif;
+ } else if (nd6_prproxy) {
+ /*
+ * In the prefix proxying case, we need to inform nd6_output()
+ * about the inbound interface, so that any subsequent NS
+ * packets generated by nd6_prproxy_ns_output() will not be
+ * sent back to that same interface.
+ */
+ origifp = rcvifp = m->m_pkthdr.rcvif;
+ } else {
+ rcvifp = m->m_pkthdr.rcvif;
+ origifp = rt->rt_ifp;
+ }
+ /*
+ * clear embedded scope identifiers if necessary.
+ * in6_clearscope will touch the addresses only when necessary.
+ */
+ in6_clearscope(&ip6->ip6_src);
+ in6_clearscope(&ip6->ip6_dst);
+
+ ifp = rt->rt_ifp;
+ /* Drop the lock but retain the extra ref */
+ RT_UNLOCK(rt);
+
+ /*
+ * If this is to be processed locally, let ip6_input have it.
+ */
+ if (proxy) {
+ VERIFY(m->m_pkthdr.pkt_flags & PKTF_PROXY_DST);
+ /* Release extra ref */
+ RT_REMREF(rt);
+ if (mcopy != NULL)
+ m_freem(mcopy);
+ return (m);
+ }
+
+#if PF
+ /* Invoke outbound packet filter */
+ error = pf_af_hook(ifp, NULL, &m, AF_INET6, FALSE, NULL);
+
+ if (error != 0 || m == NULL) {
+ if (m != NULL) {
+ panic("%s: unexpected packet %p\n", __func__, m);
+ /* NOTREACHED */
+ }
+ /* Already freed by callee */
+ goto senderr;
+ }
+ ip6 = mtod(m, struct ip6_hdr *);
+#endif /* PF */
+
+ /* Mark this packet as being forwarded from another interface */
+ m->m_pkthdr.pkt_flags |= PKTF_FORWARDED;
+ len = m_pktlen(m);
+
+ error = nd6_output(ifp, origifp, m, dst, rt, NULL);