inet6 pf rules that "rdr-to ::1" do not work currently. Matching packets just disappear and the counter "packets that violated scope rules" from a "netstat -s -p ip6" gets incremented.
It came up before on misc@: http://marc.info/?t=126804259100002&r=1&w=2 The attached diff removes the check (let's call it check #1) that drops the packet. This is just to point out where the problem is because the BSD's have diverged here: FreeBSD _replaced_ check #1 with another check (#2) in this diff from 2004 (from kame): http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/netinet6/ip6_input.c.diff?r1=1.68;r2=1.69 NetBSD _replaced_ check #1 it with something totally different (attributed to jinmei@kame) http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/netinet6/ip6_input.c?rev=1.81&content-type=text/x-cvsweb-markup Check #2 was _added_ to OpenBSD in 2006 (attributed to jinmei@kame): http://www.openbsd.org/cgi-bin/cvsweb/src/sys/netinet6/ip6_input.c.diff?r1=1.72;r2=1.73 Basically, check #1 is gone in FreeBSD and NetBSD and the diff syncs us closer to FreeBSD. I'm unsure if it's the right thing to do though for a few reasons. The FreeBSD diff has a second part that I cannot yet tell is related or not. Or maybe the NetBSD diff could be better. And OpenBSD also seems to have other checks in this area. I'll spend some more time on this, but maybe there's an IPv6 guru that can lend a hand? :-) -- Cam Index: ip6_input.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.99 diff -u -r1.99 ip6_input.c --- ip6_input.c 3 Apr 2011 13:56:05 -0000 1.99 +++ ip6_input.c 20 May 2011 09:30:14 -0000 @@ -270,7 +270,6 @@ in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); goto bad; } - if (IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) && !(m->m_flags & M_LOOP)) { /* @@ -340,19 +339,6 @@ ip6 = mtod(m, struct ip6_hdr *); srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); #endif - - if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) || - IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) { - if (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) { - ours = 1; - deliverifp = m->m_pkthdr.rcvif; - goto hbhcheck; - } else { - ip6stat.ip6s_badscope++; - in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); - goto bad; - } - } /* drop packets if interface ID portion is already filled */ if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {